From 6c0b89c7864d89177602b912208c463e3e73741a Mon Sep 17 00:00:00 2001 From: Qianwen Shi Date: Wed, 20 May 2026 16:19:09 +0800 Subject: [PATCH 1/4] Prepare for Cloud Agent execution --- .github/modernize/ccacontext/.ccaskills | 64 ++ .github/modernize/ccacontext/cleanup.sh | 45 ++ .github/skills/api-service-contracts/SKILL.md | 210 ++++++ .github/skills/architecture-diagram/SKILL.md | 190 +++++ .github/skills/assessment/SKILL.md | 173 +++++ .github/skills/business-workflows/SKILL.md | 199 +++++ .../skills/configuration-inventory/SKILL.md | 205 ++++++ .../create-dotnet-upgrade-plan/SKILL.md | 143 ++++ .../dotnet-upgrade-guideline.md | 43 ++ .../tasks-schema.json | 349 +++++++++ .../upgrade-plan-template.md | 42 ++ .../skills/create-java-upgrade-plan/SKILL.md | 58 ++ .../java-upgrade-guideline.md | 44 ++ .../tasks-schema.json | 349 +++++++++ .../upgrade-plan-template.md | 51 ++ .../skills/create-modernization-plan/SKILL.md | 129 ++++ .../dotnet-upgrade-guideline.md | 43 ++ .../infra-plan-template.md | 48 ++ .../java-upgrade-guideline.md | 44 ++ .../plan-template.md | 70 ++ .../questionnaire.md | 19 + .../security-plan-template.md | 26 + .../supported-patterns-dotnet.md | 50 ++ .../supported-patterns-java.md | 88 +++ .../tasks-schema.json | 349 +++++++++ .../skills/cve-known-vulnerabilities/SKILL.md | 201 +++++ .github/skills/cwe-code-quality/SKILL.md | 153 ++++ .../cwe-concurrency-synchronization/SKILL.md | 113 +++ .../skills/cwe-credentials-secrets/SKILL.md | 109 +++ .../skills/cwe-file-path-security/SKILL.md | 109 +++ .github/skills/cwe-injection-attacks/SKILL.md | 137 ++++ .github/skills/cwe-memory-safety/SKILL.md | 149 ++++ .github/skills/data-architecture/SKILL.md | 227 ++++++ .github/skills/dependency-map/SKILL.md | 180 +++++ .../skills/execute-java-upgrade-task/SKILL.md | 376 ++++++++++ .../execute-modernization-task/SKILL.md | 49 ++ .github/skills/execute-upgrade-task/SKILL.md | 23 + .github/skills/fact-application-name/SKILL.md | 112 +++ .github/skills/fact-application-port/SKILL.md | 96 +++ .github/skills/fact-application-type/SKILL.md | 133 ++++ .../skills/fact-architecture-pattern/SKILL.md | 218 ++++++ .github/skills/fact-base-image/SKILL.md | 102 +++ .../fact-communication-protocols/SKILL.md | 118 +++ .../fact-compliance-requirements/SKILL.md | 131 ++++ .github/skills/fact-container-engine/SKILL.md | 108 +++ .../skills/fact-container-version/SKILL.md | 99 +++ .../skills/fact-data-classification/SKILL.md | 151 ++++ .../fact-embedded-language-usage/SKILL.md | 277 +++++++ .../fact-environment-variables/SKILL.md | 105 +++ .../fact-external-dependencies/SKILL.md | 124 ++++ .../skills/fact-external-services/SKILL.md | 93 +++ .../fact-hardware-requirements/SKILL.md | 115 +++ .github/skills/fact-health-checks/SKILL.md | 110 +++ .github/skills/fact-image-layers/SKILL.md | 102 +++ .github/skills/fact-image-size/SKILL.md | 121 +++ .../fact-language-dependencies/SKILL.md | 104 +++ .../fact-licensing-information/SKILL.md | 119 +++ .../skills/fact-multi-stage-build/SKILL.md | 92 +++ .github/skills/fact-network-settings/SKILL.md | 90 +++ .github/skills/fact-operating-system/SKILL.md | 126 ++++ .../skills/fact-orchestration-tool/SKILL.md | 96 +++ .github/skills/fact-profile-settings/SKILL.md | 332 +++++++++ .github/skills/fact-resource-limits/SKILL.md | 103 +++ .../skills/fact-runtime-environment/SKILL.md | 107 +++ .../fact-security-implementation/SKILL.md | 142 ++++ .../skills/fact-service-definition/SKILL.md | 108 +++ .../skills/fact-servlet-container/SKILL.md | 310 ++++++++ .../fact-startup-instrumentation/SKILL.md | 371 ++++++++++ .github/skills/fact-system-packages/SKILL.md | 99 +++ .../skills/fact-testing-framework/SKILL.md | 139 ++++ .../skills/fact-version-information/SKILL.md | 109 +++ .github/skills/fact-volume-mounts/SKILL.md | 96 +++ .github/skills/fact-xml-configs/SKILL.md | 298 ++++++++ .github/skills/integration-tests/SKILL.md | 324 +++++++++ .../references/azure-auth-strategies.md | 189 +++++ .../azure-servicebus-testcontainers.md | 688 ++++++++++++++++++ .../azure-storage-testcontainers.md | 276 +++++++ .../references/layer1-local-integration.md | 358 +++++++++ .../layer2-runner-script-templates.md | 287 ++++++++ .../references/layer2-smoke-tests.md | 261 +++++++ .../references/layer3-azure-integration.md | 194 +++++ .../layer4-behavioral-comparison.md | 242 ++++++ .github/skills/playbook-create/SKILL.md | 87 +++ .../playbook-create/charter-template.md | 30 + .../playbook-create/policies-template.md | 72 ++ .../playbook-create/targets-template.md | 31 + .github/skills/rearchitect/SKILL.md | 126 ++++ .../skills/reconcile-tasks-with-plan/SKILL.md | 46 ++ .../repository-dependency-graph/SKILL.md | 250 +++++++ .../skills/security-assessment-merge/SKILL.md | 318 ++++++++ .../validate-playbook-compliance/SKILL.md | 31 + .../validate-playbook-evidence/SKILL.md | 32 + 92 files changed, 13855 insertions(+) create mode 100644 .github/modernize/ccacontext/.ccaskills create mode 100644 .github/modernize/ccacontext/cleanup.sh create mode 100644 .github/skills/api-service-contracts/SKILL.md create mode 100644 .github/skills/architecture-diagram/SKILL.md create mode 100644 .github/skills/assessment/SKILL.md create mode 100644 .github/skills/business-workflows/SKILL.md create mode 100644 .github/skills/configuration-inventory/SKILL.md create mode 100644 .github/skills/create-dotnet-upgrade-plan/SKILL.md create mode 100644 .github/skills/create-dotnet-upgrade-plan/dotnet-upgrade-guideline.md create mode 100644 .github/skills/create-dotnet-upgrade-plan/tasks-schema.json create mode 100644 .github/skills/create-dotnet-upgrade-plan/upgrade-plan-template.md create mode 100644 .github/skills/create-java-upgrade-plan/SKILL.md create mode 100644 .github/skills/create-java-upgrade-plan/java-upgrade-guideline.md create mode 100644 .github/skills/create-java-upgrade-plan/tasks-schema.json create mode 100644 .github/skills/create-java-upgrade-plan/upgrade-plan-template.md create mode 100644 .github/skills/create-modernization-plan/SKILL.md create mode 100644 .github/skills/create-modernization-plan/dotnet-upgrade-guideline.md create mode 100644 .github/skills/create-modernization-plan/infra-plan-template.md create mode 100644 .github/skills/create-modernization-plan/java-upgrade-guideline.md create mode 100644 .github/skills/create-modernization-plan/plan-template.md create mode 100644 .github/skills/create-modernization-plan/questionnaire.md create mode 100644 .github/skills/create-modernization-plan/security-plan-template.md create mode 100644 .github/skills/create-modernization-plan/supported-patterns-dotnet.md create mode 100644 .github/skills/create-modernization-plan/supported-patterns-java.md create mode 100644 .github/skills/create-modernization-plan/tasks-schema.json create mode 100644 .github/skills/cve-known-vulnerabilities/SKILL.md create mode 100644 .github/skills/cwe-code-quality/SKILL.md create mode 100644 .github/skills/cwe-concurrency-synchronization/SKILL.md create mode 100644 .github/skills/cwe-credentials-secrets/SKILL.md create mode 100644 .github/skills/cwe-file-path-security/SKILL.md create mode 100644 .github/skills/cwe-injection-attacks/SKILL.md create mode 100644 .github/skills/cwe-memory-safety/SKILL.md create mode 100644 .github/skills/data-architecture/SKILL.md create mode 100644 .github/skills/dependency-map/SKILL.md create mode 100644 .github/skills/execute-java-upgrade-task/SKILL.md create mode 100644 .github/skills/execute-modernization-task/SKILL.md create mode 100644 .github/skills/execute-upgrade-task/SKILL.md create mode 100644 .github/skills/fact-application-name/SKILL.md create mode 100644 .github/skills/fact-application-port/SKILL.md create mode 100644 .github/skills/fact-application-type/SKILL.md create mode 100644 .github/skills/fact-architecture-pattern/SKILL.md create mode 100644 .github/skills/fact-base-image/SKILL.md create mode 100644 .github/skills/fact-communication-protocols/SKILL.md create mode 100644 .github/skills/fact-compliance-requirements/SKILL.md create mode 100644 .github/skills/fact-container-engine/SKILL.md create mode 100644 .github/skills/fact-container-version/SKILL.md create mode 100644 .github/skills/fact-data-classification/SKILL.md create mode 100644 .github/skills/fact-embedded-language-usage/SKILL.md create mode 100644 .github/skills/fact-environment-variables/SKILL.md create mode 100644 .github/skills/fact-external-dependencies/SKILL.md create mode 100644 .github/skills/fact-external-services/SKILL.md create mode 100644 .github/skills/fact-hardware-requirements/SKILL.md create mode 100644 .github/skills/fact-health-checks/SKILL.md create mode 100644 .github/skills/fact-image-layers/SKILL.md create mode 100644 .github/skills/fact-image-size/SKILL.md create mode 100644 .github/skills/fact-language-dependencies/SKILL.md create mode 100644 .github/skills/fact-licensing-information/SKILL.md create mode 100644 .github/skills/fact-multi-stage-build/SKILL.md create mode 100644 .github/skills/fact-network-settings/SKILL.md create mode 100644 .github/skills/fact-operating-system/SKILL.md create mode 100644 .github/skills/fact-orchestration-tool/SKILL.md create mode 100644 .github/skills/fact-profile-settings/SKILL.md create mode 100644 .github/skills/fact-resource-limits/SKILL.md create mode 100644 .github/skills/fact-runtime-environment/SKILL.md create mode 100644 .github/skills/fact-security-implementation/SKILL.md create mode 100644 .github/skills/fact-service-definition/SKILL.md create mode 100644 .github/skills/fact-servlet-container/SKILL.md create mode 100644 .github/skills/fact-startup-instrumentation/SKILL.md create mode 100644 .github/skills/fact-system-packages/SKILL.md create mode 100644 .github/skills/fact-testing-framework/SKILL.md create mode 100644 .github/skills/fact-version-information/SKILL.md create mode 100644 .github/skills/fact-volume-mounts/SKILL.md create mode 100644 .github/skills/fact-xml-configs/SKILL.md create mode 100644 .github/skills/integration-tests/SKILL.md create mode 100644 .github/skills/integration-tests/references/azure-auth-strategies.md create mode 100644 .github/skills/integration-tests/references/azure-servicebus-testcontainers.md create mode 100644 .github/skills/integration-tests/references/azure-storage-testcontainers.md create mode 100644 .github/skills/integration-tests/references/layer1-local-integration.md create mode 100644 .github/skills/integration-tests/references/layer2-runner-script-templates.md create mode 100644 .github/skills/integration-tests/references/layer2-smoke-tests.md create mode 100644 .github/skills/integration-tests/references/layer3-azure-integration.md create mode 100644 .github/skills/integration-tests/references/layer4-behavioral-comparison.md create mode 100644 .github/skills/playbook-create/SKILL.md create mode 100644 .github/skills/playbook-create/charter-template.md create mode 100644 .github/skills/playbook-create/policies-template.md create mode 100644 .github/skills/playbook-create/targets-template.md create mode 100644 .github/skills/rearchitect/SKILL.md create mode 100644 .github/skills/reconcile-tasks-with-plan/SKILL.md create mode 100644 .github/skills/repository-dependency-graph/SKILL.md create mode 100644 .github/skills/security-assessment-merge/SKILL.md create mode 100644 .github/skills/validate-playbook-compliance/SKILL.md create mode 100644 .github/skills/validate-playbook-evidence/SKILL.md diff --git a/.github/modernize/ccacontext/.ccaskills b/.github/modernize/ccacontext/.ccaskills new file mode 100644 index 000000000..637e49324 --- /dev/null +++ b/.github/modernize/ccacontext/.ccaskills @@ -0,0 +1,64 @@ +assessment +create-dotnet-upgrade-plan +create-java-upgrade-plan +create-modernization-plan +execute-java-upgrade-task +execute-modernization-task +execute-upgrade-task +integration-tests +playbook-create +reconcile-tasks-with-plan +validate-playbook-compliance +validate-playbook-evidence +api-service-contracts +architecture-diagram +business-workflows +configuration-inventory +cve-known-vulnerabilities +cwe-code-quality +cwe-concurrency-synchronization +cwe-credentials-secrets +cwe-file-path-security +cwe-injection-attacks +cwe-memory-safety +data-architecture +dependency-map +fact-application-name +fact-application-port +fact-application-type +fact-architecture-pattern +fact-base-image +fact-communication-protocols +fact-compliance-requirements +fact-container-engine +fact-container-version +fact-data-classification +fact-embedded-language-usage +fact-environment-variables +fact-external-dependencies +fact-external-services +fact-hardware-requirements +fact-health-checks +fact-image-layers +fact-image-size +fact-language-dependencies +fact-licensing-information +fact-multi-stage-build +fact-network-settings +fact-operating-system +fact-orchestration-tool +fact-profile-settings +fact-resource-limits +fact-runtime-environment +fact-security-implementation +fact-service-definition +fact-servlet-container +fact-startup-instrumentation +fact-system-packages +fact-testing-framework +fact-version-information +fact-volume-mounts +fact-xml-configs +rearchitect +repository-dependency-graph +security-assessment-merge diff --git a/.github/modernize/ccacontext/cleanup.sh b/.github/modernize/ccacontext/cleanup.sh new file mode 100644 index 000000000..72b039d23 --- /dev/null +++ b/.github/modernize/ccacontext/cleanup.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Removes CCA-copied skill directories listed in .ccaskills +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SKILLS_DIR="$(cd "$SCRIPT_DIR/../../skills" && pwd)" +SKILLS_DIR_REAL="$(cd "$SKILLS_DIR" && pwd -P)" +CCASKILLS="$SCRIPT_DIR/.ccaskills" + +if [ ! -f "$CCASKILLS" ]; then + echo "No .ccaskills file found, nothing to clean." + exit 0 +fi + +while IFS= read -r skill; do + skill="${skill%$'\r'}" + [ -z "$skill" ] && continue + + case "$skill" in + /*|*\\*|*/*|*..*) + echo "Skipping invalid skill entry: $skill" + continue + ;; + esac + + target="$SKILLS_DIR/$skill" + if [ -d "$target" ]; then + target_real="$(cd "$target" 2>/dev/null && pwd -P)" + if [ -z "$target_real" ]; then + echo "Skipping unresolved path: $skill" + continue + fi + + case "$target_real" in + "$SKILLS_DIR_REAL"/*) + rm -rf -- "$target_real" + echo "Removed: $skill" + ;; + *) + echo "Skipping out-of-scope path: $skill" + ;; + esac + fi +done < "$CCASKILLS" + +rm -f "$CCASKILLS" +echo "Cleanup complete." diff --git a/.github/skills/api-service-contracts/SKILL.md b/.github/skills/api-service-contracts/SKILL.md new file mode 100644 index 000000000..bcbbe5e28 --- /dev/null +++ b/.github/skills/api-service-contracts/SKILL.md @@ -0,0 +1,210 @@ +--- +name: api-service-contracts +description: Generate API and service communication contracts with sequence diagram +--- + +# API & Service Communication Contracts + +Analyze the project to document all services, API endpoints, communication patterns (sync/async), DTOs, and retry/circuit-breaker policies. Generate a Mermaid sequence diagram showing the primary request flow across services. Save to `.github/modernize/assessment/engines/api-service-contracts.md`. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Scope Boundaries — Avoid Redundancy with Other Skills + +This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: + +- **Introduction**: Write a 1-2 sentence intro focused on the API surface (number of endpoints, communication style). Do NOT restate the application's technology stack, database options, or architecture type — those are covered by other skills. +- **Entity fields and persistence details** are owned by the `data-architecture` skill. In the DTOs & Contracts section, list entity/DTO **class names** and their role in the API contract (request type, response type, immutability). Do NOT reproduce full field lists, ORM annotations (cascade, fetch strategy), or table names — reference `data-architecture.md` instead. +- **Validation rules** (e.g., `@NotBlank`, custom validators) are owned by the `business-workflows` skill. Mention validation only when it affects the API contract (e.g., "returns 400 if validation fails"). Do NOT enumerate individual field constraints. +- **Caching implementation details** (provider, TTL, configuration class) are owned by the `data-architecture` skill. In the sequence diagram, you may show cache hit/miss behavior, but do NOT repeat the cache provider name, configuration details, or rationale. +- **Configuration properties and profiles** (e.g., `spring.jpa.*`, database profiles) are owned by the `configuration-inventory` skill. Do NOT list property keys/values. +- **Startup dependency chain details** (readiness probes, K8s manifests, dockerize) are owned by the `configuration-inventory` skill. Mention startup order only if it directly affects API availability. Do NOT repeat probe paths or wait mechanisms. + +## Execution Steps + +### Step 1: Generate Service Catalog Section + +Identify all independently deployable services/modules and produce the complete `## Service Catalog` section: + +- Multi-module builds: Maven modules (`pom.xml` ``), Gradle subprojects (`settings.gradle`), .NET solutions (`.sln` → `.csproj` projects), monorepo workspaces (`package.json` workspaces) +- Docker Compose services (`docker-compose.yml` service definitions) — note third-party containers vs source-built services +- Kubernetes deployments, Helm charts, or IaC definitions + +For each service extract: +- Service name and Maven module / project name +- Port number (from config files, `docker-compose.yml`, or `application.properties`/`appsettings.json`) +- Category: **API Layer** (gateways, BFFs), **Business** (domain services), **Infrastructure** (config, discovery, admin), **Observability** (tracing, metrics, dashboards) +- Purpose (one-line description) +- Key framework dependencies (from `pom.xml`, `.csproj`, `package.json`) + +### Step 2: Generate API Endpoints Inventory Section + +Scan source code for API endpoint definitions and produce the complete `## API Endpoints Inventory` section: + +- Java (Spring): `@RestController`, `@Controller`, `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`, `@RequestMapping` +- Java (Jakarta EE): `@Path`, `@GET`, `@POST`, `@PUT`, `@DELETE` (JAX-RS) +- .NET (ASP.NET Core): `[ApiController]`, `[HttpGet]`, `[HttpPost]`, `[HttpPut]`, `[HttpDelete]`, `[Route]` +- JavaScript/TypeScript: Express routes (`app.get`, `app.post`, `router.get`), Fastify routes, NestJS decorators (`@Get`, `@Post`) + +For each endpoint extract: +- HTTP method (GET, POST, PUT, DELETE, PATCH) +- URL path (including path parameters) +- Request type (body/query/path parameters, DTO class name) +- Response type (DTO class name, status codes) +- API versioning scheme if present (URL path, header, query parameter) +- Which service/controller it belongs to + +### Step 3: Generate Management & Observability Endpoints Section + +Identify management and observability endpoints and produce the complete `## Management & Observability Endpoints` section: + +- Spring Boot Actuator endpoints (`/actuator/health`, `/actuator/info`, `/actuator/metrics`, `/actuator/prometheus`) +- .NET health checks (`/health`, `/healthz`), Swagger UI (`/swagger`) +- Custom metrics annotations: `@Timed` (Micrometer), `[Meter]`, custom metric registrations — note the metric name and which service exposes it + +### Step 4: Generate DTOs & Contracts Section + +Analyze DTO and contract definitions and produce the complete `## DTOs & Contracts` section: + +- Find DTO / request / response model classes (records, POJOs, C# records/classes). List class names and their API role (request body, response, path/query param). Do NOT reproduce full field lists or ORM annotations — those belong in `data-architecture.md`. +- **Distinguish gateway-level DTOs** (aggregation/composition models that combine data from multiple services) from **service-level domain entities** (owned by a single service) +- Note which DTOs are immutable (Lombok `@Value`, Java records, C# records, frozen data classes) +- Identify OpenAPI/Swagger specifications (`openapi.yaml`, `swagger.json`, Springdoc/Swashbuckle annotations) +- Check for protobuf schemas (`.proto` files) or GraphQL schemas +- Note serialization configuration (Jackson, System.Text.Json, custom serializers) + +### Step 5: Generate Communication Patterns Section + +Identify inter-service and intra-service communication and produce the complete `## Communication Patterns` section: + +- **Synchronous**: REST (HttpClient, RestTemplate, WebClient, Feign), gRPC, direct method calls +- **Asynchronous**: Message queues (Kafka, RabbitMQ, Azure Service Bus, SQS), event-driven patterns, pub/sub +- **Resilience patterns**: Circuit breaker (Resilience4j, Polly, Spring Retry), retry policies, timeout configuration, bulkhead patterns — note specific timeout values and fallback behavior +- **Service discovery**: Eureka, Consul, Kubernetes DNS, Azure Service Discovery — note whether services register by logical name or hardcoded URL +- **API gateway**: Spring Cloud Gateway, Ocelot, Kong, custom gateway patterns +- **Gateway aggregation/composition**: Document how the gateway combines responses from multiple backend services (e.g., fetching owner details from one service and visit history from another, then merging them into a single response). Note the composition logic and fallback behavior when a downstream service is unavailable. +- **Client-side load balancing**: Spring Cloud LoadBalancer, Ribbon, or framework-provided balancing +- **Startup dependency chain**: Briefly note the service startup order if it affects API availability. For full details (probes, wait mechanisms, timeouts), refer to `configuration-inventory.md`. +- **Security posture**: Note whether transport security (HTTPS/TLS), authentication (JWT, OAuth2, Basic Auth, Spring Security), or authorization (RBAC, `@PreAuthorize`, role checks) are implemented at the API level. If absent, state it explicitly — e.g., "No authentication or TLS configured; all endpoints are publicly accessible with no authorization checks." Do NOT duplicate CWE security scan findings; focus only on presence or absence at the API contract level. + +### Step 6: Generate Service Technology Matrix Section + +For each service, identify which cross-cutting capabilities it uses and produce the complete `## Service Technology Matrix` section: + +- Web framework (MVC, Reactive/WebFlux, Minimal API) +- Data access (JPA, EF Core, Mongoose, etc.) +- Service discovery (client, server, or none) +- Gateway functionality +- Actuator/health checks +- Caching layer +- Metrics export (Prometheus, Application Insights, etc.) + +### Step 7: Generate Service Communication Sequence Section + +Create a **Mermaid `sequenceDiagram`** and produce the complete `## Service Communication Sequence` section: +- Show key actors: Client, API Gateway (if present), Controllers, Services, External Services, Message Brokers +- Annotate synchronous calls with solid arrows and asynchronous calls with dashed arrows +- Include request/response types where relevant +- Show error handling paths for critical flows (circuit breaker, retry) +- For gateway aggregation flows, show how multiple downstream calls are composed + +Example: + +~~~mermaid +sequenceDiagram + participant Client + participant Gateway as "API Gateway" + participant CustSvc as "Customers Service" + participant VisitSvc as "Visits Service" + participant DB as "Database" + + Client->>Gateway: GET /api/gateway/owners/1 + Gateway->>CustSvc: GET /owners/1 + CustSvc->>DB: findById(1) + DB-->>CustSvc: Owner + Pets + CustSvc-->>Gateway: OwnerDetails(pets=[Pet1,Pet2]) + Gateway->>VisitSvc: GET /pets/visits?petId=1,2 + alt Visits Service Available + VisitSvc->>DB: findByPetIdIn([1,2]) + DB-->>VisitSvc: Visits list + VisitSvc-->>Gateway: Visits(items=[...]) + else Circuit Breaker Open + Gateway-->>Gateway: Fallback - empty visits + end + Gateway->>Gateway: Merge visits into pets + Gateway-->>Client: 200 OwnerDetails + Visits +~~~ + +### Step 8: Save Output + +Save to `.github/modernize/assessment/engines/api-service-contracts.md` with this exact structure: + +``` +# API & Service Communication Contracts + +A brief introduction (1-2 sentences) summarizing the API surface and communication patterns found. + +## Service Catalog + +[Table: Service | Port | Category | Purpose] + +## API Endpoints Inventory + +[Table: Service | Method | Path | Request Type | Response Type] + +## Management & Observability Endpoints + +[Table: Service | Endpoint | Custom Metrics (if any)] + +## DTOs & Contracts + +[Description of gateway-level DTOs vs service-level entities, immutability, serialization] + +## Communication Patterns + +[Description of sync/async patterns, gateway aggregation/composition logic, circuit breaker/retry policies with timeout values, service discovery, startup dependency chain, and security posture (authentication/authorization/TLS — or explicit statement that none is configured)] + +## Service Technology Matrix + +[Table: Service | Web | Data Access | Discovery | Gateway | Actuator | Cache | Metrics] + +## Service Communication Sequence + +< Mermaid sequenceDiagram here > +``` + +## Scaling Rules + +- If the project has **more than 30 endpoints**, group by service/controller and show representative endpoints per group +- Keep the sequence diagram under **40 participants and messages** to ensure readability and GitHub rendering compatibility +- For multi-module projects, focus on inter-module communication in the sequence diagram and list all endpoints in the table +- Aggregate similar endpoints (e.g., CRUD operations on the same resource) into one table row if needed for brevity +- For the service technology matrix, use checkmarks or short labels; omit columns where no service uses the capability + +## Mermaid Syntax Rules + +- Use `sequenceDiagram` +- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in participant labels — use plain text or quoted labels +- Use `->>` for synchronous calls and `-->>` for responses/async messages +- Use `participant` with alias syntax for readable labels: `participant Svc as "OrderService"` +- Use `alt`/`else`/`end` blocks to show circuit breaker fallback paths +- Do not use backticks inside node labels + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No API endpoints found**: Output: `> ERROR: No recognized API endpoints found at {workspace-path}. Verify the path is correct.` +- **Insufficient info**: Generate a best-effort document from available data. Add a note: `> Note: Some endpoints or communication patterns could not be fully identified.` + +## Success Criteria + +- Service catalog table lists all discovered services with ports, categories, and purposes +- API endpoints table lists all discovered endpoints with HTTP method, path, and types +- Management/observability endpoints are cataloged with custom metric names +- Gateway aggregation/composition patterns are documented with fallback behavior +- Service technology matrix shows per-service capabilities +- Communication patterns section describes sync/async patterns, resilience policies, and security posture (authentication, authorization, TLS — explicitly stating if none is configured) +- Mermaid sequence diagram renders correctly showing primary request flow with aggregation and fallback +- File saved to `.github/modernize/assessment/engines/api-service-contracts.md` diff --git a/.github/skills/architecture-diagram/SKILL.md b/.github/skills/architecture-diagram/SKILL.md new file mode 100644 index 000000000..e74695943 --- /dev/null +++ b/.github/skills/architecture-diagram/SKILL.md @@ -0,0 +1,190 @@ +--- +name: architecture-diagram +description: Generate architecture diagram with component relationship details from project analysis +--- + +# Architecture Diagram + +This skill generates a two-layer architecture visualization: a high-level application architecture diagram and a detailed component relationship diagram. Produce both in a single pass and save to `.github/modernize/assessment/engines/architecture-diagram.md`. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Execution Steps + +### Step 1: Generate Application Architecture Section + +Analyze the project and produce the complete `## Application Architecture` section in one pass: + +**Analysis:** +- Examine build files (Java: pom.xml, build.gradle; .NET: *.csproj, *.sln; JS/TS: package.json, tsconfig.json) +- Review configuration files (application.properties, appsettings.json, .env, database/API configs) +- Scan key source files to extract: framework, major dependencies, data access patterns, external integrations, technology stack +- Identify application layers (UI, Business Logic, Data Access), data storage technologies, and external service dependencies + +**Diagram — Mermaid `flowchart TD`:** +- Application layers with technology info (use `subgraph` for grouping) +- Data storage components (specific names like "PostgreSQL", "Redis") +- External service integrations +- Data flow with descriptive arrow labels + +**Do NOT include**: individual classes/methods or migration directions. + +Example: + +~~~mermaid +flowchart TD + subgraph Client["Client Layer"] + Browser["Web Browser"] + end + subgraph App["Application Layer - Spring Boot 2.7"] + Web["Spring MVC + Thymeleaf"] + Security["Spring Security"] + Service["Business Services"] + end + subgraph Data["Data Layer"] + JPA["Spring Data JPA"] + DB[("PostgreSQL 14")] + Cache[("Redis")] + end + subgraph External["External Services"] + SMTP["SMTP Email Service"] + S3["AWS S3 Storage"] + end + + Browser -->|"HTTP requests"| Web + Web --> Security -->|"authorized"| Service + Service -->|"CRUD operations"| JPA + JPA -->|"SQL queries"| DB + Service -->|"session cache"| Cache + Service -->|"send email"| SMTP + Service -->|"file upload"| S3 +~~~ + +**Textual explanations (write immediately after the diagram):** +- **Technology Stack Summary table**: Layer | Technology | Version | Purpose (e.g., Presentation | ASP.NET MVC 5 | 5.2.7 | Server-side web framework) +- **Data Storage & External Services**: A short paragraph describing what databases, caches, message brokers, or external APIs are used and how they fit into the architecture +- **Key Architectural Decisions**: 1-3 bullet points on notable patterns (e.g., "Uses repository pattern with EF6 for data access", "Autofac provides DI with module-based registration") + +### Step 2: Generate Component Relationships Section + +Analyze component interactions and produce the complete `## Component Relationships` section in one pass: + +**Analysis:** +- Identify key component types by framework conventions: + - Java (Spring): Controllers, Services, Repositories, Configurations, Entities, DTOs, Listeners, Filters + - Java (Jakarta EE): Servlets, EJBs, CDI Beans, JPA Entities, JAX-RS Resources + - .NET (ASP.NET Core): Controllers, Services, Middleware, DbContext, Entities, Hubs, Filters + - .NET (Blazor/MVC): Pages, Components, ViewModels + - JavaScript/TypeScript (Node.js): Routes, Controllers, Services, Middleware, Models + - JavaScript/TypeScript (React/Angular/Vue): Components, Hooks, Services, Stores, Pages +- Trace dependency injection (constructor/field injection) +- Map communication patterns (REST, gRPC, message queues, events) +- Map data access patterns (service-to-repository, DbContext usage) +- Detect cross-cutting concerns (middleware, interceptors, filters) + +**Diagram — Mermaid `flowchart LR`:** +- Components grouped by architectural layer using `subgraph` (Presentation, Business Logic, Data Access, Infrastructure) +- Interaction arrows with brief labels +- Cross-cutting concerns + +**Do NOT include**: method signatures, private helpers, or external dependencies (covered by dependency-map skill). + +Example: + +~~~mermaid +flowchart LR + subgraph Presentation + UserCtrl["UserController"] + OrderCtrl["OrderController"] + end + subgraph Business["Business Logic"] + UserSvc["UserService"] + OrderSvc["OrderService"] + NotifSvc["NotificationService"] + end + subgraph DataAccess["Data Access"] + UserRepo["UserRepository"] + OrderRepo["OrderRepository"] + end + subgraph Infra["Infrastructure"] + AuthFilter["AuthenticationFilter"] + LogMiddleware["LoggingMiddleware"] + end + + UserCtrl -->|"delegates"| UserSvc + OrderCtrl -->|"delegates"| OrderSvc + OrderSvc -->|"lookups"| UserSvc + OrderSvc -->|"triggers"| NotifSvc + UserSvc -->|"queries"| UserRepo + OrderSvc -->|"queries"| OrderRepo + AuthFilter -.->|"intercepts"| UserCtrl + AuthFilter -.->|"intercepts"| OrderCtrl + LogMiddleware -.->|"wraps"| Presentation +~~~ + +**Textual explanation (write immediately after the diagram):** +- **Component Inventory table**: Component | Layer | Type | Responsibility (e.g., CatalogController | Presentation | MVC Controller | Handles catalog browsing and CRUD) + +### Step 3: Save Output + +Save the combined output to `.github/modernize/assessment/engines/architecture-diagram.md` with this exact structure: + +``` +# Architecture Diagram + +A brief introduction (1-2 sentences). + +## Application Architecture + +< Layer 1 Mermaid flowchart TD here > + +### Technology Stack Summary + +[Table: Layer | Technology | Version | Purpose] + +### Data Storage & External Services + +[Short paragraph on databases, caches, external APIs] + +### Key Architectural Decisions + +[1-3 bullet points on notable patterns] + +## Component Relationships + +< Layer 2 Mermaid flowchart LR here > + +### Component Inventory + +[Table: Component | Layer | Type | Responsibility] +``` + +## Scaling Rules + +- If the project has **more than 30 components**, aggregate by package/namespace (e.g., show `com.example.orders` as one node instead of listing every class) +- Keep each diagram under **40 nodes** to ensure readability and GitHub rendering compatibility +- For multi-module projects, focus on inter-module boundaries in Layer 1 and key components within the most important modules in Layer 2 + +## Mermaid Syntax Rules + +- Use `flowchart TD` for Layer 1 and `flowchart LR` for Layer 2 +- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in node labels — use plain text +- Always quote arrow labels with double quotes: `-->|"label"|` +- Use `subgraph` for grouping, with a display name in quotes if it contains spaces +- Verify all node IDs are unique across the entire diagram + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No source code found**: Output: `> ERROR: No recognized source files found at {workspace-path}. Verify the path is correct.` +- **Insufficient info**: Generate a best-effort diagram from available data. Add a note inside the diagram: `Note["Some components could not be identified"]` + +## Success Criteria + +- Layer 1 Mermaid diagram renders correctly showing architecture with technology names, data storage, and external dependencies +- Layer 1 is accompanied by Technology Stack Summary table, Data Storage & External Services paragraph, and Key Architectural Decisions +- Layer 2 Mermaid diagram renders correctly showing component interactions grouped by architectural layer +- Layer 2 is accompanied by Component Inventory table +- File saved to `.github/modernize/assessment/engines/architecture-diagram.md` diff --git a/.github/skills/assessment/SKILL.md b/.github/skills/assessment/SKILL.md new file mode 100644 index 000000000..a9c4cae77 --- /dev/null +++ b/.github/skills/assessment/SKILL.md @@ -0,0 +1,173 @@ +--- +name: assessment +description: Run application assessment for a single repository +--- + +# Application Assessment + +This skill performs application assessment for a single repository. It supports Java, .NET, and JavaScript/TypeScript projects. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to assess. Defaults to the current directory (repository root) when not specified. All assessment outputs are written relative to this path (e.g. `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json`). For a repository with multiple sub-projects, pass the sub-project directory path so that each sub-project's outputs are isolated. + +## When to Use This Skill + +Use this skill when you need to: + +- Assess a Java or .NET application for cloud readiness and migration issues +- Assess a JavaScript/TypeScript project for outdated dependencies and available updates +- Generate detailed assessment reports with issue analysis and recommendations +- Understand application dependencies, frameworks, and potential migration blockers + +## What This Skill Does + +This skill performs a simplified assessment workflow: + +1. **Check Project Type and Prerequisites**: + - **For Java projects**: Verify that MCP tools are available ('appmod-precheck-assessment' and 'appmod-run-assessment') + - If these MCP tools are not configured, return immediately with setup instructions + - **For .NET projects**: Check if .NET SDK is available + - No MCP tools required for .NET assessment + - **For JavaScript/TypeScript projects**: Check if Node.js and npm are available + - No MCP tools required for JS/TS assessment + +2. **Run Assessment**: + - **For Java projects**: Trigger AppCAT analysis via Assessment MCP server + - Uses 'appmod-precheck-assessment' and 'appmod-run-assessment' MCP tools + - Auto-detects project configuration within `{workspace-path}` + - **For .NET projects**: Install and run AppCAT directly + - Install: `dotnet tool update dotnet-appcat` + - Find all .csproj files under `{workspace-path}` + - Join project paths with semicolons: `projectPaths="project1.csproj;project2.csproj"` + - Run: `dotnet-appcat analyze $projectPaths --source Solution --target Any --serializer APPMODJSON --code --privacyMode Restricted --non-interactive --report {workspace-path}\.github\modernize\appcat\result\report.json` + - **For JavaScript/TypeScript projects**: Install and run npm-check-updates + - Install: `npm install -g npm-check-updates@19.6.3 --prefix {tool-install-dir}` + - Run: `ncu --format group --packageFile {workspace-path}/package.json` + - Save the output to `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` + - Analyzes code for cloud migration issues or dependency updates + - Generates structured assessment data + +3. **Save Report to Versioned Directory (Java and .NET only)**: + - **For Java projects**: Search for `report.json` under `{workspace-path}/.github/modernize/appcat/result/` or `{workspace-path}/.github/appmod/appcat/result/` subdirectories + - **For .NET projects**: The report is at `{workspace-path}/.github/modernize/appcat/result/report.json` + - Read the generated `report.json` and extract the `metadata.analysisStartTime` field + - Format the timestamp as `yyyyMMddHHmmss` to produce the `reportId` (e.g. `2024-06-15T14:30:52Z` becomes `20240615143052`) + - Create the versioned directory: `mkdir -p {workspace-path}/.github/modernize/assessment/reports/report-{reportId}` + - Move the report to: `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` + - This versioned report should be included in the pull request + +## How to Use + +### Prerequisites + +**For Java projects**: +- MCP tools must be available: 'appmod-precheck-assessment' and 'appmod-run-assessment' +- If tools are not configured, the skill will return instructions for setup + +**For .NET projects**: +- .NET SDK must be installed +- No MCP tools required - appcat will be installed and run directly via .NET CLI +- The assessment will automatically install `dotnet-appcat` tool if not already present + +**For JavaScript/TypeScript projects**: +- Node.js and npm must be installed +- No MCP tools required - npm-check-updates will be installed and run directly via npm +- The assessment will automatically install `npm-check-updates` if not already present + +### Triggering Assessment + +Simply express the intent to assess the application. Example prompts: + +- "Assess the application" +- "Run assessment for this project" + +The assessment process automatically: +- Detects project language and framework within `{workspace-path}` +- **For Java**: Uses MCP tools to install and run AppCAT +- **For .NET**: Installs dotnet-appcat tool and runs analysis directly +- **For JavaScript/TypeScript**: Installs npm-check-updates and runs dependency analysis +- Executes comprehensive analysis +- **For Java**: Generates report at `{workspace-path}/.github/modernize/appcat/result/` or `{workspace-path}/.github/appmod/appcat/result/report.json` +- **For .NET**: Generates report at `{workspace-path}/.github/modernize/appcat/result/report.json` +- **For JavaScript/TypeScript**: Generates report at `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` + +### Report Saving + +**For Java projects**: +1. Search for `report.json` files under `{workspace-path}/.github/modernize/appcat/result/` or `{workspace-path}/.github/appmod/appcat/result/` subdirectories +2. If multiple reports exist, identify the most recently modified one +3. Read the report and extract `metadata.analysisStartTime`, format as `yyyyMMddHHmmss` to get `reportId` +4. Move the report to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` +5. Include this versioned report in the pull request + +**For .NET projects**: +1. Report is initially generated at `{workspace-path}/.github/modernize/appcat/result/report.json` +2. Read the report and extract `metadata.analysisStartTime`, format as `yyyyMMddHHmmss` to get `reportId` +3. Move the report to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` +4. Include this versioned report in the pull request + +**For JavaScript/TypeScript projects**: +1. Report is directly generated at `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` +2. Include this report in the pull request + +## Report Output Location + +Report location depends on project type: + +**For Java projects** (via MCP server): +- Initially stored under `{workspace-path}/.github/modernize/appcat/result/` or `{workspace-path}/.github/appmod/appcat/result/` subdirectories +- Saved to versioned directory: `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` + +Where `{reportId}` is derived from `metadata.analysisStartTime` in the report, formatted as `yyyyMMddHHmmss`. + +**For .NET projects** (direct execution): +- Initially generated at: `{workspace-path}/.github/modernize/appcat/result/report.json` +- Moved to versioned directory: `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` + +**For JavaScript/TypeScript projects** (direct execution): +- Directly generated at: `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` + +## Success Criteria + +Assessment is complete when: +- ✅ **For Java**: MCP server is available (or clear instructions provided if not) +- ✅ **For .NET**: .NET SDK is available and dotnet-appcat tool is installed +- ✅ **For JavaScript/TypeScript**: Node.js and npm are available and npm-check-updates is installed +- ✅ AppCAT analysis executes without errors (Java/.NET) or ncu analysis executes without errors (JS/TS) +- ✅ **For Java and .NET**: Report generated at `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` +- ✅ **For JavaScript/TypeScript**: Report generated at `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` +- ✅ Report metadata includes assessment tool version, timestamp, and configuration + +## Troubleshooting + +**Prerequisites Not Met**: +- **For Java**: Verify MCP tools are available ('appmod-precheck-assessment' and 'appmod-run-assessment') + - Return immediately with setup instructions if tools are not available + - Do not attempt to run assessment without MCP +- **For .NET**: Verify .NET SDK is installed + - Check with `dotnet --version` command + - Provide installation instructions if .NET SDK is missing +- **For JavaScript/TypeScript**: Verify Node.js and npm are installed + - Check with `npm --version` command + - Provide installation instructions if npm is missing + +**Assessment Failures**: +- Unsupported project type (only Java, .NET, and JavaScript/TypeScript supported) +- **For Java**: MCP server communication errors +- **For .NET**: + - dotnet-appcat tool installation failure + - dotnet-appcat command execution errors +- **For JavaScript/TypeScript**: + - npm-check-updates installation failure + - ncu command execution errors + - No package.json found at `{workspace-path}/package.json` +- Invalid project structure or build configuration + +**Report Generation Issues**: +- **For Java**: No report.json found under `{workspace-path}/.github/modernize/appcat/result/` or `{workspace-path}/.github/appmod/appcat/result/` subdirectories after MCP execution +- **For .NET**: Report not generated at `{workspace-path}/.github/modernize/appcat/result/report.json`, or `metadata.analysisStartTime` missing from report +- **For JavaScript/TypeScript**: Report not generated at `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` +- Report file is corrupted or invalid JSON (Java/.NET only) + +For any failure, provide clear error messages and troubleshooting steps. diff --git a/.github/skills/business-workflows/SKILL.md b/.github/skills/business-workflows/SKILL.md new file mode 100644 index 000000000..73d79be9b --- /dev/null +++ b/.github/skills/business-workflows/SKILL.md @@ -0,0 +1,199 @@ +--- +name: business-workflows +description: Generate core business workflow documentation with sequence diagram +--- + +# Core Business Workflows + +Analyze the project to document business processes end-to-end, domain entities, business rules, service-to-domain mapping, cross-service data flows, and decision logic. Generate a Mermaid sequence diagram showing the primary business workflow. Save to `.github/modernize/assessment/engines/business-workflows.md`. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Scope Boundaries — Avoid Redundancy with Other Skills + +This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: + +- **Introduction**: Write a 1-2 sentence intro focused on the business domain (what the application does for its users). Do NOT restate the technology stack, database options, or framework versions. +- **Domain Entities table**: Focus on business meaning — entity description, bounded context, and business relationships. Do NOT reproduce entity field lists, data types, PK/FK annotations, or ORM mapping details (cascade, fetch strategy) — those are owned by the `data-architecture` skill. +- **Validation rules in workflow steps**: When describing a workflow step that involves validation, reference the rule by name (e.g., "PetValidator checks name and birthDate") rather than re-listing every constraint. Enumerate the full validation rules only once in the "Business Rules & Decision Logic" section. +- **Caching behavior**: If caching affects a workflow (e.g., vet list served from cache), mention the business impact (e.g., "vet data served from cache, reducing load") but do NOT describe the cache provider, TTL, configuration class, or JMX statistics — those are owned by the `data-architecture` skill. +- **API endpoint paths and HTTP methods**: Only mention endpoint paths as entry points for workflows (e.g., "Staff submits POST /owners/new"). Do NOT create endpoint inventory tables — those are owned by the `api-service-contracts` skill. + +## Execution Steps + +### Step 1: Generate Domain Entities Section + +Identify the domain model and produce the complete `## Domain Entities` section: + +- Identify domain entities and aggregates (DDD patterns if present) +- Focus on business meaning — entity description, bounded context, and business relationships +- Do NOT reproduce entity field lists, data types, PK/FK annotations, or ORM mapping details (cascade, fetch strategy) — those are owned by the `data-architecture` skill + +### Step 2: Generate Service-to-Domain Mapping Section + +Map each service to its bounded context and owned entities, then produce the complete `## Service-to-Domain Mapping` section (applies to microservice or multi-module architectures): + +- Service name → bounded context (e.g., `customers-service` → Customer Management, `visits-service` → Appointment Management) +- Domain entities owned by each service/context +- Cross-context data exchange patterns: how domains communicate (REST API, events, shared database) +- Data that spans contexts (e.g., `petId` as a foreign key in visits-service referencing customers-service's Pet entity) +- Aggregation boundaries: which service is the source of truth for which data + +### Step 3: Generate Primary Workflows Section + +Scan for business process entry points, trace each significant workflow end-to-end, and produce the complete `## Primary Workflows` section: + +**Entry points to scan:** +- Controllers/endpoints that initiate business processes (not just CRUD — look for multi-step operations) +- **API Gateway aggregation endpoints** that compose responses from multiple backend services — these are business workflow entry points even though they live in the gateway layer (e.g., fetching owner details combined with visit history) +- Scheduled tasks (`@Scheduled`, Quartz, Hangfire, cron jobs, `BackgroundService`) +- Event listeners (`@EventListener`, `@KafkaListener`, `INotificationHandler`, message handlers) +- CLI commands or batch job entry points +- Startup/initialization routines that set up business state + +**For each significant entry point, trace the flow:** +- Entry point → service layer → domain logic → persistence +- The sequence of operations: validation → business rule check → state mutation → side effects +- Branching logic (if/else, switch, strategy pattern) that represents business decisions +- Orchestration vs choreography patterns in multi-service workflows + +### Step 4: Generate Cross-Service Data Flows Section + +Trace cross-service data composition flows end-to-end and produce the complete `## Cross-Service Data Flows` section: + +- Gateway aggregation patterns: e.g., gateway fetches owner from customers-service → extracts pet IDs → fetches visits from visits-service → merges visits into pet records → returns composite response +- Which service provides which data and how they are joined/merged +- Circuit breaker fallback behavior that affects business outcomes (e.g., "when visits-service is unavailable, owner details are returned without visit history" — this is a business-relevant degradation, not just a technical detail) + +### Step 5: Generate Business Workflow Sequence Section + +Create a **Mermaid `sequenceDiagram`** showing the primary business workflow end-to-end and produce the complete `## Business Workflow Sequence` section: + +- Show the most important business process (e.g., "customer places order", "owner registers pet and schedules visit", "gateway aggregates owner with visit history") +- Include actors, services, and domain entities as participants +- Show business rule checks and decision points +- Annotate with business-relevant labels (not technical method names) +- Use `alt`/`else` blocks to show circuit breaker fallback paths that affect business outcomes +- Show cross-service data aggregation flows + +Example: + +~~~mermaid +sequenceDiagram + participant Owner + participant Gateway as "API Gateway" + participant CustSvc as "Customer Service" + participant VisitSvc as "Visit Service" + participant DB as "Database" + + Owner->>Gateway: View my pets and visits + Gateway->>CustSvc: Get owner details + CustSvc->>DB: Find owner with pets + DB-->>CustSvc: Owner + Pet list + CustSvc-->>Gateway: OwnerDetails(pets) + + Gateway->>Gateway: Extract pet IDs from response + Gateway->>VisitSvc: Get visits for pets (batch) + alt Visit Service Available + VisitSvc->>DB: Find visits by pet IDs + DB-->>VisitSvc: Visit records + VisitSvc-->>Gateway: Visits per pet + Gateway->>Gateway: Merge visits into pet records + else Visit Service Unavailable (Circuit Breaker) + Note over Gateway: Fallback - return owner without visits + end + Gateway-->>Owner: Complete owner profile with visits +~~~ + +### Step 6: Generate Business Rules & Decision Logic Section + +Extract and document business rules and cross-cutting concerns, and produce the complete `## Business Rules & Decision Logic` section: + +**Business Rules:** +- **Validation rules**: Input validation, field constraints, format checks, custom validators +- **Decision logic**: Conditional business logic, pricing rules, eligibility checks, approval workflows +- **State transitions**: Entity lifecycle states (e.g., Order: Created → Confirmed → Shipped → Delivered), state machines +- **Business constraints**: Uniqueness rules, capacity limits, temporal constraints (booking windows, cooldown periods) +- **Computed values**: Derived fields, calculated totals, aggregated metrics +- **Data integrity rules**: Bidirectional relationship maintenance (e.g., `owner.addPet(pet)` ensuring both sides of the relationship are set) + +**Cross-Cutting Concerns:** +- **Transactions**: Transaction boundaries, `@Transactional` scope, saga patterns, eventual consistency +- **Error handling**: Business exception types, compensating actions, dead-letter handling +- **Audit/logging**: Business event logging, audit trails, change tracking +- **Authorization**: Business-level authorization rules (role-based, attribute-based, resource ownership) + +### Step 7: Save Output + +Save to `.github/modernize/assessment/engines/business-workflows.md` with this exact structure: + +``` +# Core Business Workflows + +A brief introduction (1-2 sentences) summarizing the application's business domain. + +## Domain Entities + +[Table: Entity | Service / Bounded Context | Description | Key Relationships] + +## Service-to-Domain Mapping + +[Table: Service | Domain Context | Owned Entities | External Dependencies] + +## Primary Workflows + +### Workflow 1: [Name] + +[Description, steps, business rules involved, cross-service interactions] + +### Workflow 2: [Name] + +[Description, steps, business rules involved] + +## Cross-Service Data Flows + +[Description of aggregation/composition patterns, which service provides which data, how data is joined, fallback behavior when services are unavailable] + +## Business Workflow Sequence + +< Mermaid sequenceDiagram here, with alt/else blocks for fallback paths > + +## Business Rules & Decision Logic + +[Summary of key business rules, validation rules, state transitions, and decision points] +``` + +## Scaling Rules + +- If the project has **more than 10 distinct workflows**, focus on the 3-5 most important business processes and summarize the rest in a "Other Workflows" section +- Keep the sequence diagram under **40 participants and messages** to ensure readability and GitHub rendering compatibility +- For multi-module projects, focus on the primary end-to-end business workflow that spans modules +- Aggregate minor CRUD operations and show only workflows that involve business logic beyond simple create/read/update/delete + +## Mermaid Syntax Rules + +- Use `sequenceDiagram` +- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in participant labels — use plain text or quoted labels +- Use `->>` for synchronous calls and `-->>` for responses +- Use `participant` with alias syntax for readable labels: `participant Svc as "OrderService"` +- Use `Note over` for annotations about business decisions or fallback behavior +- Use `alt`/`else`/`end` blocks for decision points and circuit breaker fallbacks +- Do not use backticks inside participant labels + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No business logic found**: Output: `> ERROR: No recognized business logic or workflows found at {workspace-path}. The project may be a library or framework without business processes.` +- **Insufficient info**: Generate a best-effort document from available data. Add a note: `> Note: Some workflows or business rules could not be fully traced.` + +## Success Criteria + +- Domain entities table lists key entities with their owning service/bounded context, descriptions, and relationships +- Service-to-domain mapping table maps each service to its domain context and owned entities +- At least one primary workflow is documented with steps, business rules, and cross-service interactions +- Cross-service data flows describe aggregation/composition patterns with fallback behavior +- Mermaid sequence diagram renders correctly showing end-to-end business workflow with `alt`/`else` blocks for fallbacks +- Business rules section summarizes validation, decision logic, state transitions, and constraints +- File saved to `.github/modernize/assessment/engines/business-workflows.md` diff --git a/.github/skills/configuration-inventory/SKILL.md b/.github/skills/configuration-inventory/SKILL.md new file mode 100644 index 000000000..780125774 --- /dev/null +++ b/.github/skills/configuration-inventory/SKILL.md @@ -0,0 +1,205 @@ +--- +name: configuration-inventory +description: Generate comprehensive configuration and externalized settings inventory +--- + +# Configuration & Externalized Settings Inventory + +Analyze the project to produce a comprehensive inventory of all configuration sources, build profiles, runtime profiles, externalized properties, secrets workflows, feature flags, startup dependencies, and framework versions. Save to `.github/modernize/assessment/engines/configuration-inventory.md`. + +> Note: This skill produces a comprehensive reference document. For structured findings suitable for automated processing, see `fact-profile-settings`, `fact-environment-variables`, and `fact-xml-configs`. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Scope Boundaries — Avoid Redundancy with Other Skills + +This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: + +- **Introduction**: Write a 1-2 sentence intro focused on the configuration landscape (number of config sources, profiles, secrets approach). Do NOT restate the application's architecture type, business domain, or API surface. +- **Database architecture details** (entity models, ER diagrams, ORM mappings, caching strategy rationale, repository methods) are owned by the `data-architecture` skill. In the Properties Inventory, list database-related property keys and values as raw configuration entries, but do NOT explain their behavioral implications (e.g., do not explain what `spring.jpa.open-in-view=false` means for lazy loading — that belongs in `data-architecture.md`). +- **API endpoints** are owned by the `api-service-contracts` skill. Do NOT list HTTP endpoints, controller routes, or actuator paths. +- **Business workflows and validation rules** are owned by the `business-workflows` skill. Do NOT describe business processes or entity validation constraints. +- **Entity/domain model listings** are owned by `data-architecture` and `business-workflows`. Do NOT enumerate entity names, fields, or relationships. + +## Execution Steps + +### Step 1: Generate Configuration Sources Section + +Identify all configuration files and sources and produce the complete `## Configuration Sources` section: + +- Java (Spring): `application.properties`, `application.yml`, `bootstrap.properties`, `bootstrap.yml` — note that `bootstrap.*` files are distinct from `application.*` (bootstrap configures the config server connection and runs before application context; application configures the app itself) +- .NET: `appsettings.json`, `appsettings.{Environment}.json`, `web.config`, `launchSettings.json` +- JavaScript/TypeScript: `.env`, `.env.local`, `.env.production`, `config/*.js`, `config/*.ts` +- Shared: `docker-compose.yml` environment sections, Kubernetes ConfigMaps/Secrets YAML files +- Config server references: Spring Cloud Config (note the external Git repository URI), Azure App Configuration, AWS AppConfig, Consul KV +- Secret stores: HashiCorp Vault, Azure KeyVault, AWS Secrets Manager references +- External configuration repositories: document the URI/path of any external config repos (e.g., `spring.cloud.config.server.git.uri`) + +### Step 2: Generate Build Profiles Section + +Identify build-time profiles that affect compilation, packaging, and dependency resolution, and produce the complete `## Build Profiles` section: + +- **Java/Maven**: profiles in `pom.xml` (e.g., `springboot`, `buildDocker`, `dev`, `cloud`) — for each, document activation condition (auto, manual `-P`, system property `-Denv=`), purpose, and key dependencies or plugins added +- **Java/Gradle**: build types and flavors in `build.gradle` +- **.NET**: build configurations (Debug, Release), conditional compilation symbols, MSBuild properties +- **JavaScript/TypeScript**: build scripts in `package.json`, webpack/vite/esbuild configurations per environment + +For each build profile extract: +- Profile name +- Activation condition (automatic, manual flag, system property, environment variable) +- Purpose (what it enables) +- Key dependencies or plugins added/removed + +### Step 3: Generate Runtime Profiles Section + +List all runtime profile-specific or environment-specific configuration and produce the complete `## Runtime Profiles` section: + +- Java (Spring): Profile-specific files (`application-dev.yml`, `application-prod.yml`), `@Profile` annotations, `spring.profiles.active` settings, combined profile activation (e.g., `mysql,key-vault`) +- .NET: Environment-specific files (`appsettings.Development.json`, `appsettings.Production.json`), `ASPNETCORE_ENVIRONMENT` usage +- JavaScript/TypeScript: `.env.development`, `.env.production`, NODE_ENV-based branching +- Identify profile activation conditions, defaults, and how profiles compose (multiple active profiles) + +### Step 4: Generate Properties Inventory Section + +For each service/module, catalog all configuration properties and produce the complete `## Properties Inventory` section: + +- Property keys with their default values +- Which profiles/environments override each property +- Data types and expected value ranges (where inferable) +- Properties sourced from environment variables (`${ENV_VAR}`, `%ENV_VAR%`) +- Placeholder references and property resolution chain + +> Do NOT include JVM startup parameters, `-Xms`/`-Xmx` heap settings, `-D` system properties, container memory/CPU limits, or instance counts here — those belong in the `## Startup Parameters & Resource Requirements` section (Step 5). + +### Step 5: Generate Startup Parameters & Resource Requirements Section + +Document JVM startup options, runtime parameters, and per-service resource allocations, and produce the complete `## Startup Parameters & Resource Requirements` section: + +- JVM heap settings (`-Xms`, `-Xmx`) per service +- System properties passed at startup (`-Dspring.profiles.active=`, `-Dazure.keyvault.uri=`, etc.) +- Docker/container environment variable overrides (`SPRING_PROFILES_ACTIVE`, `ASPNETCORE_ENVIRONMENT`) +- Memory allocation per service (Docker `mem_limit`, Kubernetes `resources.requests/limits`, cloud deployment settings) +- CPU allocation if specified +- Instance count and scaling configuration +- JVM heap settings mapped to service memory allocation (e.g., `-Xms2048m -Xmx2048m` for 2Gi services) + +### Step 6: Generate Startup Dependency Chain Section + +Map the service startup order and readiness dependencies and produce the complete `## Startup Dependency Chain` section: + +- Which services must start before others (e.g., config-server → discovery-server → business services → gateway) +- Health-check/wait mechanisms: `dockerize` wait-for-TCP, Kubernetes readiness probes, Spring Cloud Config retry, Docker Compose `depends_on` with health checks +- Startup timeout configurations +- Service readiness indicators (actuator health endpoints, custom health checks) + +### Step 7: Generate Secrets & Sensitive Configuration Section + +Flag sensitive configuration entries and document the secrets provisioning workflow, and produce the complete `## Secrets & Sensitive Configuration` section (including the `### Secrets Provisioning Workflow` subsection): + +- Database passwords, API keys, connection strings with credentials +- Secret references: KeyVault URIs, Vault paths, encrypted property values +- Entries marked as sensitive by framework conventions (e.g., `spring.datasource.password`) +- **Do NOT output actual secret values** — show the reference path or "[MASKED]" placeholder +- Note encryption methods if present (Jasypt, DPAPI, sealed secrets) + +Document how secrets flow through the system (`### Secrets Provisioning Workflow`): +- Secret source: environment variables, Key Vault, Vault, AWS Secrets Manager, sealed secrets +- Identity/access model: managed identities, service principals, RBAC permissions (e.g., "system-assigned managed identity with `get` and `list` permissions on Key Vault") +- Provisioning sequence: how secrets are set up during deployment (e.g., GitHub Actions retrieves service principal credentials → authenticates → creates MySQL secrets → binds to services) +- Which services need which secrets (e.g., data services need MySQL connection strings, all services need config server credentials) + +### Step 8: Generate Feature Flags Section + +Identify feature toggles and conditional configuration and produce the complete `## Feature Flags` section: + +- Feature flag frameworks: Spring Feature Flags, LaunchDarkly, Unleash, .NET FeatureManagement, custom toggles +- Conditional beans/services (`@ConditionalOnProperty`, `@ConditionalOnExpression`) +- A/B testing flags and gradual rollout configurations +- Default values and controlling sources (config file, environment variable, remote service) + +### Step 9: Generate Framework & Runtime Versions Section + +Catalog the technology stack versions that affect configuration and produce the complete `## Framework & Runtime Versions` section: + +- Core framework versions: Spring Boot, Spring Cloud, ASP.NET Core, Node.js, Express +- Target language/runtime version: Java 8/11/17/21, .NET 6/7/8, Node.js 18/20 +- Key library versions: Hibernate, EF Core, Resilience4j, Eureka, etc. +- Docker base images and their versions (e.g., `openjdk:11-jre`, `mcr.microsoft.com/dotnet/aspnet:8.0`) +- Build tool versions: Maven, Gradle, MSBuild, npm/yarn/pnpm + +### Step 10: Save Output + +Save to `.github/modernize/assessment/engines/configuration-inventory.md` with this exact structure: + +``` +# Configuration & Externalized Settings Inventory + +A brief introduction (1-2 sentences) summarizing the configuration landscape. + +## Configuration Sources + +[Table: Source | Type | Path/Location | Notes] + +## Build Profiles + +[Table: Profile | Activation | Purpose | Key Dependencies/Plugins] + +## Runtime Profiles + +[Table: Profile | Activation Method | Config Files | Key Overrides] + +## Properties Inventory + +[Per-service tables: Property Key | Default | Profiles | Source] + +## Startup Parameters & Resource Requirements + +[Table: Service | JVM/Runtime Options | Memory | Instance Count] + +## Startup Dependency Chain + +[Ordered list: Service → waits for → Service, with mechanism (dockerize, health check, etc.)] + +## Secrets & Sensitive Configuration + +[Table: Secret Reference | Type | Storage (masked)] + +### Secrets Provisioning Workflow + +[Description of how secrets flow: source → identity/access → binding → services] + +## Feature Flags + +[Table: Flag Name | Default | Controlled By] + +## Framework & Runtime Versions + +[Table: Component | Version | Source] +``` + +## Scaling Rules + +- If the project has **more than 100 properties**, group by category (database, messaging, security, etc.) and show representative examples with counts +- For multi-module projects, organize the properties inventory by module/service +- Collapse repetitive property patterns (e.g., 20 similar cache TTL settings) into a summary row with count + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No configuration files found**: Output: `> ERROR: No recognized configuration files found at {workspace-path}. Verify the path is correct.` +- **Insufficient info**: Generate a best-effort inventory from available data. Add a note: `> Note: Some configuration sources or properties could not be fully identified.` + +## Success Criteria + +- Configuration sources table lists all discovered config files, external config repos, and secret stores +- Build profiles are documented separately from runtime profiles with activation conditions and purposes +- Runtime profiles are documented with config files and key overrides +- Properties inventory covers all discovered properties with defaults and sources +- Startup parameters and resource requirements are documented per service +- Startup dependency chain shows service boot order with wait mechanisms +- Secrets are identified with references (no actual values exposed) and the provisioning workflow is described +- Feature flags are cataloged with defaults and controlling sources +- Framework and runtime versions are documented +- File saved to `.github/modernize/assessment/engines/configuration-inventory.md` diff --git a/.github/skills/create-dotnet-upgrade-plan/SKILL.md b/.github/skills/create-dotnet-upgrade-plan/SKILL.md new file mode 100644 index 000000000..bb6797d8e --- /dev/null +++ b/.github/skills/create-dotnet-upgrade-plan/SKILL.md @@ -0,0 +1,143 @@ +--- +name: create-dotnet-upgrade-plan +description: Creates a .NET upgrade plan (plan.md and tasks.json) for a repository. Analyzes the project to determine if a .NET version upgrade is needed and generates a structured upgrade task. Use when the user wants to create, generate, or prepare an upgrade/migration plan for a .NET project or solution. +--- + +# Create .NET Upgrade Plan + +Generate an upgrade plan (`plan.md` and `.metadata/tasks.json`) for a .NET project or solution. This skill **only creates the plan** — it does not execute the upgrade. The upgrade execution is handled by the `modernize-dotnet-upgrade-engineer` agent during plan execution. + +> **Supported**: .NET upgrades only. Other languages are not supported. + +--- + +## CRITICAL: HEADLESS EXECUTION MODE + +**This skill operates in fully autonomous headless mode. NO USER INTERACTION IS PERMITTED.** + +### Non-Negotiable Rules + +1. **NEVER stop, pause, or wait for user input** — not for confirmations, selections, reviews, or approvals +2. **NEVER ask "Would you like to proceed?"** — just proceed +3. **NEVER ask "Should I continue?"** — just continue +4. **ALWAYS complete the entire workflow** — from start to finish without interruption + +--- + +## Input Parameters + +| Parameter | Required | Description | +|-----------|----------|-------------| +| `upgrade-prompt` | Yes | The user's upgrade request (e.g., ".NET 10", "net10.0", "latest LTS") | +| `modernization-work-folder` | Yes | The folder to save the upgrade plan outputs | + +--- + +## Input Validation + +**Valid requests**: .NET version upgrades, LTS migrations, .NET Framework to modern .NET migrations + +**Invalid requests**: Feature additions, bug fixes, refactoring, containerization, deployment, non-.NET languages + +If invalid, output exactly and STOP: +``` +ERROR: The provided prompt is not a valid upgrade request. Please specify a target version (e.g., '.NET 10', 'net10.0'). +``` + +If unsupported language, output exactly and STOP: +``` +ERROR: Only .NET upgrades are supported. The requested language is not supported. +``` + +--- + +## Guidelines + +Refer to `dotnet-upgrade-guideline.md` for the rules on when to create an upgrade task, target version selection, and framework compatibility. + +Key rules from the guideline: +- Only add an upgrade task if: the project is EOL, has Azure SDK incompatibility, or the user explicitly requests it +- Always upgrade to the **latest LTS** version unless the user specifies a different target +- Current latest LTS: **.NET 10** (`net10.0`) +- Create a **single** upgrade task that encompasses all necessary changes + +--- + +## Workflow + +### Step 1: Analyze the Project + +Examine the project to determine: +1. **Current .NET version**: Read `.csproj` files to find `` or `` +2. **Project type**: Is it .NET Framework (requires SDK-style conversion), .NET Core, or modern .NET? +3. **Solution structure**: Is it a single project or a multi-project solution? List all projects. + +### Step 2: Determine Upgrade Need + +Apply the rules from `dotnet-upgrade-guideline.md`: +- If the project's .NET version is EOL → upgrade needed +- If the project targets .NET Framework < 4.6.2 (Azure SDK incompatibility) → upgrade needed +- If the user explicitly requests an upgrade → upgrade needed +- Otherwise → no upgrade needed, output: `ERROR: No upgrade is needed. The project is already on a supported .NET version.` + +### Step 3: Generate plan.md + +Create `plan.md` in `${modernization-work-folder}/` with: +- Source .NET version (detected from the project) +- Target .NET version (from user request or latest LTS) +- List of projects in the solution +- High-level description of what the upgrade entails (e.g., SDK-style conversion, TFM update, NuGet updates, API migration) + +### Step 4: Generate tasks.json + +Generate `tasks.json` in `${modernization-work-folder}/.metadata/` following `tasks-schema.json` and `upgrade-plan-template.md`. + +Create a **single** upgrade task: + +**Task Generation Rules:** + +| Rule | Requirement | +|------|-------------| +| Task type | Use `upgrade` type | +| Task count | Exactly **one** upgrade task | +| Description | Include source and target .NET versions, project names | +| Reason | Include a **non-empty** `reason` field explaining why the upgrade is needed (for example: current .NET version is outdated or unsupported, target version standardization, required compatibility/security/support improvements) | +| Requirements | High-level summary of the upgrade scope (source version, target version, general areas affected). Do not include implementation details — the upgrade agent determines the specific steps. | +| Skills | Empty array `[]` — the upgrade agent handles execution internally | +| successCriteria values | Must be **strings** (`"true"`, not `true`) | +| status | Set to `"pending"` | +| id format | Use pattern `001-upgrade-dotnet-to-{target}` (e.g., `001-upgrade-dotnet-to-net10`) | + +--- + +## Success Criteria + +All of the following must be true: + +- [ ] `plan.md` exists in `${modernization-work-folder}/` +- [ ] `tasks.json` exists in `${modernization-work-folder}/.metadata/` +- [ ] `plan.md` clearly states source and target .NET versions +- [ ] `tasks.json` follows schema with all required fields +- [ ] Exactly one upgrade task in tasks.json +- [ ] Workflow completed without user interaction + +--- + +## Error Handling + +| Problem | Solution | +|---------|----------| +| No .csproj found | Output `ERROR: No supported .NET project files (.csproj) found in the repository.` | +| Cannot determine current .NET version | Output `ERROR: Could not determine the current .NET version from project files.` | +| Project already on target version | Output `ERROR: The project is already on the target .NET version.` | + +--- + +## Anti-Patterns (NEVER DO THESE) + +| Don't | Do Instead | +|-------|------------| +| Stop to ask user for confirmation | Accept defaults and continue | +| Create multiple granular upgrade tasks | Create a single upgrade task | +| Wait for user review | Complete workflow, then show final results | +| Ask "Should I proceed?" | Just proceed | diff --git a/.github/skills/create-dotnet-upgrade-plan/dotnet-upgrade-guideline.md b/.github/skills/create-dotnet-upgrade-plan/dotnet-upgrade-guideline.md new file mode 100644 index 000000000..a5c97e03a --- /dev/null +++ b/.github/skills/create-dotnet-upgrade-plan/dotnet-upgrade-guideline.md @@ -0,0 +1,43 @@ +# .NET Upgrade Task Guidelines + +Only add a .NET upgrade task if one of the following conditions is met: + +1. **End of Life (EOL)**: The project's .NET version is out of mainstream support. +2. **Azure SDK Compatibility**: The project targets a .NET Framework version older than 4.6.2, which does not support `netstandard2.0` and cannot use modern Azure SDK (`Azure.*`) packages. +3. **User Request**: The user explicitly requests a .NET version upgrade. + +The upgrade task must be the first task if it exists. + +### Target Version + +Always upgrade to the **latest LTS** version unless the user explicitly specifies a different target version. + +- Current latest LTS: **.NET 10** (`net10.0`) + +### Azure SDK Minimum .NET Version + +The modern Azure SDK for .NET (`Azure.*` packages) targets `netstandard2.0` as its baseline. The following .NET Framework versions do **not** support `netstandard2.0` and require an upgrade: + +| .NET Framework Version | `netstandard2.0` Support | Action | +|------------------------|:------------------------:|--------| +| 4.5 and below | ❌ | Upgrade required | +| 4.6 | ❌ | Upgrade required | +| 4.6.1 | ⚠️ Unreliable | Upgrade recommended | +| 4.6.2+ | ✅ | No upgrade needed for Azure SDK compatibility | + +> **Note**: .NET Framework 4.6.1 is technically listed as supporting `netstandard2.0` but has known issues. Microsoft recommends 4.7.2+ for reliable support. The Azure SDK explicitly targets `net462` as its minimum. + +## Framework Compatibility + +| Source Framework | Target Framework | SDK-Style Conversion Required | +|-----------------|:----------------:|:----------------------------:| +| .NET Framework 4.x | net10.0 | Yes | +| .NET Core 3.1 | net10.0 | No | +| .NET 5–9 | net10.0 | No | + +## .NET Task Selection Rules + +- **Rule 1 — Single task only**: Always create a **single** upgrade task that encompasses all necessary changes. The `modernize-dotnet-upgrade-engineer` agent handles the detailed breakdown during execution. +- **Rule 2 — EOL or Azure SDK incompatibility**: Create task "Upgrade .NET to latest LTS (net10.0)". Set the task `skills` array to `[]` (empty) — the upgrade agent handles execution internally. +- **Rule 3 — User-specified version**: Create task "Upgrade .NET to version X". Set the task `skills` array to `[]` (empty) — the upgrade agent handles execution internally. +- **Rule 4 — No upgrade needed**: If the project's .NET version is in support **and** the project targets .NET Framework 4.6.2+ (or any .NET Core / modern .NET) **and** the user did not request an upgrade, do **not** add an upgrade task. \ No newline at end of file diff --git a/.github/skills/create-dotnet-upgrade-plan/tasks-schema.json b/.github/skills/create-dotnet-upgrade-plan/tasks-schema.json new file mode 100644 index 000000000..397678e03 --- /dev/null +++ b/.github/skills/create-dotnet-upgrade-plan/tasks-schema.json @@ -0,0 +1,349 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Modernization Tasks Template", + "description": "Schema for tasks-template.json. Preserve field descriptions because they are used to generate the JSON by LLM.", + "type": "object", + "required": ["$schema", "description", "tasks", "metadata"], + "additionalProperties": false, + "properties": { + "$schema": { + "type": "string", + "description": "JSON Schema reference used by the template." + }, + "description": { + "type": "string", + "description": "Tasks template for modernization plan. Generate this file alongside plan.md to track individual migration tasks." + }, + "tasks": { + "type": "array", + "description": "List of individual migration tasks.", + "items": { + "oneOf": [ + { "$ref": "#/$defs/transformTask" }, + { "$ref": "#/$defs/upgradeTask" }, + { "$ref": "#/$defs/integrationTestTask" }, + { "$ref": "#/$defs/containerizationTask" }, + { "$ref": "#/$defs/deploymentTask" }, + { "$ref": "#/$defs/securityTask" }, + { "$ref": "#/$defs/infrastructureTask" } + ] + } + }, + "metadata": { + "type": "object", + "description": "Metadata for the plan.", + "additionalProperties": false, + "required": ["planName", "projectName", "language", "createdAt", "version"], + "properties": { + "planName": { + "type": "string", + "description": "[Plan name]" + }, + "projectName": { + "type": "string", + "description": "[Application Name]" + }, + "language": { + "type": "string", + "description": "[Programming language]" + }, + "createdAt": { + "type": "string", + "description": "[ISO 8601 timestamp]", + "format": "date-time" + }, + "version": { + "type": "string", + "description": "Version of the template schema.", + "const": "1.0" + } + } + } + }, + "$defs": { + "taskBase": { + "type": "object", + "additionalProperties": false, + "required": ["type", "id", "description", "requirements"], + "properties": { + "type": { + "type": "string", + "description": "Task type identifier." + }, + "id": { + "type": "string", + "description": "[Unique identifier for this task, start with sequence and category name, like '001-transform-migration-rabbitmq-to-servicebus']" + }, + "description": { + "type": "string", + "description": "[Brief description of what this task achieves from the user's perspective. It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" + }, + "reason": { + "type": "string", + "description": "[Explain why this task is needed, e.g., the motivation, business justification, or technical necessity that drives this task]" + }, + "requirements": { + "type": "string", + "description": "[The specific requirements for this task including: what to migrate (features, APIs, patterns), constraints (backward compatibility, modules to avoid), target Azure services, and technical preferences (authentication methods, patterns). It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" + }, + "environmentConfiguration": { + "type": ["string"], + "description": "[Environment configuration from user input (e.g. endpoint, access id). Omit this field if not specified]" + }, + "status": { + "type": ["string"], + "description": "Task execution status. Only has value after task is executed.", + "enum": ["pending", "started", "success", "failed", "skipped"] + }, + "taskSummary": { + "type": "string", + "description": "Summary of task execution result. Only has value after task is executed." + }, + "dependencies": { + "type": "array", + "description": "[List of task IDs that this task depends on. The task will only be executed after all its dependencies have completed successfully.]", + "items": { + "type": "string" + } + } + } + }, + "skill": { + "type": "object", + "additionalProperties": false, + "required": ["name", "location"], + "properties": { + "name": { + "type": "string", + "description": "[The skill name that will be used for this task, e.g., 'migration-rabbitmq-to-servicebus'.]" + }, + "location": { + "type": "string", + "description": "Skill location: project, remote and builtin, builtin is renamed from custom", + "enum": ["project","remote","builtin"] + } + } + }, + "successCriteria": { + "type": "object", + "additionalProperties": false, + "required": [ + "passBuild", + "generateNewUnitTests", + "passUnitTests" + ], + "description": "The task success criteria to validate after task execution.", + "properties": { + "passBuild": { + "type": ["string"], + "default": "true", + "description": "Project must compile successfully after migration, use default value if user does not specify" + }, + "generateNewUnitTests": { + "type": ["string"], + "default": "false", + "description": "Create mock-based unit tests for newly added Azure integration code to ensure test coverage, use default value if user does not specify" + }, + "passUnitTests": { + "type": ["string"], + "default": "true", + "description": "All unit tests must pass; mock dependent Azure resources if not provided, use default value if user does not specify" + } + } + }, + "successCriteriaStatus": { + "type": "object", + "not": { + "type": "null" + }, + "additionalProperties": false, + "description": "Optional validation status for each success criterion. Omit this field until validation is complete. If present, use true/false string values.", + "properties": { + "passBuild": { + "type": ["string"], + "description": "Validation status of passBuild criterion. true means passed, false means failed." + }, + "generateNewUnitTests": { + "type": ["string"], + "description": "Validation status of generateNewUnitTests criterion. true means passed, false means failed." + }, + "passUnitTests": { + "type": ["string"], + "description": "Validation status of passUnitTests criterion. true means passed, false means failed." + } + } + }, + "transformTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "successCriteria"], + "properties": { + "type": { + "const": "transform", + "description": "transform task template" + }, + "skills": { + "type": "array", + "description": "The skills that will be used for this task, it is started with migration and looks like 'migration-rabbitmq-to-servicebus-mi'", + "items": { "$ref": "#/$defs/skill" } + }, + "successCriteria": { "$ref": "#/$defs/successCriteria" }, + "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } + } + } + ] + }, + "upgradeTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "successCriteria"], + "properties": { + "type": { + "const": "upgrade", + "description": "Upgrade task template" + }, + "successCriteria": { "$ref": "#/$defs/successCriteria" }, + "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } + } + } + ] + }, + "containerizationTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "dockerfilePath"], + "properties": { + "type": { + "const": "containerization", + "description": "Containerization task template - Only include if the target deployment requires containerization (e.g., AKS, ACA) or if the user explicitly requested containerization. Skip for non-containerized deployments." + }, + "dockerfilePath": { + "type": "string", + "description": "[Path to Dockerfile, indicate if existing or to be created]" + } + } + } + ] + }, + "deploymentTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "targetAzureService", "resourceStatus", "deploymentTool", "skills"], + "properties": { + "type": { + "const": "deployment", + "description": "Deployment task template - Containerize, provision and deploy the application to Azure. Only include if the user explicitly requested deployment." + }, + "skills": { + "type": "array", + "description": "The deployment skill to use based on targetAzureService: 'azcli-aks-deploy' for Azure Kubernetes Service, 'azcli-containerapp-deploy' for Azure Container Apps, 'azcli-appservice-deploy' for Azure App Service, 'azcli-functionapp-deploy' for Azure Function App, 'azcli-appservicemi-deploy' for Azure App Service with Managed Identity", + "items": { "$ref": "#/$defs/skill" } + }, + "targetAzureService": { + "type": "string", + "description": "[Azure service name, e.g., Azure Container Apps, AKS, App Service]" + }, + "resourceStatus": { + "type": "string", + "description": "[Specify if using existing resource or will create new service]" + }, + "deploymentTool": { + "type": "string", + "description": "Infrastructure as Code tool type. Default to 'terraform' for aks, 'bicep' for other services if not specified.", + "enum": ["bicep", "terraform"] + } + } + } + ] + }, + "integrationTestTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "layers"], + "properties": { + "type": { + "const": "integrationTest", + "description": "Integration test task template - Generate and run integration tests for migrated Azure services. Only include when user explicitly requests integration testing. This task runs after all transform/upgrade tasks but before containerization." + }, + "layers": { + "type": "array", + "description": "[Array of test layers to execute, e.g., [1, 2] for Layer 1 (Local Integration with TestContainers) and Layer 2 (Smoke Tests)]", + "items": { + "type": "number", + "enum": [1, 2] + }, + "minItems": 1 + } + } + } + ] + }, + "securityTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "successCriteria"], + "properties": { + "type": { + "const": "security", + "description": "Security task template - Include when security remediation, vulnerability scanning, or compliance checks are required." + }, + "cveReport": { + "type": ["string"], + "description": "Path to final-cve-report.json. Only has value after CVE checking is complete." + }, + "successCriteria": { "$ref": "#/$defs/successCriteria" }, + "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } + } + } + ] + }, + "infrastructureTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "skills", "iacType", "provision"], + "properties": { + "type": { + "const": "infrastructure", + "description": "Infrastructure task template - Generate IaC files (Bicep or Terraform) to provision Azure resources." + }, + "iacType": { + "type": "string", + "description": "Infrastructure as Code tool type.", + "enum": ["bicep", "terraform"] + }, + "provision": { + "type": "boolean", + "description": "Whether to provision Azure resources after generating IaC files." + }, + "skills": { + "type": "array", + "description": "The skill used for this task, e.g., 'infrastructure-bicep-generation' or 'infrastructure-terraform-generation'", + "items": { "$ref": "#/$defs/skill" } + } + } + } + ] + } + } +} diff --git a/.github/skills/create-dotnet-upgrade-plan/upgrade-plan-template.md b/.github/skills/create-dotnet-upgrade-plan/upgrade-plan-template.md new file mode 100644 index 000000000..b534fece6 --- /dev/null +++ b/.github/skills/create-dotnet-upgrade-plan/upgrade-plan-template.md @@ -0,0 +1,42 @@ +# .NET Upgrade Plan Template + +## Schema Rules + +- Use `upgradeTask` type from `tasks-schema.json` +- `successCriteria` values: **strings** (`"true"`, `"false"`) +- `skills.location`: `"builtin"` | `"project"` | `"remote"` +- `status`: `"pending"` + +## Example: tasks.json + +```json +{ + "$schema": "tasks-schema.json", + "description": ".NET version upgrade plan from .NET Framework 4.6.1 to .NET 10.0", + "tasks": [ + { + "type": "upgrade", + "id": "001-upgrade-dotnet-to-net10", + "description": "Upgrade ContosoUniversity from .NET Framework 4.6.1 to .NET 10.0", + "reason": ".NET Framework 4.6.1 reached end of support on April 26, 2022 and does not meet the minimum .NET Framework 4.6.2 requirement for Azure SDK (.NET Standard 2.0) compatibility. Upgrading to .NET 10.0 LTS ensures long-term support, access to modern APIs, and full Azure SDK compatibility.", + "requirements": "Upgrade the project from .NET Framework 4.6.1 to .NET 10.0, including project file modernization, dependency updates, and API compatibility fixes.", + "environmentConfiguration": null, + "skills": [], + "successCriteria": { + "passBuild": "true", + "generateNewUnitTests": "false", + "passUnitTests": "true", + "securityComplianceCheck": "true" + }, + "status": "pending" + } + ], + "metadata": { + "planName": "upgrade-to-lts", + "projectName": "ContosoUniversity", + "language": "dotnet", + "createdAt": "2026-02-13T00:00:00.000Z", + "version": "1.0" + } +} +``` diff --git a/.github/skills/create-java-upgrade-plan/SKILL.md b/.github/skills/create-java-upgrade-plan/SKILL.md new file mode 100644 index 000000000..fe4b54afb --- /dev/null +++ b/.github/skills/create-java-upgrade-plan/SKILL.md @@ -0,0 +1,58 @@ +--- +name: create-java-upgrade-plan +description: Create an upgrade plan to migrate a Java project to latest LTS versions +--- + +# Create Upgrade Plan + +Creates `tasks.json` (in `.metadata/` subdirectory) and `plan.md` for upgrading Java projects to target versions. + +> **Supported**: Java upgrades only. .NET and other languages are not supported. + +## ⚠️ CRITICAL: Do NOT Read Files + +**Do NOT read any workspace files** (pom.xml, build.gradle, source code, etc.). + +This plan may apply to multiple repositories not yet cloned. Generate a **generic plan** based solely on the user's prompt—never detect or mention "current versions." + +## User Input + +upgrade-prompt (Mandatory): The user's upgrade request (e.g., "Java 17", "Spring Boot 3.2", or "Upgrade to the latest LTS versions") +modernization-work-folder (Mandatory): The folder to save the upgrade plan + +## Validation + +**Valid requests**: Java/framework version upgrades, LTS migrations, dependency bumps +**Invalid requests**: Feature additions, bug fixes, refactoring, containerization, deployment, non-Java languages (.NET, Python, etc.) + +If invalid, output exactly: +``` +ERROR: The provided prompt is not a valid upgrade request. Please specify a target version (e.g., 'Java 17', 'Spring Boot 3.2'). +``` + +If unsupported language, output exactly: +``` +ERROR: Only Java upgrades are supported. The requested language is not supported. +``` +Then STOP—do not create files or ask for clarification. + +## Workflow + +1. **Parse request** → Extract target versions (defaults: Java 25, Spring Boot 4.x) +2. **Generate tasks.json** → Follow `tasks-schema.json` and `upgrade-plan-template.md`, and save it to `.metadata/tasks.json` +3. **Generate plan.md** → Brief overview of the upgrade plan + +## Task Rules + +- **Java Upgrade Task Guidelines**: You must refer to the ./java-upgrade-guideline.md for specific rules and guidelines when creating Java upgrade tasks. +- Create **only** `upgrade` type tasks +- Specify **target versions only**—never "from version X" +- Use `builtin` skills (e.g., `java-version-upgrade`) +- `successCriteria` values must be **strings** (`"true"`, not `true`) +- Set `status` to `"pending"` + +## Output + +Save to `${modernization-work-folder}/`: +- `.metadata/tasks.json` — Upgrade tasks per schema +- `plan.md` — Plan overview diff --git a/.github/skills/create-java-upgrade-plan/java-upgrade-guideline.md b/.github/skills/create-java-upgrade-plan/java-upgrade-guideline.md new file mode 100644 index 000000000..270412a96 --- /dev/null +++ b/.github/skills/create-java-upgrade-plan/java-upgrade-guideline.md @@ -0,0 +1,44 @@ +# Java Upgrade Task Guidelines + +Only add an upgrade task if the user explicitly requests it. The upgrade task must be the first task if it exists. + +## Latest Stable Versions + +- Java: 25 +- Spring Boot: 4.x +- Spring Framework: 7.x + +## Supported Upgrade Versions + +- Java: 11, 17, 21, 25 +- Spring Boot: 3.x, 4.x +- Spring Framework: 6.x, 7.x + +## Framework Compatibility + +| Spring Boot | Spring Framework | Jakarta EE | Minimum Java | Maximum Java | +|-------------|:----------------:|:----------:|:------------:|:------------:| +| 2.x | 5.x | JavaEE (javax.*) | 8 | 11 | +| 3.x | 6.x | Jakarta EE (jakarta.*) | 17 | 21 | +| 4.x | 7.x | Jakarta EE (jakarta.*) | 25 | 25 | + +## Upgrade Task Types and Included Changes + +| Task Type | Spring Framework Upgrade | Jakarta EE Migration (javax.* → jakarta.*) | JDK/Java | +|-----------|:------------------------:|:------------------------------------------:|:-----------:| +| Spring Boot 4.x upgrade | 7.x | ✓ | 25 | +| Spring Boot 3.x upgrade | 6.x | ✓ | 21 | +| Spring Framework 7.x upgrade | — | ✓ | 25 | +| Spring Framework 6.x upgrade | — | ✓ | 21 | +| Jakarta EE upgrade | — | ✓ | 21 | +| JDK/Java upgrade | — | — | to specified version | + +## Java Task Selection Rules + +When selecting the Java upgrade task type, follow these rules in order: + +- **Rule 1 — No redundant sub-tasks**: Each upgrade type (Spring Boot, Spring Framework, Jakarta EE, JDK/Java) is hierarchical — higher-level tasks already include lower-level ones. Never create a lower-level task that is already covered by a selected higher-level task. For example, if a Spring Boot 4.x upgrade task is selected (which already includes JDK 25), do NOT also create a separate JDK/Java upgrade task. +- **Rule 2 — User-specified framework request doesn't fully match system state**: When the user requests a **framework** upgrade (e.g., Spring Boot, Spring Framework) but the target version they specify is not the latest available, select the highest-level task applicable and prompt the user to clarify. For example, if the user asks to "upgrade Spring Boot to 3.x" but Spring Boot 4.x is available, create a Spring Boot 3.x upgrade task and add a clarification question asking whether they want 4.x. **This rule does NOT apply to pure JDK/Java upgrade requests — see Rule 4.** +- **Rule 3 — User-specified request matches system state**: Select the most closely matching task type that directly matches the user's request and fits the system. For example, if the user asks to "upgrade JDK" and the JDK is outdated, create a JDK/Java upgrade task — NOT a higher-level Spring Boot or Spring Framework upgrade task. +- **Rule 4 — Never upgrade other frameworks on a JDK/Java request**: When the user explicitly requests a JDK/Java upgrade, you MUST NOT upgrade Spring Boot, Spring Framework, or Jakarta EE — create only a JDK/Java upgrade task targeting the user-specified version. If the project's existing Spring Boot, Spring Framework, or Jakarta EE versions are incompatible with the target Java version (per the Framework Compatibility table above), add a clarification question asking the user whether they also want to upgrade the incompatible framework(s) to a compatible version. +- **Rule 5 — Ask for clarification when the selected task diverges from the user's request**: Whenever the task you create differs from what the user explicitly asked for (e.g., upgrading to a different version, choosing a higher-level task type, or skipping a requested change due to compatibility), you MUST use the `ask_user` tool to explain what was selected, why it differs, and ask the user to confirm or adjust. If `ask_user` is not available, add the question to the "## Open Questions" section of `plan.md`. Never silently override the user's intent. \ No newline at end of file diff --git a/.github/skills/create-java-upgrade-plan/tasks-schema.json b/.github/skills/create-java-upgrade-plan/tasks-schema.json new file mode 100644 index 000000000..397678e03 --- /dev/null +++ b/.github/skills/create-java-upgrade-plan/tasks-schema.json @@ -0,0 +1,349 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Modernization Tasks Template", + "description": "Schema for tasks-template.json. Preserve field descriptions because they are used to generate the JSON by LLM.", + "type": "object", + "required": ["$schema", "description", "tasks", "metadata"], + "additionalProperties": false, + "properties": { + "$schema": { + "type": "string", + "description": "JSON Schema reference used by the template." + }, + "description": { + "type": "string", + "description": "Tasks template for modernization plan. Generate this file alongside plan.md to track individual migration tasks." + }, + "tasks": { + "type": "array", + "description": "List of individual migration tasks.", + "items": { + "oneOf": [ + { "$ref": "#/$defs/transformTask" }, + { "$ref": "#/$defs/upgradeTask" }, + { "$ref": "#/$defs/integrationTestTask" }, + { "$ref": "#/$defs/containerizationTask" }, + { "$ref": "#/$defs/deploymentTask" }, + { "$ref": "#/$defs/securityTask" }, + { "$ref": "#/$defs/infrastructureTask" } + ] + } + }, + "metadata": { + "type": "object", + "description": "Metadata for the plan.", + "additionalProperties": false, + "required": ["planName", "projectName", "language", "createdAt", "version"], + "properties": { + "planName": { + "type": "string", + "description": "[Plan name]" + }, + "projectName": { + "type": "string", + "description": "[Application Name]" + }, + "language": { + "type": "string", + "description": "[Programming language]" + }, + "createdAt": { + "type": "string", + "description": "[ISO 8601 timestamp]", + "format": "date-time" + }, + "version": { + "type": "string", + "description": "Version of the template schema.", + "const": "1.0" + } + } + } + }, + "$defs": { + "taskBase": { + "type": "object", + "additionalProperties": false, + "required": ["type", "id", "description", "requirements"], + "properties": { + "type": { + "type": "string", + "description": "Task type identifier." + }, + "id": { + "type": "string", + "description": "[Unique identifier for this task, start with sequence and category name, like '001-transform-migration-rabbitmq-to-servicebus']" + }, + "description": { + "type": "string", + "description": "[Brief description of what this task achieves from the user's perspective. It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" + }, + "reason": { + "type": "string", + "description": "[Explain why this task is needed, e.g., the motivation, business justification, or technical necessity that drives this task]" + }, + "requirements": { + "type": "string", + "description": "[The specific requirements for this task including: what to migrate (features, APIs, patterns), constraints (backward compatibility, modules to avoid), target Azure services, and technical preferences (authentication methods, patterns). It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" + }, + "environmentConfiguration": { + "type": ["string"], + "description": "[Environment configuration from user input (e.g. endpoint, access id). Omit this field if not specified]" + }, + "status": { + "type": ["string"], + "description": "Task execution status. Only has value after task is executed.", + "enum": ["pending", "started", "success", "failed", "skipped"] + }, + "taskSummary": { + "type": "string", + "description": "Summary of task execution result. Only has value after task is executed." + }, + "dependencies": { + "type": "array", + "description": "[List of task IDs that this task depends on. The task will only be executed after all its dependencies have completed successfully.]", + "items": { + "type": "string" + } + } + } + }, + "skill": { + "type": "object", + "additionalProperties": false, + "required": ["name", "location"], + "properties": { + "name": { + "type": "string", + "description": "[The skill name that will be used for this task, e.g., 'migration-rabbitmq-to-servicebus'.]" + }, + "location": { + "type": "string", + "description": "Skill location: project, remote and builtin, builtin is renamed from custom", + "enum": ["project","remote","builtin"] + } + } + }, + "successCriteria": { + "type": "object", + "additionalProperties": false, + "required": [ + "passBuild", + "generateNewUnitTests", + "passUnitTests" + ], + "description": "The task success criteria to validate after task execution.", + "properties": { + "passBuild": { + "type": ["string"], + "default": "true", + "description": "Project must compile successfully after migration, use default value if user does not specify" + }, + "generateNewUnitTests": { + "type": ["string"], + "default": "false", + "description": "Create mock-based unit tests for newly added Azure integration code to ensure test coverage, use default value if user does not specify" + }, + "passUnitTests": { + "type": ["string"], + "default": "true", + "description": "All unit tests must pass; mock dependent Azure resources if not provided, use default value if user does not specify" + } + } + }, + "successCriteriaStatus": { + "type": "object", + "not": { + "type": "null" + }, + "additionalProperties": false, + "description": "Optional validation status for each success criterion. Omit this field until validation is complete. If present, use true/false string values.", + "properties": { + "passBuild": { + "type": ["string"], + "description": "Validation status of passBuild criterion. true means passed, false means failed." + }, + "generateNewUnitTests": { + "type": ["string"], + "description": "Validation status of generateNewUnitTests criterion. true means passed, false means failed." + }, + "passUnitTests": { + "type": ["string"], + "description": "Validation status of passUnitTests criterion. true means passed, false means failed." + } + } + }, + "transformTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "successCriteria"], + "properties": { + "type": { + "const": "transform", + "description": "transform task template" + }, + "skills": { + "type": "array", + "description": "The skills that will be used for this task, it is started with migration and looks like 'migration-rabbitmq-to-servicebus-mi'", + "items": { "$ref": "#/$defs/skill" } + }, + "successCriteria": { "$ref": "#/$defs/successCriteria" }, + "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } + } + } + ] + }, + "upgradeTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "successCriteria"], + "properties": { + "type": { + "const": "upgrade", + "description": "Upgrade task template" + }, + "successCriteria": { "$ref": "#/$defs/successCriteria" }, + "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } + } + } + ] + }, + "containerizationTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "dockerfilePath"], + "properties": { + "type": { + "const": "containerization", + "description": "Containerization task template - Only include if the target deployment requires containerization (e.g., AKS, ACA) or if the user explicitly requested containerization. Skip for non-containerized deployments." + }, + "dockerfilePath": { + "type": "string", + "description": "[Path to Dockerfile, indicate if existing or to be created]" + } + } + } + ] + }, + "deploymentTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "targetAzureService", "resourceStatus", "deploymentTool", "skills"], + "properties": { + "type": { + "const": "deployment", + "description": "Deployment task template - Containerize, provision and deploy the application to Azure. Only include if the user explicitly requested deployment." + }, + "skills": { + "type": "array", + "description": "The deployment skill to use based on targetAzureService: 'azcli-aks-deploy' for Azure Kubernetes Service, 'azcli-containerapp-deploy' for Azure Container Apps, 'azcli-appservice-deploy' for Azure App Service, 'azcli-functionapp-deploy' for Azure Function App, 'azcli-appservicemi-deploy' for Azure App Service with Managed Identity", + "items": { "$ref": "#/$defs/skill" } + }, + "targetAzureService": { + "type": "string", + "description": "[Azure service name, e.g., Azure Container Apps, AKS, App Service]" + }, + "resourceStatus": { + "type": "string", + "description": "[Specify if using existing resource or will create new service]" + }, + "deploymentTool": { + "type": "string", + "description": "Infrastructure as Code tool type. Default to 'terraform' for aks, 'bicep' for other services if not specified.", + "enum": ["bicep", "terraform"] + } + } + } + ] + }, + "integrationTestTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "layers"], + "properties": { + "type": { + "const": "integrationTest", + "description": "Integration test task template - Generate and run integration tests for migrated Azure services. Only include when user explicitly requests integration testing. This task runs after all transform/upgrade tasks but before containerization." + }, + "layers": { + "type": "array", + "description": "[Array of test layers to execute, e.g., [1, 2] for Layer 1 (Local Integration with TestContainers) and Layer 2 (Smoke Tests)]", + "items": { + "type": "number", + "enum": [1, 2] + }, + "minItems": 1 + } + } + } + ] + }, + "securityTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "successCriteria"], + "properties": { + "type": { + "const": "security", + "description": "Security task template - Include when security remediation, vulnerability scanning, or compliance checks are required." + }, + "cveReport": { + "type": ["string"], + "description": "Path to final-cve-report.json. Only has value after CVE checking is complete." + }, + "successCriteria": { "$ref": "#/$defs/successCriteria" }, + "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } + } + } + ] + }, + "infrastructureTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "skills", "iacType", "provision"], + "properties": { + "type": { + "const": "infrastructure", + "description": "Infrastructure task template - Generate IaC files (Bicep or Terraform) to provision Azure resources." + }, + "iacType": { + "type": "string", + "description": "Infrastructure as Code tool type.", + "enum": ["bicep", "terraform"] + }, + "provision": { + "type": "boolean", + "description": "Whether to provision Azure resources after generating IaC files." + }, + "skills": { + "type": "array", + "description": "The skill used for this task, e.g., 'infrastructure-bicep-generation' or 'infrastructure-terraform-generation'", + "items": { "$ref": "#/$defs/skill" } + } + } + } + ] + } + } +} diff --git a/.github/skills/create-java-upgrade-plan/upgrade-plan-template.md b/.github/skills/create-java-upgrade-plan/upgrade-plan-template.md new file mode 100644 index 000000000..144ae61e4 --- /dev/null +++ b/.github/skills/create-java-upgrade-plan/upgrade-plan-template.md @@ -0,0 +1,51 @@ +# Upgrade Plan Template + +> **Important**: Specify only TARGET versions—never "current" or "from" versions. Do NOT read project files. + +## Schema Rules + +- Use `upgradeTask` type from `tasks-schema.json` +- `successCriteria` values: **strings** (`"true"`, `"false"`) +- `skills.location`: `"builtin"` | `"project"` | `"remote"` +- `status`: `"pending"` + +## Example: tasks.json +{ + "description": "Upgrade plan to migrate project to latest LTS versions", + "tasks": [ + { + "type": "upgrade", + "id": "001-upgrade-java-spring-boot", + "description": "Upgrade to Java 25 and Spring Boot 4.x", + "requirements": "Upgrade JDK to 25, Spring Boot to 4.x, Spring Framework to 7.x, and migrate javax.* to jakarta.* if needed", + "environmentConfiguration": null, + "skills": [{ "name": "java-version-upgrade", "location": "builtin" }], + "successCriteria": { + "passBuild": "true", + "generateNewUnitTests": "false", + "passUnitTests": "true" + }, + "status": "pending" + } + ], + "metadata": { + "planName": "upgrade-to-lts", + "projectName": "application", + "language": "java", + "createdAt": "2026-02-06T00:00:00.000Z", + "version": "1.0" + } +} +``` + +## Example: plan.md + +```markdown +# Upgrade Plan + +## Overview +Upgrade to latest LTS versions. + +## Tasks +See the .metadata/tasks.json for detailed task breakdown. +``` diff --git a/.github/skills/create-modernization-plan/SKILL.md b/.github/skills/create-modernization-plan/SKILL.md new file mode 100644 index 000000000..fbc539737 --- /dev/null +++ b/.github/skills/create-modernization-plan/SKILL.md @@ -0,0 +1,129 @@ +--- +name: create-modernization-plan +description: Create a modernization plan to migrate the project to Azure +--- + +# Create modernization plan + +This skill is used to create a modernization plan to migrate the a given project to Azure + +## User Input + +modernization-prompt: The user input to generate the modernization plan +modernization-work-folder (Mandatory): The folder to save the modernization plan +github-issue-link (Optional): A github issue to track the modernization status, to be filled into plan template +assessment-report (Optional): A assessment report for the project will be modernized, it will provide the data about the project for modernization +plan-name (Optional): The plan name to be filled into plan template +language (Mandatory): The programming language of the project (java or dotnet) + +## Supported Task Patterns + +Read the supported patterns file based on the language: +- For .NET projects: Read `supported-patterns-dotnet.md` +- For all other projects: Read `supported-patterns-java.md`. Default option. + +These files contain the list of supported task patterns with and without skill definitions. If a skill is available, the skill location should be set to `builtin`. + +## Workflow + +Given the user input, do this: + +1. Double Check the issues + **IMPORTANT**: + - If you are given an assessment-report, you need to double check if the issue really exist in current project. If not, please ignore this issue when you generate the plan + +2. **Load context**: Retrieve information for plan, you can read + 1) Analysis the supported patterns to find the right tasks for the issues + 2) Analysis modernization requirement from user input + +3. **Clarification and Questionnaire** (only when the `ask_user` tool is available): If there are any open issues or ambiguities that need user input, use the following steps to answer any questions. Also ask the questions outlined in `questionnaire.md` via `ask_user` tool to scope the modernization plan. For questionnaire questions, if the user input already provides the answer, skip asking that question and use the provided information as the answer. + 1) Use the `ask_user` tool to ask the user each clarification question directly. Wait for the user's response before proceeding. + 2) Record each question and answer for use in the summary step. + 3) If the `ask_user` tool is not available, skip this step entirely and proceed to plan generation using best-effort defaults. + +4. **Summary & Confirmation** (only when the `ask_user` tool is available): + 1) Present a summary to the user via `ask_user` that includes: + - All clarification questions and the user's answers (if any were asked in step 3) + - The planned task list with key details for each task: task name, type, matched skill/pattern, and a brief description of what it will do + 2) Ask the user to confirm the summary is correct, or provide additional input to adjust any answers or task list. + 3) If the user provides additional input, incorporate the changes. If the user chooses to skip or confirms, proceed to plan generation. + 4) If the `ask_user` tool is not available, skip this step entirely. + +5. **Generate plan and tasks**: Generate plan.md and tasks.json using the appropriate templates: + + **Template Selection**: + - Use **plan-template.md** for code migration, containerization, and deployment tasks + - Use **security-plan-template.md** to include a security/CVE remediation task in every modernization plan. + - Use **infra-plan-template.md** ONLY when user explicitly requests infrastructure (e.g., "prepare infrastructure", "create landing zone", "provision resources", "generate Bicep/Terraform") + + **Plan Generation**: + 1) Follow the structure of the selected template to generate the plan + 2) Follow the rules defined in the template to fill in the sections with relevant information based on the analysis of user input and content of mentioned files + 3) Save the plan in folder ${modernization-work-folder} with the filename plan.md. If a plan already exists, overwrite it. + 4) Generate a separate tasks.json file following the tasks-schema.json schema with all upgrade, transform, security, integration test, infrastructure, containerization, and deployment tasks + 5) Save the tasks in folder ${modernization-work-folder}/.metadata/ with the filename tasks.json. If tasks.json already exists, overwrite it. + + **Clarification Outcomes in Plan**: Incorporate all clarification answers from steps 3–4 into `plan.md` and `tasks.json`: + - Update the relevant task's `requirements` or `description` in `tasks.json` based on the answer. Do NOT create a separate task for an implementation detail—only add a new task when the answer introduces entirely new migration scope. + - Record all clarification questions and their outcomes in the **"## Open Questions & Questionnaire"** section of `plan.md`: + - Answered: `- [x] Q: ... → A: ...` + - Unanswered/skipped: `- [ ] ...` + - Remove the section entirely if no clarification questions were raised. + + **IMPORTANT**: The plan.md should NOT contain the detailed task breakdown. Those details go into tasks.json for better tracking and programmatic access. + + **Task Breakdown Rules**: When creating tasks for tasks.json and plan.md: + - Purpose: Break down coding work into discrete migration tasks. Each task represents a user-requested migration from one service/component to another, or a specific business logic modernization. + - Create tasks ONLY based on what the user explicitly requested - do not infer or add implicit tasks, **except** for the security/CVE remediation task which must always be included in every plan + - If an `assessment-report` is provided, the task description must identify which specific issues from the assessment report are addressed by that task (e.g., "Addresses issues: , ") + - Group related changes that serve a single user goal into one task (e.g., all changes needed to migrate to PostgreSQL) + - Find a matched skill / pattern for the task, following the following priority order. + 1. Skills available for the project, which will be listed in the `skill` tool description. + 2. Patterns that will be attached and available at plan execution phase, listed in the supported patterns file. + 3. Otherwise if no relevant pattern is available for the task pattern, use the prompt segment from the user directly. DO NOT expand the request scope. + - **IMPORTANT**: + - You MUST NOT use the pattern name as the skill name in the generated plan and tasks.json. + - If there are similar skills defined in project skill `.github/skills/` versus other skills, MUST use the one defined in project. + - Skills must be fully matched. For migration scenarios, both the source product and target product must match the task intent. + - Each task should be independently testable with integration tests + - Do not add tests for unimpacted code or existing functionality unless user requested + - **IMPORTANT**: Do NOT read individual skill files at this stage; Do Not include the skill detail in the tasks. + + **Integration Test Task Rules**: When user explicitly requests integration testing (e.g., "add integration tests", "generate integration tests", "test the migration"): + - Add an integration test task with type "integrationTest" after all transform/upgrade tasks but before containerization tasks + - This integration test task should: + - Have id format: "{sequence}-integrationTest" where sequence is the next number after the last migration task (e.g., if last migration is 001, use "002-integrationTest") + - Have description: "Generate and run integration tests for Azure service migrations" + - Have dependencies on ALL transform and upgrade task ids (so it runs after all migrations are complete) + - Have requirements: "Generate Layer 1 (Local Integration with TestContainers) and Layer 2 (Smoke Tests) for all Azure service migrations" + - Have layers: [1, 2] (only Layer 1 and Layer 2 tests) + - Omit environmentConfiguration unless explicitly provided by user input + - The integration test task appears in plan.md as a separate section after migration tasks but before containerization + + **Java Upgrade Task Guidelines**: Only add an upgrade task if the user explicitly requests it. You must refer to the ./java-upgrade-guideline.md for specific rules and guidelines when creating Java upgrade tasks. + + **.NET Upgrade Task Guidelines**: You must refer to the ./dotnet-upgrade-guideline.md for specific rules and guidelines when creating .NET upgrade tasks. + + **Deployment Task Rules**: + - **IMPORTANT** Do NOT create task type with `containerization` if deployment task already exists, deployment task will cover the containerization work if needed. + - Deployment Task Options: Azure App Service, Azure Kubernetes Service, Azure Container Apps (default), Azure App Service Managed Instance, Azure Static Web App, Azure Function App + + **Security Task Guidelines**: The security task order should be after all the upgrade and transform tasks and before the deployment tasks in the generated plan. If the user provides specific security requirements, incorporate them into the security task; otherwise, use the default requirements from the template. + + **IMPORTANT**: The upgrade task must be the first task in the task list because subsequent transform tasks (e.g., migrating to Azure services) depend on the upgraded runtime and project format. + +6. **Playbook Compliance Validation** (only when playbook attachments are present): + After generating the plan and tasks, call skill `validate-playbook-compliance` to validate that the plan tasks cover the playbook rules: + - tasks-json-path: `${modernization-work-folder}/.metadata/tasks.json` + - compliance-output-path: `${modernization-work-folder}/playbook-compliance.md` + - This validation is **best-effort only** and must **not** block or fail plan creation. + - If the validation call cannot run, fails, or required context/attachments are missing, you must still complete the workflow and emit `${modernization-work-folder}/plan.md` and `${modernization-work-folder}/.metadata/tasks.json`. + - If validation cannot be completed successfully, write a minimal warning/status report to `${modernization-work-folder}/playbook-compliance.md` explaining that validation was skipped or failed and why, if known. + +## Completion Criteria + +1. All clarification & questionnaire questions have been asked (or skipped with defaults) via `ask_user`, answers incorporated into `plan.md` and `tasks.json`, and outcomes recorded in the "## Open Questions & Questionnaire" section of `plan.md` +2. The modernization task list is built +3. The modernization task list MUST be scoped according to user input +4. DON'T RUN the plan if user does not explicitly ask you to run the plan +5. The generated plan.md and tasks.json are saved in the specified folder `${modernization-work-folder}` \ No newline at end of file diff --git a/.github/skills/create-modernization-plan/dotnet-upgrade-guideline.md b/.github/skills/create-modernization-plan/dotnet-upgrade-guideline.md new file mode 100644 index 000000000..a5c97e03a --- /dev/null +++ b/.github/skills/create-modernization-plan/dotnet-upgrade-guideline.md @@ -0,0 +1,43 @@ +# .NET Upgrade Task Guidelines + +Only add a .NET upgrade task if one of the following conditions is met: + +1. **End of Life (EOL)**: The project's .NET version is out of mainstream support. +2. **Azure SDK Compatibility**: The project targets a .NET Framework version older than 4.6.2, which does not support `netstandard2.0` and cannot use modern Azure SDK (`Azure.*`) packages. +3. **User Request**: The user explicitly requests a .NET version upgrade. + +The upgrade task must be the first task if it exists. + +### Target Version + +Always upgrade to the **latest LTS** version unless the user explicitly specifies a different target version. + +- Current latest LTS: **.NET 10** (`net10.0`) + +### Azure SDK Minimum .NET Version + +The modern Azure SDK for .NET (`Azure.*` packages) targets `netstandard2.0` as its baseline. The following .NET Framework versions do **not** support `netstandard2.0` and require an upgrade: + +| .NET Framework Version | `netstandard2.0` Support | Action | +|------------------------|:------------------------:|--------| +| 4.5 and below | ❌ | Upgrade required | +| 4.6 | ❌ | Upgrade required | +| 4.6.1 | ⚠️ Unreliable | Upgrade recommended | +| 4.6.2+ | ✅ | No upgrade needed for Azure SDK compatibility | + +> **Note**: .NET Framework 4.6.1 is technically listed as supporting `netstandard2.0` but has known issues. Microsoft recommends 4.7.2+ for reliable support. The Azure SDK explicitly targets `net462` as its minimum. + +## Framework Compatibility + +| Source Framework | Target Framework | SDK-Style Conversion Required | +|-----------------|:----------------:|:----------------------------:| +| .NET Framework 4.x | net10.0 | Yes | +| .NET Core 3.1 | net10.0 | No | +| .NET 5–9 | net10.0 | No | + +## .NET Task Selection Rules + +- **Rule 1 — Single task only**: Always create a **single** upgrade task that encompasses all necessary changes. The `modernize-dotnet-upgrade-engineer` agent handles the detailed breakdown during execution. +- **Rule 2 — EOL or Azure SDK incompatibility**: Create task "Upgrade .NET to latest LTS (net10.0)". Set the task `skills` array to `[]` (empty) — the upgrade agent handles execution internally. +- **Rule 3 — User-specified version**: Create task "Upgrade .NET to version X". Set the task `skills` array to `[]` (empty) — the upgrade agent handles execution internally. +- **Rule 4 — No upgrade needed**: If the project's .NET version is in support **and** the project targets .NET Framework 4.6.2+ (or any .NET Core / modern .NET) **and** the user did not request an upgrade, do **not** add an upgrade task. \ No newline at end of file diff --git a/.github/skills/create-modernization-plan/infra-plan-template.md b/.github/skills/create-modernization-plan/infra-plan-template.md new file mode 100644 index 000000000..a0bf419fb --- /dev/null +++ b/.github/skills/create-modernization-plan/infra-plan-template.md @@ -0,0 +1,48 @@ +# Infrastructure Plan Template + +Use this template when user explicitly requests infrastructure preparation (e.g., "prepare infrastructure", "create landing zone", "provision resources", "generate Bicep/Terraform/IaC files"). + +--- + +# Infrastructure Plan: [Plan Title] + +## User Requirements + +[A concise summary of the user's inputs, requirements and preferences for the infrastructure, may include: project codes, assessment report, architecture diagram] + +**Plan Configuration**: + +| Parameter | Value | Description | +|-----------|-------|-------------| +| IaC Tool | [bicep (default) / terraform] | Infrastructure as Code tool | +| Provision | [true (default) / false] | Whether to provision resources after generating IaC | +| Subscription | [Azure subscription ID] | Target Azure subscription | + +--- + +## Proposed Architecture + +[A high-level text diagram illustrating the proposed Azure resource architecture that meets the user's requirements] + +--- + +## Azure Resource List +A complete list of Azure resources to be generated. + +| Resource Type | Resource Name | SKU | Purpose | +|---------------|---------------|-----|---------| +| [e.g., SQL Database] | [e.g., sqldb-myapp-prod] | [e.g., S1] | [Purpose] | + +--- + +## Task + +**Description**: Generate IaC files to provision the required Azure resources. + +**Output**: Files of infrastructure as code + +**Skill**: [infrastructure-bicep-generation | infrastructure-terraform-generation] + +**Success Criteria**: +- IaC files generated and validated +- Resources provisioned successfully (if Provision=true) diff --git a/.github/skills/create-modernization-plan/java-upgrade-guideline.md b/.github/skills/create-modernization-plan/java-upgrade-guideline.md new file mode 100644 index 000000000..270412a96 --- /dev/null +++ b/.github/skills/create-modernization-plan/java-upgrade-guideline.md @@ -0,0 +1,44 @@ +# Java Upgrade Task Guidelines + +Only add an upgrade task if the user explicitly requests it. The upgrade task must be the first task if it exists. + +## Latest Stable Versions + +- Java: 25 +- Spring Boot: 4.x +- Spring Framework: 7.x + +## Supported Upgrade Versions + +- Java: 11, 17, 21, 25 +- Spring Boot: 3.x, 4.x +- Spring Framework: 6.x, 7.x + +## Framework Compatibility + +| Spring Boot | Spring Framework | Jakarta EE | Minimum Java | Maximum Java | +|-------------|:----------------:|:----------:|:------------:|:------------:| +| 2.x | 5.x | JavaEE (javax.*) | 8 | 11 | +| 3.x | 6.x | Jakarta EE (jakarta.*) | 17 | 21 | +| 4.x | 7.x | Jakarta EE (jakarta.*) | 25 | 25 | + +## Upgrade Task Types and Included Changes + +| Task Type | Spring Framework Upgrade | Jakarta EE Migration (javax.* → jakarta.*) | JDK/Java | +|-----------|:------------------------:|:------------------------------------------:|:-----------:| +| Spring Boot 4.x upgrade | 7.x | ✓ | 25 | +| Spring Boot 3.x upgrade | 6.x | ✓ | 21 | +| Spring Framework 7.x upgrade | — | ✓ | 25 | +| Spring Framework 6.x upgrade | — | ✓ | 21 | +| Jakarta EE upgrade | — | ✓ | 21 | +| JDK/Java upgrade | — | — | to specified version | + +## Java Task Selection Rules + +When selecting the Java upgrade task type, follow these rules in order: + +- **Rule 1 — No redundant sub-tasks**: Each upgrade type (Spring Boot, Spring Framework, Jakarta EE, JDK/Java) is hierarchical — higher-level tasks already include lower-level ones. Never create a lower-level task that is already covered by a selected higher-level task. For example, if a Spring Boot 4.x upgrade task is selected (which already includes JDK 25), do NOT also create a separate JDK/Java upgrade task. +- **Rule 2 — User-specified framework request doesn't fully match system state**: When the user requests a **framework** upgrade (e.g., Spring Boot, Spring Framework) but the target version they specify is not the latest available, select the highest-level task applicable and prompt the user to clarify. For example, if the user asks to "upgrade Spring Boot to 3.x" but Spring Boot 4.x is available, create a Spring Boot 3.x upgrade task and add a clarification question asking whether they want 4.x. **This rule does NOT apply to pure JDK/Java upgrade requests — see Rule 4.** +- **Rule 3 — User-specified request matches system state**: Select the most closely matching task type that directly matches the user's request and fits the system. For example, if the user asks to "upgrade JDK" and the JDK is outdated, create a JDK/Java upgrade task — NOT a higher-level Spring Boot or Spring Framework upgrade task. +- **Rule 4 — Never upgrade other frameworks on a JDK/Java request**: When the user explicitly requests a JDK/Java upgrade, you MUST NOT upgrade Spring Boot, Spring Framework, or Jakarta EE — create only a JDK/Java upgrade task targeting the user-specified version. If the project's existing Spring Boot, Spring Framework, or Jakarta EE versions are incompatible with the target Java version (per the Framework Compatibility table above), add a clarification question asking the user whether they also want to upgrade the incompatible framework(s) to a compatible version. +- **Rule 5 — Ask for clarification when the selected task diverges from the user's request**: Whenever the task you create differs from what the user explicitly asked for (e.g., upgrading to a different version, choosing a higher-level task type, or skipping a requested change due to compatibility), you MUST use the `ask_user` tool to explain what was selected, why it differs, and ask the user to confirm or adjust. If `ask_user` is not available, add the question to the "## Open Questions" section of `plan.md`. Never silently override the user's intent. \ No newline at end of file diff --git a/.github/skills/create-modernization-plan/plan-template.md b/.github/skills/create-modernization-plan/plan-template.md new file mode 100644 index 000000000..907521214 --- /dev/null +++ b/.github/skills/create-modernization-plan/plan-template.md @@ -0,0 +1,70 @@ +# Modernization Plan Template + +Use this template to generate modernization plans for applications. Replace placeholders with actual values and customize content based on the specific modernization scenario. + +**Planning Philosophy**: +- **Focus on GOALS, not implementation**: Describe WHAT needs to be achieved from the user's perspective +- **Skills define HOW**: All implementation details (frameworks, SDKs, libraries, code patterns, authentication methods) will be determined by the referenced skills +- **No assumptions**: Do not assume or specify any technical implementation approach in the plan - let skills handle all "how" decisions + +--- + +# Modernization Plan: [Modernization Title] + +**Project**: [Application Name] + +--- + +## Technical Framework + +**Purpose**: Document the application's current technology stack to provide context for the migration. + +**Template**: +```markdown +- **Language**: [Programming language and version, e.g., Java 11, Python 3.9, .NET 6] +- **Framework**: [Application framework and version, e.g., Spring Boot 2.7.18, Django 4.2, ASP.NET Core 6.0] +- **Build Tool**: [Build system, e.g., Maven 3.9, Gradle 8.0, npm] +- **Database**: [Current database, e.g., Oracle 19c, PostgreSQL 14, SQL Server 2019] +- **Key Dependencies**: [Major libraries/frameworks, e.g., Spring Data JPA, Hibernate, Entity Framework] +``` + +--- + +## Overview + +**Purpose**: Describe the high-level modernization goals without technical details. Focus on business objectives and what will change. + +**Template**: +> This migration [describe what is being migrated]. The application currently [describe current state]. The new architecture will: +> +> - [First key change and its business benefit] +> - [Second key change and its business benefit] +> - [Third key change and its business benefit] +> +> The migration follows [describe phased approach without technical specifics]. + +--- + +## Migration Impact Summary + +**Purpose**: Create a simple table showing migration impact for each application and its affected services. +**Rule**: Each line should be limited to a maximum of 80 characters. +**Template**: +``` +| Application | Original Service | New Azure Service | Authentication | Comments | +|-------------|------------------|-------------------|-------------|----------------|----------| +| [App Name] | [Old Service] | [Azure Service] | [Auth method (Default is Managed Identity if user not specified)] | [User specified request for the migration] | +``` + +--- + +## Open Questions & Questionnaire + +**Purpose**: Record all clarification questions raised during plan creation and their resolution status. Record all answers to questionnaire questions. + +**Template**: +```markdown +- [x] Q: What authentication method should be used for Azure Storage? → A: Use managed identity +- [ ] Which region should the deployment target? +``` + diff --git a/.github/skills/create-modernization-plan/questionnaire.md b/.github/skills/create-modernization-plan/questionnaire.md new file mode 100644 index 000000000..7a87a9bfa --- /dev/null +++ b/.github/skills/create-modernization-plan/questionnaire.md @@ -0,0 +1,19 @@ +# Try to answer these from the user context, and otherwise ask the user where required. + +1. Deployment to Azure +* Azure Container Apps (must include containerization) +* Azure Kubernetes Service (must include containerization) +* Azure App Service +* Azure App Service Managed Instance +* Azure Function App +* Azure Static Web App +* (Default) No deployment + +2. Should the Modernization Plan include Integration Testing? +* Yes, Local Integration with Containers +* Yes, Local Integration and Smoke Tests +* (Default) No + +3. Should the Modernization Plan include Containerization (Dockerfile generation)? +* Yes +* (Default) No \ No newline at end of file diff --git a/.github/skills/create-modernization-plan/security-plan-template.md b/.github/skills/create-modernization-plan/security-plan-template.md new file mode 100644 index 000000000..3a641b72a --- /dev/null +++ b/.github/skills/create-modernization-plan/security-plan-template.md @@ -0,0 +1,26 @@ +## Security Compliance + +**Purpose**: Scan and remediate CVEs (Common Vulnerabilities and Exposures) in project dependencies to ensure the modernized application is free of known security vulnerabilities. + +**Condition**: Always include this task in every modernization plan. Do not include this task if the user explicitly requests that it be removed. + +**Template**: + +**Description**: Scan all project dependencies for known CVEs and remediate any identified vulnerabilities to ensure the application is secure before deployment. + +**Requirements**: + Upgrade vulnerable dependencies to the minimum patched version. If a CVE fix requires a major version upgrade, document the affected dependency, the current version, the upgraded major version, and the breaking change risk. Verify that the project builds and all tests pass after remediation. + If the user provided specific security requirements, incorporate them as well. + +**Environment Configuration**: + Runtime environment established by previous tasks (e.g., Java Home, .NET runtime). + Build tool established by previous tasks (e.g., Maven/Gradle, dotnet). + +**App Scope**: + The app folders that this task will operate on + +**Skills**: + - Skill Name: validate-cves-and-fix + - Skill Location: builtin + - Skill Name: [additional skill if needed] + - Skill Location: [Skill location] \ No newline at end of file diff --git a/.github/skills/create-modernization-plan/supported-patterns-dotnet.md b/.github/skills/create-modernization-plan/supported-patterns-dotnet.md new file mode 100644 index 000000000..61212775b --- /dev/null +++ b/.github/skills/create-modernization-plan/supported-patterns-dotnet.md @@ -0,0 +1,50 @@ +## Supported Task Patterns + +The following are the task patterns supported by the modernize CLI. These patterns are used to identify the modernization tasks that need to be performed based on the user's input. + +The patterns are categorized into two groups, and they should be treated differently if picked: + +* Patterns with skill definitions: These patterns have pre-defined skills that can be used to execute the tasks. If a task matches one of these patterns, the corresponding skill should be used in the task plan. +* Patterns without skill definitions: These patterns do not have pre-defined skills. If a task matches one of these patterns, the description should be used to guide the AI in performing the required tasks. + **IMPORTANT**: The pattern name should NEVER be used as the skill name in the generated plan and tasks.json. They are meant to guide the task generation, not to be directly used as skills. + + +### Task Patterns with Skill Definitions +These patterns have pre-defined skills to assist in their execution. When they are selected in a modernization plan, the corresponding skills should be used. +Each of the item is written in the following format: `- **skill-name**: skill-description`. + +- **azcli-aks-deploy**: Generate plan for deploying to existing Azure Resources for Azure Kubernetes Service, using azcli +- **azcli-appservice-deploy**: Deployment steps for Azure App Service under the AzCLI flow +- **azcli-appservicemi-deploy**: Deployment steps for Azure App Service Managed Identity under the AzCLI flow +- **azcli-containerapp-deploy**: Generate plan for deploying to existing Azure Resources for Azure Container Apps, using azcli +- **azcli-functionapp-deploy**: Deployment steps for Azure Function App under the AzCLI flow +- **containerization**: Setup Dockerfiles for the project to run inside of containers for Azure Container Apps or Azure Kubernetes Service. +- **infrastructure-bicep-generation**: Generate Bicep IaC files for Azure infrastructure provisioning +- **infrastructure-terraform-generation**: Generate Terraform IaC files for Azure infrastructure provisioning +- **migration-azure-communication-email**: This knowledge base provides knowledge about how to use Azure Communication Services for sending emails in .NET applications, covering authentication with Managed Identity, configuration, and email operations. +- **migration-azure-confluent-kafka**: This knowledge base provides knowledge about migrating .NET applications using Confluent.Kafka from local Kafka to Confluent Cloud on Azure, using Azure Managed Identity and DefaultAzureCredential. +- **migration-azure-database-postgresql**: This file provides guidance for migrating .NET applications to Azure Database for PostgreSQL with passwordless Managed Identity, covering both Entity Framework Core and non-EF Core applications. +- **migration-azure-eventhubs-kafka**: This knowledge base provides knowledge about migrating .NET applications using Confluent.Kafka from local Kafka to Azure Event Hubs for Kafka, using Azure Managed Identity and DefaultAzureCredential. +- **migration-azure-keyvault-certificate**: This file provides guidance on using Azure Key Vault certificate management in .NET, covering authentication, configuration, and certificate operations. +- **migration-azure-keyvault-secret**: This file provides guidance on using Azure Key Vault secrets in .NET, covering authentication, configuration, and secret operations. +- **migration-azure-redis-cache**: This knowledge base provides guidance for adding distributed caching with Azure Cache for Redis to .NET applications, or migrating existing caching implementations (in-memory cache, Redis, or other providers) to use Azure Cache for Redis with DefaultAzureCredential (Managed Identity) authentication. +- **migration-azure-servicebus**: This knowledge base provides knowledge about migrating .NET applications to use Azure Service Bus with Managed Identity, covering queue and topic operations, message handling, and processor configurations. +- **migration-azure-sql-database**: This knowledge base provides knowledge about migrating .NET applications to use Azure SQL Database and Azure SQL Managed Instance with Managed Identity authentication, including Entity Framework 6 provider configuration. +- **migration-azure-storage-blob**: This knowledge base provides comprehensive knowledge about using Azure Storage Blob SDK in .NET applications, covering Managed Identity authentication, blob operations, container management, and SAS token generation. +- **migration-azure-storage-mount**: This knowledge base provides knowledge about migrating .NET applications from using hard-coded local file paths to Azure mounted storage paths while maintaining the same functionality. +- **migration-console-logging**: This knowledge base provides knowledge about configuring console logging in .NET applications for cloud environments, ensuring proper log output for container and cloud platform log aggregation. +- **migration-dependency-management**: Comprehensive guide for understanding and implementing dependency management in .NET projects, covering both modern SDK-style projects (.NET Core, .NET 5+) and legacy .NET Framework projects. Includes package reference management, project file structure, and migration considerations. +- **migration-managed-identity**: Comprehensive guidance for migrating .NET applications to use Azure Managed Identity for authentication instead of connection strings, client secrets, certificates, or other credential-based authentication methods. Covers Azure SQL, Storage, Key Vault, Service Bus, Event Hubs, Cosmos DB, and more. +- **migration-microsoft-entra-id**: This knowledge base provides knowledge about migrating .NET applications to use Microsoft Entra ID (formerly Azure AD) for authentication, including ASP.NET Core, ASP.NET Web Forms, and Microsoft Graph integration. +- **migration-opentelemetry-azure**: This guide describes how to implement OpenTelemetry in .NET with Azure Monitor for tracing, metrics, and logging migration. + +### Task Patterns without Skill Definitions +These patterns DO NOT have pre-defined skills. The pattern name and description define the modernization scenario, NOT A SKILL. They are in the format of `- **pattern-name**: pattern-description`. + +A pattern should be selected if it matches one of the customer's requirements, and there are no skills supporting this requirement. + +**IMPORTANT**: +- NEVER write the pattern name as skill name in the generated plan. +- Tasks generated from these patterns must have NO skill assigned. Do not reuse any skill from the "Task Patterns with Skill Definitions" section, even if a skill targets a similar technology or appears related. + + diff --git a/.github/skills/create-modernization-plan/supported-patterns-java.md b/.github/skills/create-modernization-plan/supported-patterns-java.md new file mode 100644 index 000000000..6ae2dee44 --- /dev/null +++ b/.github/skills/create-modernization-plan/supported-patterns-java.md @@ -0,0 +1,88 @@ +## Supported Task Patterns + +The following are the task patterns supported by the modernize CLI. These patterns are used to identify the modernization tasks that need to be performed based on the user's input. + +The patterns are categorized into two groups, and they should be treated differently if picked: + +* Patterns with skill definitions: These patterns have pre-defined skills that can be used to execute the tasks. If a task matches one of these patterns, the corresponding skill should be used in the task plan. +* Patterns without skill definitions: These patterns do not have pre-defined skills. If a task matches one of these patterns, the description should be used to guide the AI in performing the required tasks. + **IMPORTANT**: The pattern name should NEVER be used as the skill name in the generated plan and tasks.json. They are meant to guide the task generation, not to be directly used as skills. + + +### Task Patterns with Skill Definitions +These patterns have pre-defined skills to assist in their execution. When they are selected in a modernization plan, the corresponding skills should be used. +Each of the item is written in the following format: `- **skill-name**: skill-description`. + +- **azcli-aks-deploy**: Generate plan for deploying to existing Azure Resources for Azure Kubernetes Service, using azcli +- **azcli-appservice-deploy**: Deployment steps for Azure App Service under the AzCLI flow +- **azcli-appservicemi-deploy**: Deployment steps for Azure App Service Managed Identity under the AzCLI flow +- **azcli-containerapp-deploy**: Generate plan for deploying to existing Azure Resources for Azure Container Apps, using azcli +- **azcli-functionapp-deploy**: Deployment steps for Azure Function App under the AzCLI flow +- **containerization**: Setup Dockerfiles for the project to run inside of containers for Azure Container Apps or Azure Kubernetes Service. +- **infrastructure-bicep-generation**: Generate Bicep IaC files for Azure infrastructure provisioning +- **infrastructure-terraform-generation**: Generate Terraform IaC files for Azure infrastructure provisioning +- **migration-AWS-secrets-manager-to-azure-key-vault**: Migrates Java applications from AWS Secrets Manager (SecretsManagerClient, AWSSecretsManager) to Azure Key Vault SecretClient for secrets management. Use when migrating Java projects from AWS to Azure, replacing AWS secret storage with Azure Key Vault, or modernizing cloud secret management. +- **migration-activemq-servicebus**: Migrates Java Spring Boot applications from ActiveMQ JMS messaging to Azure Service Bus JMS. Replaces ActiveMQ dependencies with Spring Cloud Azure Service Bus JMS starter and updates connection configuration. Use when migrating Spring JMS applications from ActiveMQ to Azure Service Bus or modernizing on-premises messaging to Azure. +- **migration-amqp-rabbitmq-servicebus**: Migrates Java Spring applications from RabbitMQ AMQP messaging to Azure Service Bus via Spring Messaging. Replaces Spring AMQP RabbitMQ dependencies, updates connection settings, and migrates message producers and consumers. Use when migrating Spring applications from RabbitMQ to Azure Service Bus or replacing on-premises message brokers with Azure managed messaging. +- **migration-ant-project-to-maven-project**: Migrates Java projects from Ant build system to Maven, converting build.xml to pom.xml and restructuring directories to Maven standard layout. Use when modernizing Java projects that use Ant builds, converting to Maven for dependency management, or standardizing build tooling. +- **migration-auth-by-mi-for-azure-redis-in-micronaut-project**: Secure Azure Cache for Redis with Managed Identity via Micronaut +- **migration-certificate-management-to-azure-key-vault**: Migrates Java TLS/MTLS certificate management from local KeyStore storage to Azure Key Vault JCA (Java Cryptography Architecture). Replaces local certificate handling with Azure Key Vault for centralized certificate management. Use when migrating Java applications that use local KeyStore, SSLContext, or Certificate classes to Azure Key Vault for secure certificate storage. +- **migration-confluent-cloud-kafka**: Migrates Java applications from self-hosted Apache Kafka to Apache Kafka on Confluent Cloud with passwordless authentication via Microsoft Entra ID. Updates Kafka connection configuration and authentication settings. Use when migrating Java Kafka producers or consumers to Confluent Cloud or enabling passwordless Entra ID authentication for Kafka on Confluent Cloud. +- **migration-cryptography-operations-to-azure-key-vault**: Migrates Java cryptographic operations (Cipher, Signature) from local key management to Azure Key Vault for centralized key management and cryptographic operations. Use when migrating Java applications that use javax.crypto.Cipher or java.security.Signature to Azure Key Vault, or centralizing cryptographic key management in Azure. +- **migration-eclipse-project-to-maven-project**: Migrates Java projects from Eclipse IDE project format (.project, .classpath) to Apache Maven project structure with pom.xml. Converts Eclipse build configuration and classpath settings to Maven conventions. Use when modernizing Eclipse-based Java projects to Maven, converting .project/.classpath files, or standardizing build tooling. +- **migration-ibm-db2-to-azure-postgresql**: Migrate IBM Db2 to Azure Database for PostgreSQL +- **migration-ibm-db2-to-azure-sql**: Migrate IBM Db2 to Azure SQL Database +- **migration-informix-to-postgresql**: Migrates Java application database layer from Informix Database to PostgreSQL, including JDBC driver changes, SQL syntax conversion, and Informix-specific feature replacement. Use when migrating Java applications from Informix to PostgreSQL, converting Informix SQL to PostgreSQL syntax, or replacing Informix JDBC drivers. +- **migration-java-ee-amqp-rabbitmq-servicebus**: Migrates Java EE/Jakarta EE applications from RabbitMQ AMQP messaging to Azure Service Bus SDK. Replaces RabbitMQ client dependencies, migrates publishers and consumers, updates connection management, and maps RabbitMQ concepts (exchanges, queues) to Service Bus equivalents (topics, subscriptions). Use when migrating Java EE or Jakarta EE applications from RabbitMQ to Azure Service Bus. +- **migration-javax.email-send-to-azure-communication-service-email**: Migrates Java applications from JavaMail (javax.mail) API to Azure Communication Service Email for sending emails. Replaces JavaMail email sending, message construction, and authentication with Azure Communication Service equivalents. Use when migrating Java applications from JavaMail or SMTP-based email sending to Azure Communication Service Email. +- **migration-jax-rpc-to-jax-ws**: Migrates Java web service implementations from deprecated JAX-RPC to JAX-WS. Updates web service configuration files and JAX-RPC specific code to use JAX-WS equivalents. Use when modernizing Java web services that use JAX-RPC or upgrading deprecated JAX-RPC APIs to the JAX-WS standard. +- **migration-kafka-to-eventhubs**: Migrates Java applications from Kafka to Azure Event Hubs for Kafka with managed identity for secure, passwordless authentication. Updates Spring Cloud Azure dependencies, Kafka connection settings, and authentication configuration. Use when migrating Java Kafka producers or consumers to Azure Event Hubs, or enabling managed identity authentication for event streaming. +- **migration-log-to-console**: Migrates Java application logging from file-based output to console-only output. Removes file appenders from logging configuration (logback, logging.xml) and ensures all log output goes to console. Use when containerizing Java applications, migrating to cloud-native logging, or preparing Java apps for Azure where console logging is preferred. +- **migration-mi-azure-sql**: Migrates Java Spring Boot projects from password-based authentication to Azure Managed Identity for connecting to Azure SQL Database. Updates Spring Cloud Azure dependencies and datasource configuration for passwordless authentication. Use when enabling managed identity for Azure SQL Database connections, removing hardcoded database passwords, or securing Java Spring Boot database authentication. +- **migration-mi-cassandra**: Migrates Java applications to connect to Azure Cosmos DB for Apache Cassandra using managed identity via Service Connector in Azure public cloud. Updates CqlSession configuration and Spring Data Cassandra properties. Use when migrating Java or Spring Boot applications to Azure Cosmos DB Cassandra API, enabling managed identity for Cassandra connections, or replacing Cassandra password authentication. +- **migration-mi-eventhub**: Migrates Java projects from password-based authentication to Azure Managed Identity for connecting to Azure Event Hubs. Adds Spring Cloud Azure dependencies and updates Event Hubs and Kafka configuration for passwordless authentication. Use when enabling managed identity for Azure Event Hubs in Java applications, removing Event Hubs connection string passwords, or securing event streaming authentication. +- **migration-mi-mariadb**: Migrates Java applications from password-based MariaDB authentication to Azure Managed Identity for Azure Database for MariaDB in public cloud using AzureMysqlAuthenticationPlugin. Updates JDBC connection and authentication configuration. Use when enabling managed identity for Azure Database for MariaDB, removing MariaDB passwords, or implementing credential-free MariaDB authentication in Azure. +- **migration-mi-mongodb**: Migrate from password-based authentication to Microsoft Entra ID authentication for Azure DocumentDB (with MongoDB Compatibility) in Java projects +- **migration-mi-mysql**: Migrates Java Spring Boot projects from password-based MySQL authentication to Azure Managed Identity for Azure Database for MySQL. Updates Spring Cloud Azure dependencies and datasource configuration for passwordless authentication. Use when enabling managed identity for Azure MySQL connections in Spring Boot, removing hardcoded MySQL passwords, or securing Spring datasource authentication. +- **migration-mi-postgresql**: Migrates Java Spring Boot projects from password-based PostgreSQL authentication to Azure Managed Identity for Azure Database for PostgreSQL. Updates Spring Cloud Azure dependencies and datasource configuration for passwordless authentication. Use when enabling managed identity for Azure PostgreSQL connections in Spring Boot, removing hardcoded PostgreSQL passwords, or securing Spring datasource authentication. +- **migration-mi-servicebus**: Azure Service Bus Managed Identity via Spring +- **migration-on-premises-user-authentication-to-microsoft-entra-id**: Migrates Java Spring Boot application user authentication from on-premises login to Microsoft Entra ID using spring-cloud-azure-starter-active-directory and spring-boot-starter-oauth2-client. Use when migrating Java web application authentication to Microsoft Entra ID, modernizing on-premises login to cloud identity, or adding Azure Active Directory authentication. +- **migration-oracle-to-postgresql**: Migrates Java application database layer from Oracle Database to PostgreSQL, including JDBC driver changes, SQL syntax conversion, and Oracle-specific feature replacement. Uses project-specific coding_notes.md guidance when available. Use when migrating Java applications from Oracle to PostgreSQL, converting Oracle SQL to PostgreSQL syntax, or replacing Oracle JDBC drivers. +- **migration-other-cache-solutions-to-azure-managed-cache**: Migrate other cache solutions to use Redis, and potentially to Azure Managed Redis / Azure Cache for Redis (retiring) while following best practices. Use this skill when users want to migrate other cache solutions to use Redis, such as Apache Commons JCS, DynaCache, Embedded cache, JCache, OSCache, ShiftOne, Oracle Coherence, etc., or local Redis to Azure Managed Redis / Azure Cache for Redis (retiring) with secure authentication changes. +- **migration-plaintext-credential-to-azure-keyvault**: Migrates hardcoded plaintext credentials (passwords, secrets, API keys, connection strings, tokens) in Java source code to Azure Key Vault for secure storage and retrieval. Use when securing Java applications by removing hardcoded credentials, migrating plaintext secrets to Azure Key Vault, or implementing centralized secret management. +- **migration-s3-to-azure-blob-storage**: Migrates Java applications from Amazon S3 SDK to Azure Blob Storage SDK, including bucket/container operations, object storage, access policies, and SAS token generation. Use when migrating Java applications from AWS S3 to Azure Blob Storage, replacing S3Client with BlobServiceClient, or converting AWS storage APIs to Azure equivalents. +- **migration-spring-jms-rabbitmq-servicebus**: Migrates Java Spring Boot applications from RabbitMQ JMS messaging to Azure Service Bus JMS. Replaces RabbitMQ JMS dependencies with Spring Cloud Azure Service Bus JMS starter and updates connection configuration. Use when migrating Spring JMS applications from RabbitMQ to Azure Service Bus, replacing RMQConnectionFactory, or modernizing JMS messaging to Azure. +- **migration-sqs-to-servicebus**: Migrates Java applications from AWS Simple Queue Service (SQS) to Azure Service Bus for message queuing. Replaces AWS SQS SDK dependencies with Azure Service Bus SDK, updates message sending and receiving code, and migrates queue configuration. Use when migrating Java applications from AWS SQS to Azure Service Bus, replacing SQS client code, or modernizing cloud message queuing to Azure. +- **migration-sybase-ase-to-azure-sql-database**: Migrates Java application database layer from Sybase ASE (Adaptive Server Enterprise) to Azure SQL Database with passwordless managed identity authentication. Use when migrating Java applications from Sybase ASE to Azure SQL. + +### Task Patterns without Skill Definitions +These patterns DO NOT have pre-defined skills. The pattern name and description define the modernization scenario, NOT A SKILL. They are in the format of `- **pattern-name**: pattern-description`. + +A pattern should be selected if it matches one of the customer's requirements, and there are no skills supporting this requirement. + +**IMPORTANT**: +- NEVER write the pattern name as skill name in the generated plan. +- Tasks generated from these patterns must have NO skill assigned. Do not reuse any skill from the "Task Patterns with Skill Definitions" section, even if a skill targets a similar technology or appears related. + +- **amazon-kinesis-to-azure-event-hubs**: Amazon Kinesis to Azure Event Hubs +- **amazon-sns-to-azure-service-bus**: Amazon SNS to Azure Service Bus +- **apache-pulsar-to-azure-event-hubs**: Apache Pulsar to Azure Event Hubs +- **aws-lambda-to-azure-functions**: AWS Lambda to Azure Functions +- **firebird-to-azure-postgresql**: Firebird to Azure PostgreSQL +- **google-cloud-bigtable-to-azure-cosmos-db**: Google Cloud Bigtable to Azure Cosmos DB +- **google-cloud-functions-to-azure-functions**: Google Cloud Functions to Azure Functions +- **google-cloud-pub-sub-to-azure-service-bus**: Google Cloud Pub/Sub to Azure Service Bus +- **google-cloud-spanner-to-azure-postgresql**: Google Cloud Spanner to Azure PostgreSQL +- **google-cloud-storage-to-azure-blob-storage**: Google Cloud Storage to Azure Blob Storage +- **google-firestore-to-azure-cosmos-db**: Google Firestore to Azure Cosmos DB +- **ibm-db2-to-azure-postgresql**: IBM DB2 to Azure PostgreSQL +- **ibm-mq-jms-to-azure-service-bus**: IBM MQ JMS to Azure Service Bus +- **migration-local-certificate-management-to-azure-key-vault**: Local certificate management to Azure Key Vault +- **migration-local-files-to-mounted-azure-storage**: Local files to mounted Azure Storage paths (starts with `${AZURE_MOUNT_PATH:/mnt/azure}`) +- **quartz-scheduler-to-azure-functions**: Quartz Scheduler to Azure Functions +- **solace-pubsub-to-azure-service-bus**: Solace PubSub+ to Azure Service Bus +- **spring-batch-to-azure-durable-functions**: Spring Batch to Azure Durable Functions +- **spring-cloud-config-to-azure-app-configuration**: Spring Cloud Config to Azure App Configuration +- **sqlite-to-azure-postgresql**: SQLite to Azure PostgreSQL +- **sybase-ase-to-azure-postgresql**: Sybase ASE to Azure Database for PostgreSQL +- **tibco-ems-jms-to-azure-service-bus**: TIBCO EMS JMS to Azure Service Bus diff --git a/.github/skills/create-modernization-plan/tasks-schema.json b/.github/skills/create-modernization-plan/tasks-schema.json new file mode 100644 index 000000000..397678e03 --- /dev/null +++ b/.github/skills/create-modernization-plan/tasks-schema.json @@ -0,0 +1,349 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Modernization Tasks Template", + "description": "Schema for tasks-template.json. Preserve field descriptions because they are used to generate the JSON by LLM.", + "type": "object", + "required": ["$schema", "description", "tasks", "metadata"], + "additionalProperties": false, + "properties": { + "$schema": { + "type": "string", + "description": "JSON Schema reference used by the template." + }, + "description": { + "type": "string", + "description": "Tasks template for modernization plan. Generate this file alongside plan.md to track individual migration tasks." + }, + "tasks": { + "type": "array", + "description": "List of individual migration tasks.", + "items": { + "oneOf": [ + { "$ref": "#/$defs/transformTask" }, + { "$ref": "#/$defs/upgradeTask" }, + { "$ref": "#/$defs/integrationTestTask" }, + { "$ref": "#/$defs/containerizationTask" }, + { "$ref": "#/$defs/deploymentTask" }, + { "$ref": "#/$defs/securityTask" }, + { "$ref": "#/$defs/infrastructureTask" } + ] + } + }, + "metadata": { + "type": "object", + "description": "Metadata for the plan.", + "additionalProperties": false, + "required": ["planName", "projectName", "language", "createdAt", "version"], + "properties": { + "planName": { + "type": "string", + "description": "[Plan name]" + }, + "projectName": { + "type": "string", + "description": "[Application Name]" + }, + "language": { + "type": "string", + "description": "[Programming language]" + }, + "createdAt": { + "type": "string", + "description": "[ISO 8601 timestamp]", + "format": "date-time" + }, + "version": { + "type": "string", + "description": "Version of the template schema.", + "const": "1.0" + } + } + } + }, + "$defs": { + "taskBase": { + "type": "object", + "additionalProperties": false, + "required": ["type", "id", "description", "requirements"], + "properties": { + "type": { + "type": "string", + "description": "Task type identifier." + }, + "id": { + "type": "string", + "description": "[Unique identifier for this task, start with sequence and category name, like '001-transform-migration-rabbitmq-to-servicebus']" + }, + "description": { + "type": "string", + "description": "[Brief description of what this task achieves from the user's perspective. It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" + }, + "reason": { + "type": "string", + "description": "[Explain why this task is needed, e.g., the motivation, business justification, or technical necessity that drives this task]" + }, + "requirements": { + "type": "string", + "description": "[The specific requirements for this task including: what to migrate (features, APIs, patterns), constraints (backward compatibility, modules to avoid), target Azure services, and technical preferences (authentication methods, patterns). It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" + }, + "environmentConfiguration": { + "type": ["string"], + "description": "[Environment configuration from user input (e.g. endpoint, access id). Omit this field if not specified]" + }, + "status": { + "type": ["string"], + "description": "Task execution status. Only has value after task is executed.", + "enum": ["pending", "started", "success", "failed", "skipped"] + }, + "taskSummary": { + "type": "string", + "description": "Summary of task execution result. Only has value after task is executed." + }, + "dependencies": { + "type": "array", + "description": "[List of task IDs that this task depends on. The task will only be executed after all its dependencies have completed successfully.]", + "items": { + "type": "string" + } + } + } + }, + "skill": { + "type": "object", + "additionalProperties": false, + "required": ["name", "location"], + "properties": { + "name": { + "type": "string", + "description": "[The skill name that will be used for this task, e.g., 'migration-rabbitmq-to-servicebus'.]" + }, + "location": { + "type": "string", + "description": "Skill location: project, remote and builtin, builtin is renamed from custom", + "enum": ["project","remote","builtin"] + } + } + }, + "successCriteria": { + "type": "object", + "additionalProperties": false, + "required": [ + "passBuild", + "generateNewUnitTests", + "passUnitTests" + ], + "description": "The task success criteria to validate after task execution.", + "properties": { + "passBuild": { + "type": ["string"], + "default": "true", + "description": "Project must compile successfully after migration, use default value if user does not specify" + }, + "generateNewUnitTests": { + "type": ["string"], + "default": "false", + "description": "Create mock-based unit tests for newly added Azure integration code to ensure test coverage, use default value if user does not specify" + }, + "passUnitTests": { + "type": ["string"], + "default": "true", + "description": "All unit tests must pass; mock dependent Azure resources if not provided, use default value if user does not specify" + } + } + }, + "successCriteriaStatus": { + "type": "object", + "not": { + "type": "null" + }, + "additionalProperties": false, + "description": "Optional validation status for each success criterion. Omit this field until validation is complete. If present, use true/false string values.", + "properties": { + "passBuild": { + "type": ["string"], + "description": "Validation status of passBuild criterion. true means passed, false means failed." + }, + "generateNewUnitTests": { + "type": ["string"], + "description": "Validation status of generateNewUnitTests criterion. true means passed, false means failed." + }, + "passUnitTests": { + "type": ["string"], + "description": "Validation status of passUnitTests criterion. true means passed, false means failed." + } + } + }, + "transformTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "successCriteria"], + "properties": { + "type": { + "const": "transform", + "description": "transform task template" + }, + "skills": { + "type": "array", + "description": "The skills that will be used for this task, it is started with migration and looks like 'migration-rabbitmq-to-servicebus-mi'", + "items": { "$ref": "#/$defs/skill" } + }, + "successCriteria": { "$ref": "#/$defs/successCriteria" }, + "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } + } + } + ] + }, + "upgradeTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "successCriteria"], + "properties": { + "type": { + "const": "upgrade", + "description": "Upgrade task template" + }, + "successCriteria": { "$ref": "#/$defs/successCriteria" }, + "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } + } + } + ] + }, + "containerizationTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "dockerfilePath"], + "properties": { + "type": { + "const": "containerization", + "description": "Containerization task template - Only include if the target deployment requires containerization (e.g., AKS, ACA) or if the user explicitly requested containerization. Skip for non-containerized deployments." + }, + "dockerfilePath": { + "type": "string", + "description": "[Path to Dockerfile, indicate if existing or to be created]" + } + } + } + ] + }, + "deploymentTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "targetAzureService", "resourceStatus", "deploymentTool", "skills"], + "properties": { + "type": { + "const": "deployment", + "description": "Deployment task template - Containerize, provision and deploy the application to Azure. Only include if the user explicitly requested deployment." + }, + "skills": { + "type": "array", + "description": "The deployment skill to use based on targetAzureService: 'azcli-aks-deploy' for Azure Kubernetes Service, 'azcli-containerapp-deploy' for Azure Container Apps, 'azcli-appservice-deploy' for Azure App Service, 'azcli-functionapp-deploy' for Azure Function App, 'azcli-appservicemi-deploy' for Azure App Service with Managed Identity", + "items": { "$ref": "#/$defs/skill" } + }, + "targetAzureService": { + "type": "string", + "description": "[Azure service name, e.g., Azure Container Apps, AKS, App Service]" + }, + "resourceStatus": { + "type": "string", + "description": "[Specify if using existing resource or will create new service]" + }, + "deploymentTool": { + "type": "string", + "description": "Infrastructure as Code tool type. Default to 'terraform' for aks, 'bicep' for other services if not specified.", + "enum": ["bicep", "terraform"] + } + } + } + ] + }, + "integrationTestTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "layers"], + "properties": { + "type": { + "const": "integrationTest", + "description": "Integration test task template - Generate and run integration tests for migrated Azure services. Only include when user explicitly requests integration testing. This task runs after all transform/upgrade tasks but before containerization." + }, + "layers": { + "type": "array", + "description": "[Array of test layers to execute, e.g., [1, 2] for Layer 1 (Local Integration with TestContainers) and Layer 2 (Smoke Tests)]", + "items": { + "type": "number", + "enum": [1, 2] + }, + "minItems": 1 + } + } + } + ] + }, + "securityTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "successCriteria"], + "properties": { + "type": { + "const": "security", + "description": "Security task template - Include when security remediation, vulnerability scanning, or compliance checks are required." + }, + "cveReport": { + "type": ["string"], + "description": "Path to final-cve-report.json. Only has value after CVE checking is complete." + }, + "successCriteria": { "$ref": "#/$defs/successCriteria" }, + "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } + } + } + ] + }, + "infrastructureTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "skills", "iacType", "provision"], + "properties": { + "type": { + "const": "infrastructure", + "description": "Infrastructure task template - Generate IaC files (Bicep or Terraform) to provision Azure resources." + }, + "iacType": { + "type": "string", + "description": "Infrastructure as Code tool type.", + "enum": ["bicep", "terraform"] + }, + "provision": { + "type": "boolean", + "description": "Whether to provision Azure resources after generating IaC files." + }, + "skills": { + "type": "array", + "description": "The skill used for this task, e.g., 'infrastructure-bicep-generation' or 'infrastructure-terraform-generation'", + "items": { "$ref": "#/$defs/skill" } + } + } + } + ] + } + } +} diff --git a/.github/skills/cve-known-vulnerabilities/SKILL.md b/.github/skills/cve-known-vulnerabilities/SKILL.md new file mode 100644 index 000000000..2ab39f825 --- /dev/null +++ b/.github/skills/cve-known-vulnerabilities/SKILL.md @@ -0,0 +1,201 @@ +--- +name: cve-known-vulnerabilities +description: Detect known CVE vulnerabilities in Java project dependencies using the GitHub Security Advisories API +--- + +# CVE Security Assessment: Known Dependency Vulnerabilities + +## Role + +You are a **dependency security scanner**. Your task is to programmatically collect the project's Java dependencies, query the GitHub Security Advisories API for known CVEs, and report findings in a structured JSON format. + +> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether known CVE vulnerabilities exist in the project's dependencies. You may recommend dependency upgrades to patched versions, but do NOT make code changes or modify build files yourself. + +## Objective + +Identify all known CVE vulnerabilities in the project's direct and transitive dependencies by: +1. Detecting the build tool (Maven or Gradle) +2. Collecting dependency coordinates (`groupId:artifactId:version`) +3. Querying the GitHub Security Advisories API +4. Reporting findings in structured JSON format + +## Instructions + +### Step 1: Detect Build Tool + +Check which build tool the project uses: + +```bash +if [ -f "pom.xml" ]; then + BUILD_TOOL="maven" +elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then + BUILD_TOOL="gradle" +else + echo "No supported Java build tool found" + mkdir -p security + printf '[]\n' > security/cve-assessment-result.json + exit 0 +fi +``` + +### Step 2: Collect Dependencies + +#### Maven Projects + +Try the CLI approach first (produces the most accurate results): + +```bash +# Detect wrapper vs bare command +if [ -f "./mvnw" ]; then MVN_CMD="./mvnw"; elif [ -f "./mvnw.cmd" ]; then MVN_CMD="./mvnw.cmd"; else MVN_CMD="mvn"; fi + +# Collect all dependencies as a tree (direct + transitive with parent chain) +$MVN_CMD dependency:tree -DoutputFile=/tmp/mvn-deps.txt -DappendOutput=true -B -q 2>/dev/null +``` + +Parse the output file. The tree format uses indentation to show the dependency hierarchy: +- The root line is the project itself (depth 0) — skip it. +- Depth-1 entries (prefixed with `+- ` or `\- `) are **direct** dependencies. +- Depth-2+ entries are **transitive** dependencies, nested under the direct dependency that pulls them in. +- Each entry has the format: `groupId:artifactId:packaging:version:scope` (5 parts) or `groupId:artifactId:packaging:classifier:version:scope` (6 parts). Extract `groupId:artifactId:version` from each. + +For transitive dependencies (depth 2+), trace them back to their depth-1 ancestor (the direct dependency that pulls them in), and use that direct dependency's declaration line number in the evidence. + +**Fallback** — if the CLI command fails or is unavailable, parse `pom.xml` files directly (direct dependencies only): +- Find all `pom.xml` files (excluding `target/`, `node_modules/`, `.git/`) +- Extract `` elements: ``, ``, `` +- Resolve `${property}` references from the `` section of the same POM +- Skip dependencies where the version cannot be resolved + +#### Gradle Projects + +Try the CLI approach first: + +```bash +# Detect wrapper vs bare command +if [ -f "./gradlew" ]; then GRADLE_CMD="./gradlew"; elif [ -f "./gradlew.bat" ]; then GRADLE_CMD="./gradlew.bat"; else GRADLE_CMD="gradle"; fi + +# In multi-project builds, Gradle automatically runs the task on all subprojects +$GRADLE_CMD dependencies --configuration runtimeClasspath -q 2>/dev/null +``` + +Parse the dependency tree output. The tree format uses indentation to show the dependency hierarchy: +- Depth-1 entries (top-level `+---` or `\---`) are **direct** dependencies. +- Depth-2+ entries (nested under a direct dependency) are **transitive** dependencies. + +For each dependency line: +- Only process lines containing `---` (tree markers like `+---` or `\---`) +- Strip tree formatting characters (`+---`, `\---`, `|`, leading whitespace) +- Handle version conflict resolution: `group:artifact:1.0 -> 2.0` means use version `2.0` +- Skip `project :submodule` entries and entries with `FAILED` versions +- Remove `(*)` duplicate markers and `(c)` constraint markers +- Extract `groupId:artifactId:version` + +For transitive dependencies (depth 2+), trace them back to their depth-1 ancestor (the direct dependency that pulls them in), and use that direct dependency's declaration line number in the evidence. + +**Fallback** — if the CLI command fails, parse `build.gradle` / `build.gradle.kts` files (direct dependencies only): +- Look for dependency declarations: `implementation`, `api`, `compileOnly`, `runtimeOnly`, etc. +- Extract GAV from patterns like `implementation 'group:artifact:version'` or `implementation("group:artifact:version")` +- Skip entries where the version contains `$` (unresolved properties) + +### Step 3: Query GitHub Security Advisories API + +Resolve the GitHub token and query the API: + +```bash +# Resolve token +TOKEN="${GITHUB_TOKEN:-$(gh auth token 2>/dev/null)}" +``` + +**IMPORTANT: Batch dependencies in groups of 30** to avoid URL length limits. + +For each batch, construct the `affects` parameter and query: + +```bash +# Build the affects parameter: groupId:artifactId@version,groupId:artifactId@version,... +# URL-encode the affects value + +# Query using gh api (preferred — avoids firewall issues): +gh api "/advisories?ecosystem=maven&affects=${ENCODED_AFFECTS}&per_page=100" \ + --header "X-GitHub-Api-Version: 2022-11-28" \ + --paginate +``` + +If `gh api` is not available, fall back to `curl`. Only include the `Authorization` header when a token is available; omit it for unauthenticated requests: + +```bash +AUTH_HEADER="" +if [ -n "$TOKEN" ]; then + AUTH_HEADER="-H \"Authorization: Bearer $TOKEN\"" +fi + +eval curl -s -H "Accept: application/vnd.github+json" \ + $AUTH_HEADER \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "https://api.github.com/advisories?ecosystem=maven&affects=${ENCODED_AFFECTS}&per_page=100" +``` + +**Handle pagination**: If using `curl`, check the `Link` response header for `rel="next"` and follow it until there are no more pages. + +### Step 4: Process API Results + +For each advisory returned: +1. **Skip** advisories where `withdrawn_at` is not null (withdrawn advisories) +2. **Extract** the CVE ID from `cve_id` (fall back to `ghsa_id` if `cve_id` is null) +3. **Extract** severity from the `severity` field +4. **Extract** `summary`, `description`, and `html_url` +5. **Extract** affected package details from `vulnerabilities[]`: `package.name`, `vulnerable_version_range`, `first_patched_version` + +### Step 5: Format and Locate Evidence + +For each CVE found: +1. Identify which build files (`pom.xml`, `build.gradle`, `build.gradle.kts`) declare the affected dependency +2. Find the line number where the dependency is declared (if possible) +3. Build the evidence with file paths (e.g., `pom.xml:42`) and a detailed explanation including: + - Link to the CVE advisory + - Severity level + - List of affected dependencies with their declaration locations + - Recommended fix (upgrade to patched version if available) + +## Output Format + +Write the result as a **flat JSON array** (NOT wrapped in a result envelope) to the output file. + +If **no vulnerabilities are found**, write an empty array: `[]` + +If **vulnerabilities are found**, write an array of finding objects: + +```json +[ + { + "id": "CVE-2024-22233", + "name": "Spring Framework URL parsing vulnerability", + "status": "FOUND", + "category": "CVE", + "severity": "high", + "storyPoint": 1, + "evidence": { + "files": ["pom.xml:42", "module-b/pom.xml:18"], + "explanation": "[CVE-2024-22233](https://github.com/advisories/GHSA-xxxx): Spring Framework URL parsing vulnerability\n\nSeverity: HIGH\n\nAffected dependencies:\n - org.springframework:spring-core:5.3.20 (declared at pom.xml:42)\n - io.netty:netty-codec-http:4.1.86 (transitive, pulled by spring-boot-starter-web at pom.xml:42)\n\nRecommended fix:\n - Upgrade org.springframework:spring-core to 5.3.27 or later" + } + } +] +``` + +### Field Requirements + +- **id**: The CVE identifier (e.g., `CVE-2024-22233`), or GHSA ID if no CVE ID exists +- **name**: The advisory summary text +- **status**: Always `"FOUND"` for reported vulnerabilities +- **category**: Always `"CVE"` +- **severity**: The raw GitHub Advisory severity: `"critical"`, `"high"`, `"medium"`, or `"low"` +- **storyPoint**: Always `1` +- **evidence.files**: Array of workspace-relative file paths where affected dependencies are declared (with optional `:lineNumber` suffix). For transitive dependencies, use the line number of the direct dependency that pulls them in (e.g., if `netty-codec-http` is pulled in by `spring-boot-starter-web` declared at `pom.xml:42`, use `pom.xml:42`) +- **evidence.explanation**: Markdown-formatted description including CVE link, severity, affected dependencies with locations, and recommended fix + +### Important Notes + +- If a single CVE affects multiple dependencies, group them into ONE finding with all affected dependencies listed in the explanation +- If no build tool is detected, write `[]` and skip the assessment +- If the GitHub token is unavailable, proceed anyway (unauthenticated rate limits apply) +- If the API query fails, write `[]` and log the error +- Deduplicate: if the same CVE appears across multiple API batches, merge into a single finding diff --git a/.github/skills/cwe-code-quality/SKILL.md b/.github/skills/cwe-code-quality/SKILL.md new file mode 100644 index 000000000..9785ba5a3 --- /dev/null +++ b/.github/skills/cwe-code-quality/SKILL.md @@ -0,0 +1,153 @@ +--- +name: cwe-code-quality +description: Assess codebase for CWE code quality vulnerabilities (CWE-130, CWE-456, CWE-457, CWE-477, CWE-570, CWE-571, CWE-606, CWE-665, CWE-681, CWE-682, CWE-772, CWE-775, CWE-783, CWE-789, CWE-835, CWE-1057) +--- + +# CWE Security Assessment: Code Quality + +## Role + +You are an expert **code security reviewer** specializing in CWE vulnerability detection. + +> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. + +## Objective + +Analyze the application codebase for each of the 16 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. + +## CWE Rules to Assess + +### CWE-130: Improper Handling of Length Parameter Inconsistency +- **Severity:** potential | **Story Points:** 3 +- **Description:** The product parses a formatted message or structure, but it does not handle or incorrectly handles a length field that is inconsistent with the actual length of the associated data. + +### CWE-456: Missing Initialization of a Variable +- **Severity:** potential | **Story Points:** 2 +- **Description:** The product does not initialize critical variables, which causes the execution environment to use unexpected values. + +### CWE-457: Use of Uninitialized Variable +- **Severity:** potential | **Story Points:** 2 +- **Description:** The code uses a variable that has not been initialized, leading to unpredictable or unintended results. + +### CWE-477: Use of Obsolete Function +- **Severity:** optional | **Story Points:** 1 +- **Description:** The code uses deprecated or obsolete functions, which suggests that the code has not been actively reviewed or maintained. + +### CWE-570: Expression is Always False +- **Severity:** optional | **Story Points:** 1 +- **Description:** The product contains an expression that will always evaluate to false. + +### CWE-571: Expression is Always True +- **Severity:** optional | **Story Points:** 1 +- **Description:** The product contains an expression that will always evaluate to true. + +### CWE-606: Unchecked Input for Loop Condition +- **Severity:** potential | **Story Points:** 3 +- **Description:** The product does not properly check inputs that are used for loop conditions, potentially leading to a denial of service or other consequences because of excessive looping. + +### CWE-665: Improper Initialization +- **Severity:** potential | **Story Points:** 3 +- **Description:** The product does not initialize or incorrectly initializes a resource, which might leave the resource in an unexpected state when it is accessed or used. + +### CWE-681: Incorrect Conversion between Numeric Types +- **Severity:** potential | **Story Points:** 3 +- **Description:** When converting from one data type to another, such as long to integer, data can be omitted or translated in a way that produces unexpected values. If the resulting values are used in a sensitive context, then dangerous behaviors may occur. + +### CWE-682: Incorrect Calculation +- **Severity:** potential | **Story Points:** 5 +- **Description:** The product performs a calculation that generates incorrect or unintended results that are later used in security-critical decisions or resource management. + +### CWE-772: Missing Release of Resource after Effective Lifetime +- **Severity:** potential | **Story Points:** 3 +- **Description:** The product does not release a resource after its effective lifetime has ended, i.e., after the resource is no longer needed. + +### CWE-775: Missing Release of File Descriptor or Handle after Effective Lifetime +- **Severity:** potential | **Story Points:** 3 +- **Description:** The product does not release a file descriptor or handle after its effective lifetime has ended, i.e., after the file descriptor/handle is no longer needed. + +### CWE-783: Operator Precedence Logic Error +- **Severity:** optional | **Story Points:** 1 +- **Description:** The product uses an expression in which operator precedence causes incorrect logic to be used. + +### CWE-789: Memory Allocation with Excessive Size Value +- **Severity:** potential | **Story Points:** 5 +- **Description:** The product allocates memory based on an untrusted, large size value, but it does not ensure that the size is within expected limits, allowing arbitrary amounts of memory to be allocated. + +### CWE-835: Loop with Unreachable Exit Condition ('Infinite Loop') +- **Severity:** potential | **Story Points:** 3 +- **Description:** The product contains an iteration or loop with an exit condition that cannot be reached, i.e., an infinite loop. + +### CWE-1057: Data Access Operations Outside of Expected Data Manager Component +- **Severity:** potential | **Story Points:** 5 +- **Description:** The product uses a dedicated, central data manager component as required by design, but it contains code that performs data-access operations that do not use this data manager. + +## Instructions + +1. **Iterate through each CWE rule** listed above +2. **Systematically scan** the application source code for patterns matching each rule +3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match +4. **Continue to the next rule** after finding a match or exhausting the search +5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) + +### Search Strategy + +- Start with common vulnerability patterns: user input handling, external data processing, resource management +- Check configuration files, API endpoints, data access layers, and utility classes +- Consider both direct patterns and indirect/transitive vulnerability paths +- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code + +## Output Format + +Use the `write_assessment_result` tool to save results with the following JSON structure: + +```json +{ + "input_name": "CWE - Code Quality", + "analysis_method": "LLM", + "status": "success", + "result": { + "finding": "Assessed 16 CWE rules in Code Quality: X FOUND, Y NOT_FOUND", + "confidence": "high", + "evidence": ["Scanned application source files for code quality patterns"], + "values": [ + { + "id": "", + "name": "", + "status": "FOUND", + "category": "Code Quality", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": ["src/path/to/File.java"], + "explanation": "Description of the vulnerability found, including class/method and line reference" + } + }, + { + "id": "", + "name": "", + "status": "NOT_FOUND", + "category": "Code Quality", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": [], + "explanation": "" + } + } + ] + }, + "execution_time_seconds": 0, + "timestamp": "" +} +``` + +### Evidence Rules + +- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. +- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. +- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. +- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. +- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. +- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/cwe-concurrency-synchronization/SKILL.md b/.github/skills/cwe-concurrency-synchronization/SKILL.md new file mode 100644 index 000000000..7ff74ae9e --- /dev/null +++ b/.github/skills/cwe-concurrency-synchronization/SKILL.md @@ -0,0 +1,113 @@ +--- +name: cwe-concurrency-synchronization +description: Assess codebase for CWE concurrency & synchronization vulnerabilities (CWE-543, CWE-567, CWE-662, CWE-667, CWE-820, CWE-821) +--- + +# CWE Security Assessment: Concurrency & Synchronization + +## Role + +You are an expert **code security reviewer** specializing in CWE vulnerability detection. + +> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. + +## Objective + +Analyze the application codebase for each of the 6 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. + +## CWE Rules to Assess + +### CWE-543: Use of Singleton Pattern Without Synchronization in a Multithreaded Context +- **Severity:** potential | **Story Points:** 5 +- **Description:** The product uses the singleton pattern when creating a resource within a multithreaded environment. + +### CWE-567: Unsynchronized Access to Shared Data in a Multithreaded Context +- **Severity:** potential | **Story Points:** 5 +- **Description:** The product does not properly synchronize shared data, such as static variables across threads, which can lead to undefined behavior and unpredictable data changes. + +### CWE-662: Improper Synchronization +- **Severity:** potential | **Story Points:** 8 +- **Description:** The product utilizes multiple threads or processes to allow temporary access to a shared resource that can only be exclusive to one process at a time, but it does not properly synchronize these actions, which might cause simultaneous accesses of this resource by multiple threads or processes. + +### CWE-667: Improper Locking +- **Severity:** potential | **Story Points:** 8 +- **Description:** The product does not properly acquire or release a lock on a resource, leading to unexpected resource state changes and behaviors. + +### CWE-820: Missing Synchronization +- **Severity:** potential | **Story Points:** 8 +- **Description:** The product utilizes a shared resource in a concurrent manner but does not attempt to synchronize access to the resource. + +### CWE-821: Incorrect Synchronization +- **Severity:** potential | **Story Points:** 8 +- **Description:** The product utilizes a shared resource in a concurrent manner, but it does not correctly synchronize access to the resource. + +## Instructions + +1. **Iterate through each CWE rule** listed above +2. **Systematically scan** the application source code for patterns matching each rule +3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match +4. **Continue to the next rule** after finding a match or exhausting the search +5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) + +### Search Strategy + +- Start with common vulnerability patterns: user input handling, external data processing, resource management +- Check configuration files, API endpoints, data access layers, and utility classes +- Consider both direct patterns and indirect/transitive vulnerability paths +- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code + +## Output Format + +Use the `write_assessment_result` tool to save results with the following JSON structure: + +```json +{ + "input_name": "CWE - Concurrency & Synchronization", + "analysis_method": "LLM", + "status": "success", + "result": { + "finding": "Assessed 6 CWE rules in Concurrency & Synchronization: X FOUND, Y NOT_FOUND", + "confidence": "high", + "evidence": ["Scanned application source files for concurrency & synchronization patterns"], + "values": [ + { + "id": "", + "name": "", + "status": "FOUND", + "category": "Concurrency & Synchronization", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": ["src/path/to/File.java"], + "explanation": "Description of the vulnerability found, including class/method and line reference" + } + }, + { + "id": "", + "name": "", + "status": "NOT_FOUND", + "category": "Concurrency & Synchronization", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": [], + "explanation": "" + } + } + ] + }, + "execution_time_seconds": 0, + "timestamp": "" +} +``` + +### Evidence Rules + +- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. +- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. +- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. +- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. +- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. +- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/cwe-credentials-secrets/SKILL.md b/.github/skills/cwe-credentials-secrets/SKILL.md new file mode 100644 index 000000000..fe1e29b6f --- /dev/null +++ b/.github/skills/cwe-credentials-secrets/SKILL.md @@ -0,0 +1,109 @@ +--- +name: cwe-credentials-secrets +description: Assess codebase for CWE credentials & secrets vulnerabilities (CWE-259, CWE-321, CWE-732, CWE-778, CWE-798) +--- + +# CWE Security Assessment: Credentials & Secrets + +## Role + +You are an expert **code security reviewer** specializing in CWE vulnerability detection. + +> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. + +## Objective + +Analyze the application codebase for each of the 5 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. + +## CWE Rules to Assess + +### CWE-259: Use of Hard-coded Password +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product contains a hard-coded password, which it uses for its own inbound authentication or for outbound communication to external components. + +### CWE-321: Use of Hard-coded Cryptographic Key +- **Severity:** potential | **Story Points:** 5 +- **Description:** The product uses a hard-coded, unchangeable cryptographic key. + +### CWE-732: Incorrect Permission Assignment for Critical Resource +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product specifies permissions for a security-critical resource in a way that allows that resource to be read or modified by unintended actors. + +### CWE-778: Insufficient Logging +- **Severity:** potential | **Story Points:** 3 +- **Description:** When a security-critical event occurs, the product either does not record the event or omits important details about the event when logging it. + +### CWE-798: Use of Hard-coded Credentials +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product contains hard-coded credentials, such as a password or cryptographic key. + +## Instructions + +1. **Iterate through each CWE rule** listed above +2. **Systematically scan** the application source code for patterns matching each rule +3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match +4. **Continue to the next rule** after finding a match or exhausting the search +5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) + +### Search Strategy + +- Start with common vulnerability patterns: user input handling, external data processing, resource management +- Check configuration files, API endpoints, data access layers, and utility classes +- Consider both direct patterns and indirect/transitive vulnerability paths +- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code + +## Output Format + +Use the `write_assessment_result` tool to save results with the following JSON structure: + +```json +{ + "input_name": "CWE - Credentials & Secrets", + "analysis_method": "LLM", + "status": "success", + "result": { + "finding": "Assessed 5 CWE rules in Credentials & Secrets: X FOUND, Y NOT_FOUND", + "confidence": "high", + "evidence": ["Scanned application source files for credentials & secrets patterns"], + "values": [ + { + "id": "", + "name": "", + "status": "FOUND", + "category": "Credentials & Secrets", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": ["src/path/to/File.java"], + "explanation": "Description of the vulnerability found, including class/method and line reference" + } + }, + { + "id": "", + "name": "", + "status": "NOT_FOUND", + "category": "Credentials & Secrets", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": [], + "explanation": "" + } + } + ] + }, + "execution_time_seconds": 0, + "timestamp": "" +} +``` + +### Evidence Rules + +- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. +- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. +- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. +- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. +- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. +- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/cwe-file-path-security/SKILL.md b/.github/skills/cwe-file-path-security/SKILL.md new file mode 100644 index 000000000..1cac17b05 --- /dev/null +++ b/.github/skills/cwe-file-path-security/SKILL.md @@ -0,0 +1,109 @@ +--- +name: cwe-file-path-security +description: Assess codebase for CWE file & path security vulnerabilities (CWE-22, CWE-23, CWE-36, CWE-434, CWE-611) +--- + +# CWE Security Assessment: File & Path Security + +## Role + +You are an expert **code security reviewer** specializing in CWE vulnerability detection. + +> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. + +## Objective + +Analyze the application codebase for each of the 5 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. + +## CWE Rules to Assess + +### CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') +- **Severity:** optional | **Story Points:** 8 +- **Description:** The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory. + +### CWE-23: Relative Path Traversal +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product uses external input to construct a pathname that should be within a restricted directory, but it does not properly neutralize sequences such as .. that can resolve to a location that is outside of that directory. + +### CWE-36: Absolute Path Traversal +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product uses external input to construct a pathname that should be within a restricted directory, but it does not properly neutralize absolute path sequences such as /abs/path that can resolve to a location that is outside of that directory. + +### CWE-434: Unrestricted Upload of File with Dangerous Type +- **Severity:** mandatory | **Story Points:** 8 +- **Description:** The product allows the upload or transfer of dangerous file types that are automatically processed within its environment. + +### CWE-611: Improper Restriction of XML External Entity Reference +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product processes an XML document that can contain XML entities with URIs that resolve to documents outside of the intended sphere of control, causing the product to embed incorrect documents into its output. + +## Instructions + +1. **Iterate through each CWE rule** listed above +2. **Systematically scan** the application source code for patterns matching each rule +3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match +4. **Continue to the next rule** after finding a match or exhausting the search +5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) + +### Search Strategy + +- Start with common vulnerability patterns: user input handling, external data processing, resource management +- Check configuration files, API endpoints, data access layers, and utility classes +- Consider both direct patterns and indirect/transitive vulnerability paths +- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code + +## Output Format + +Use the `write_assessment_result` tool to save results with the following JSON structure: + +```json +{ + "input_name": "CWE - File & Path Security", + "analysis_method": "LLM", + "status": "success", + "result": { + "finding": "Assessed 5 CWE rules in File & Path Security: X FOUND, Y NOT_FOUND", + "confidence": "high", + "evidence": ["Scanned application source files for file & path security patterns"], + "values": [ + { + "id": "", + "name": "", + "status": "FOUND", + "category": "File & Path Security", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": ["src/path/to/File.java"], + "explanation": "Description of the vulnerability found, including class/method and line reference" + } + }, + { + "id": "", + "name": "", + "status": "NOT_FOUND", + "category": "File & Path Security", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": [], + "explanation": "" + } + } + ] + }, + "execution_time_seconds": 0, + "timestamp": "" +} +``` + +### Evidence Rules + +- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. +- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. +- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. +- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. +- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. +- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/cwe-injection-attacks/SKILL.md b/.github/skills/cwe-injection-attacks/SKILL.md new file mode 100644 index 000000000..347105abb --- /dev/null +++ b/.github/skills/cwe-injection-attacks/SKILL.md @@ -0,0 +1,137 @@ +--- +name: cwe-injection-attacks +description: Assess codebase for CWE injection attacks vulnerabilities (CWE-77, CWE-78, CWE-79, CWE-88, CWE-89, CWE-90, CWE-91, CWE-99, CWE-502, CWE-564, CWE-643, CWE-652) +--- + +# CWE Security Assessment: Injection Attacks + +## Role + +You are an expert **code security reviewer** specializing in CWE vulnerability detection. + +> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. + +## Objective + +Analyze the application codebase for each of the 12 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. + +## CWE Rules to Assess + +### CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection') +- **Severity:** mandatory | **Story Points:** 13 +- **Description:** The product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component. + +### CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') +- **Severity:** mandatory | **Story Points:** 13 +- **Description:** The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component. + +### CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') +- **Severity:** optional | **Story Points:** 8 +- **Description:** The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users. + +### CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product constructs a string for a command to be executed by a separate component in another control sphere, but it does not properly delimit the intended arguments, options, or switches within that command string. + +### CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') +- **Severity:** mandatory | **Story Points:** 13 +- **Description:** The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data. + +### CWE-90: Improper Neutralization of Special Elements used in an LDAP Query ('LDAP Injection') +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product constructs all or part of an LDAP query using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended LDAP query when it is sent to a downstream component. + +### CWE-91: XML Injection (aka Blind XPath Injection) +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product does not properly neutralize special elements that are used in XML, allowing attackers to modify the syntax, content, or commands of the XML before it is processed by an end system. + +### CWE-99: Improper Control of Resource Identifiers ('Resource Injection') +- **Severity:** potential | **Story Points:** 3 +- **Description:** The product receives input from an upstream component, but it does not restrict or incorrectly restricts the input before it is used as an identifier for a resource that may be outside the intended sphere of control. + +### CWE-502: Deserialization of Untrusted Data +- **Severity:** mandatory | **Story Points:** 13 +- **Description:** The product deserializes untrusted data without sufficiently ensuring that the resulting data will be valid. + +### CWE-564: SQL Injection: Hibernate +- **Severity:** mandatory | **Story Points:** 8 +- **Description:** Using Hibernate to execute a dynamic SQL statement built with user-controlled input can allow an attacker to modify the statement's meaning or to execute arbitrary SQL commands. + +### CWE-643: Improper Neutralization of Data within XPath Expressions ('XPath Injection') +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product uses external input to dynamically construct an XPath expression used to retrieve data from an XML database, but it does not neutralize or incorrectly neutralizes that input. This allows an attacker to control the structure of the query. + +### CWE-652: Improper Neutralization of Data within XQuery Expressions ('XQuery Injection') +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product uses external input to dynamically construct an XQuery expression used to retrieve data from an XML database, but it does not neutralize or incorrectly neutralizes that input. This allows an attacker to control the structure of the query. + +## Instructions + +1. **Iterate through each CWE rule** listed above +2. **Systematically scan** the application source code for patterns matching each rule +3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match +4. **Continue to the next rule** after finding a match or exhausting the search +5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) + +### Search Strategy + +- Start with common vulnerability patterns: user input handling, external data processing, resource management +- Check configuration files, API endpoints, data access layers, and utility classes +- Consider both direct patterns and indirect/transitive vulnerability paths +- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code + +## Output Format + +Use the `write_assessment_result` tool to save results with the following JSON structure: + +```json +{ + "input_name": "CWE - Injection Attacks", + "analysis_method": "LLM", + "status": "success", + "result": { + "finding": "Assessed 12 CWE rules in Injection Attacks: X FOUND, Y NOT_FOUND", + "confidence": "high", + "evidence": ["Scanned application source files for injection attacks patterns"], + "values": [ + { + "id": "", + "name": "", + "status": "FOUND", + "category": "Injection Attacks", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": ["src/path/to/File.java"], + "explanation": "Description of the vulnerability found, including class/method and line reference" + } + }, + { + "id": "", + "name": "", + "status": "NOT_FOUND", + "category": "Injection Attacks", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": [], + "explanation": "" + } + } + ] + }, + "execution_time_seconds": 0, + "timestamp": "" +} +``` + +### Evidence Rules + +- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. +- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. +- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. +- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. +- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. +- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/cwe-memory-safety/SKILL.md b/.github/skills/cwe-memory-safety/SKILL.md new file mode 100644 index 000000000..be7ffa439 --- /dev/null +++ b/.github/skills/cwe-memory-safety/SKILL.md @@ -0,0 +1,149 @@ +--- +name: cwe-memory-safety +description: Assess codebase for CWE memory safety vulnerabilities (CWE-119, CWE-120, CWE-123, CWE-125, CWE-415, CWE-416, CWE-672, CWE-786, CWE-787, CWE-788, CWE-805, CWE-822, CWE-823, CWE-824, CWE-825) +--- + +# CWE Security Assessment: Memory Safety + +## Role + +You are an expert **code security reviewer** specializing in CWE vulnerability detection. + +> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. + +## Objective + +Analyze the application codebase for each of the 15 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. + +## CWE Rules to Assess + +### CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer +- **Severity:** mandatory | **Story Points:** 21 +- **Description:** The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data. + +### CWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow') +- **Severity:** mandatory | **Story Points:** 13 +- **Description:** The product copies an input buffer to an output buffer without verifying that the size of the input buffer is less than the size of the output buffer. + +### CWE-123: Write-what-where Condition +- **Severity:** mandatory | **Story Points:** 13 +- **Description:** Any condition where the attacker has the ability to write an arbitrary value to an arbitrary location, often as the result of a buffer overflow. + +### CWE-125: Out-of-bounds Read +- **Severity:** optional | **Story Points:** 8 +- **Description:** The product reads data past the end, or before the beginning, of the intended buffer. + +### CWE-415: Double Free +- **Severity:** optional | **Story Points:** 8 +- **Description:** The product calls free() twice on the same memory address. + +### CWE-416: Use After Free +- **Severity:** mandatory | **Story Points:** 13 +- **Description:** The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory belongs to the code that operates on the new pointer. + +### CWE-672: Operation on a Resource after Expiration or Release +- **Severity:** potential | **Story Points:** 5 +- **Description:** The product uses, accesses, or otherwise operates on a resource after that resource has been expired, released, or revoked. + +### CWE-786: Access of Memory Location Before Start of Buffer +- **Severity:** optional | **Story Points:** 8 +- **Description:** The product reads or writes to a buffer using an index or pointer that references a memory location prior to the beginning of the buffer. + +### CWE-787: Out-of-bounds Write +- **Severity:** mandatory | **Story Points:** 13 +- **Description:** The product writes data past the end, or before the beginning, of the intended buffer. + +### CWE-788: Access of Memory Location After End of Buffer +- **Severity:** optional | **Story Points:** 8 +- **Description:** The product reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. + +### CWE-805: Buffer Access with Incorrect Length Value +- **Severity:** optional | **Story Points:** 8 +- **Description:** The product uses a sequential operation to read or write a buffer, but it uses an incorrect length value that causes it to access memory that is outside of the bounds of the buffer. + +### CWE-822: Untrusted Pointer Dereference +- **Severity:** optional | **Story Points:** 8 +- **Description:** The product obtains a value from an untrusted source, converts this value to a pointer, and dereferences the resulting pointer. + +### CWE-823: Use of Out-of-range Pointer Offset +- **Severity:** optional | **Story Points:** 8 +- **Description:** The product performs pointer arithmetic on a valid pointer, but it uses an offset that can point outside of the intended range of valid memory locations for the resulting pointer. + +### CWE-824: Access of Uninitialized Pointer +- **Severity:** optional | **Story Points:** 5 +- **Description:** The product accesses or uses a pointer that has not been initialized. + +### CWE-825: Expired Pointer Dereference +- **Severity:** optional | **Story Points:** 8 +- **Description:** The product dereferences a pointer that contains a location for memory that was previously valid, but is no longer valid. + +## Instructions + +1. **Iterate through each CWE rule** listed above +2. **Systematically scan** the application source code for patterns matching each rule +3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match +4. **Continue to the next rule** after finding a match or exhausting the search +5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) + +### Search Strategy + +- Start with common vulnerability patterns: user input handling, external data processing, resource management +- Check configuration files, API endpoints, data access layers, and utility classes +- Consider both direct patterns and indirect/transitive vulnerability paths +- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code + +## Output Format + +Use the `write_assessment_result` tool to save results with the following JSON structure: + +```json +{ + "input_name": "CWE - Memory Safety", + "analysis_method": "LLM", + "status": "success", + "result": { + "finding": "Assessed 15 CWE rules in Memory Safety: X FOUND, Y NOT_FOUND", + "confidence": "high", + "evidence": ["Scanned application source files for memory safety patterns"], + "values": [ + { + "id": "", + "name": "", + "status": "FOUND", + "category": "Memory Safety", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": ["src/path/to/File.java"], + "explanation": "Description of the vulnerability found, including class/method and line reference" + } + }, + { + "id": "", + "name": "", + "status": "NOT_FOUND", + "category": "Memory Safety", + "severity": "", + "storyPoint": "", + "description": "", + "evidence": { + "files": [], + "explanation": "" + } + } + ] + }, + "execution_time_seconds": 0, + "timestamp": "" +} +``` + +### Evidence Rules + +- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. +- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. +- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. +- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. +- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. +- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/data-architecture/SKILL.md b/.github/skills/data-architecture/SKILL.md new file mode 100644 index 000000000..4dd3a43d6 --- /dev/null +++ b/.github/skills/data-architecture/SKILL.md @@ -0,0 +1,227 @@ +--- +name: data-architecture +description: Generate data architecture and persistence layer documentation with data model diagram +--- + +# Data Architecture & Persistence Layer + +Analyze the project to document database configuration, entity models, data ownership boundaries, repository interfaces, and caching strategies. Generate a Mermaid ER diagram showing entity relationships. Save to `.github/modernize/assessment/engines/data-architecture.md`. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Scope Boundaries — Avoid Redundancy with Other Skills + +This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: + +- **Introduction**: Write a 1-2 sentence intro focused on the data layer (number of entities, database types, ORM). Do NOT restate the application's overall architecture type, web framework, or API surface — those are covered by other skills. +- **Configuration property keys/values** (e.g., `spring.jpa.hibernate.ddl-auto`, `spring.sql.init.*`) are owned by the `configuration-inventory` skill. In the Database Configuration table, describe the *behavior* (e.g., "Hibernate does not manage schema; SQL scripts are authoritative") but do NOT list raw property key-value pairs. Reference `configuration-inventory.md` for the full property inventory. +- **API endpoints and HTTP methods** are owned by the `api-service-contracts` skill. Do NOT list controller endpoints or HTTP paths. Repository methods are in scope for this skill; controller routes are not. +- **Business workflow steps and validation rules** are owned by the `business-workflows` skill. Do NOT describe multi-step business processes or enumerate validation constraints. When documenting entity relationships (cascade, fetch), focus on the persistence/ORM implications, not the business process flow. +- **Deployment configurations** (Docker Compose, K8s, profiles) are owned by the `configuration-inventory` skill. Mention database profiles only in the Database Configuration table to identify which DB is used per profile — do NOT describe Docker Compose services, K8s manifests, or deployment targets in detail. + +## Execution Steps + +### Step 1: Generate Database Configuration Section + +Extract database configuration from project files, **per profile/environment**, and produce the complete `## Database Configuration` section: + +- Database types: HSQLDB, MySQL, PostgreSQL, MongoDB, SQL Server, Oracle, SQLite, CosmosDB, DynamoDB +- **Per-profile configuration**: identify which database is used in each profile (e.g., HSQLDB for `default`/dev in-memory testing, MySQL for `production`/`mysql` profile) +- Database drivers per profile (e.g., `mysql-connector-java` for production, `hsqldb` for development) +- Connection configuration: connection strings, JDBC URLs, pooling settings (HikariCP, connection pool size) +- Migration tools: Flyway, Liquibase, EF Migrations, Alembic, Prisma Migrate, Knex migrations +- Schema management: DDL auto-generation settings (`spring.jpa.hibernate.ddl-auto`), schema versioning, initial schema scripts +- Seed data: `data.sql`, `import.sql`, seed migration files, or programmatic data seeding + +### Step 2: Generate Data Ownership per Service Section + +Determine table/entity ownership across modules/services and produce the complete `## Data Ownership per Service` section. Scope is strictly the per-service ownership table — high-level data boundary discussion belongs in Step 6. + +For each module/service, identify: + +- Which tables/entities it owns (bounded context analysis) +- ORM framework used (e.g., Hibernate, EF Core, MyBatis, Mongoose) +- Caching layer used by this service (if any) +- Brief notes (e.g., outbox table, schema-per-service) + +> Do NOT include shared-vs-isolated data store summary, cross-service data access patterns, or read/write/CQRS observations here — those belong in the `## Data Ownership Boundaries` section (Step 6). + +### Step 3: Generate Entity Model Section + +Scan source code for data access patterns and ORM entities, then produce the complete `## Entity Model` section: + +**Analysis:** +- Java: JPA/Hibernate entities (`@Entity`, `@Table`), Spring Data repositories (`JpaRepository`, `CrudRepository`), MyBatis mappers, JDBC templates +- .NET: EF Core `DbContext`, EF Core entities, Dapper, ADO.NET +- JavaScript/TypeScript: Mongoose models/schemas, Sequelize models, TypeORM entities, Prisma schema, Knex migrations + +Identify: +- Entity/model classes with their fields, types, and constraints — note the source file path for each entity +- Transaction management annotations/configuration (`@Transactional`, `TransactionScope`, etc.) +- Bidirectional vs unidirectional relationship mappings (e.g., `owner.addPet(pet)` establishing parent-child links) + +**Diagram — Mermaid `erDiagram`:** +- Show primary entities with key fields (PK, FK) +- Use standard cardinality notation: `||--o{` (one-to-many), `||--||` (one-to-one), `}o--o{` (many-to-many) +- Group related entities logically +- Include relationship labels +- Annotate which service owns each entity group (use comments or subgraph labels) + +Example: + +~~~mermaid +erDiagram + Owner ||--o{ Pet : "has" + Pet ||--o{ Visit : "has" + Pet }o--|| PetType : "is of" + Vet }o--o{ Specialty : "has" + Owner { + int id PK + string firstName + string lastName + string address + string city + string telephone + } + Pet { + int id PK + string name + date birthDate + int ownerId FK + int typeId FK + } + PetType { + int id PK + string name + } + Visit { + int id PK + int petId FK + date visitDate + string description + } + Vet { + int id PK + string firstName + string lastName + } + Specialty { + int id PK + string name + } +~~~ + +### Step 4: Generate Key Repository Methods Section + +For each service/module, document the key repository interfaces and produce the complete `## Key Repository Methods` section: + +- Repository interface name, entity type, and source file path +- Standard CRUD methods inherited from base interface +- Custom query methods with their signatures and purposes — especially: + - Bulk/batch queries (e.g., `findByPetIdIn(Collection)`) used for cross-service aggregation + - Custom finders with derived query methods + - Named queries or `@Query`-annotated methods + - Raw SQL or stored procedure calls +- Query method parameters and return types + +### Step 5: Generate Caching Strategy Section + +Identify caching layers and configuration and produce the complete `## Caching Strategy` section: + +- Cache providers: EhCache, Redis, Caffeine, Spring Cache (`@Cacheable`, `@CacheEvict`), MemoryCache, IDistributedCache +- Cache configuration: TTL, eviction policies, cache regions/names +- Cache-aside, read-through, write-through, write-behind patterns +- Session caching, query result caching, second-level cache (Hibernate) +- Rationale for caching decisions (e.g., "veterinarian data is read frequently but changes rarely") +- JSR-107 (JCache) / `cache-api` usage and provider binding + +### Step 6: Generate Data Ownership Boundaries Section + +Document data-store topology and cross-service access semantics, plus data classification, then produce the complete `## Data Ownership Boundaries` section (including the `### Data Classification & Sensitivity` subsection): + +**Boundaries:** +- Shared vs isolated data stores (shared database, database-per-service, logical separation within shared DB) +- Cross-service data access patterns: how one service queries another service's data (direct DB access vs REST API calls vs batch/bulk query methods such as `findByPetIdIn(...)` that enable gateway-level aggregation) +- Read/write patterns and CQRS observations across services + +**Data Classification & Sensitivity (`### Data Classification & Sensitivity` subsection):** +- Identify whether stored data contains sensitive categories — PII (names, addresses, phone numbers, emails), PHI (health records), PCI (payment card data) +- For each sensitive category found, note whether encryption-at-rest, data masking, or field-level access controls are in place +- If absent, state this explicitly (e.g., "Owner entity stores PII (firstName, lastName, address, telephone); no encryption-at-rest or masking configured") + +### Step 7: Save Output + +Save to `.github/modernize/assessment/engines/data-architecture.md` with this exact structure: + +``` +# Data Architecture & Persistence Layer + +A brief introduction (1-2 sentences) summarizing the data layer. + +## Database Configuration + +[Table: Service/Module | DB Type | Profile | Driver | Connection | Migration Tool] + +## Data Ownership per Service + +[Table: Service | Tables Owned | ORM Framework | Caching | Notes] + +## Entity Model + +< Mermaid erDiagram here > + +## Key Repository Methods + +[Table: Service | Repository | Notable Methods | Purpose] + +## Caching Strategy + +[Table or description of caching layers, providers, TTL, patterns, and rationale] + +## Data Ownership Boundaries + +[Description of shared vs isolated data stores, cross-service data access patterns, and aggregation enablers] + +### Data Classification & Sensitivity + +[Table: Entity | Sensitive Fields | Classification (PII/PHI/PCI/None) | Controls in Place] +[If no sensitive data found: "No PII, PHI, or PCI data detected in entity model."] +``` + +## Scaling Rules + +- If the project has **more than 30 entities**, aggregate minor entities and show only the core domain model (15-20 key entities) +- Keep the ER diagram under **40 entities** to ensure readability and GitHub rendering compatibility +- For multi-module projects, focus on inter-module entity relationships and data boundaries +- Collapse join tables into relationship annotations rather than showing them as separate entities +- In the repository methods table, focus on non-CRUD custom methods; omit standard inherited methods + +## Mermaid Syntax Rules + +- Use `erDiagram` +- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in entity/field names — use plain text +- Use standard cardinality: `||--o{`, `||--||`, `}o--o{`, `|o--o{` +- Use quoted relationship labels: `Owner ||--o{ Pet : "has"` +- Do not use backticks inside entity or field names +- **Never put `{` or `}` inside a quoted attribute description or relationship label.** Mermaid's ER parser treats `{` as the entity-body opener even inside quotes, which crashes the entire diagram with "Syntax error in text". Avoid placeholder syntax like `{userId}`, `{path}`, or `{id}` in attribute comments — write `userId`, `path`, `id` (or describe in plain words: "indexed by user id"). Example: + - ❌ `string Key PK "Redis key /basket/{BuyerId}"` + - ✅ `string Key PK "Redis key /basket/"` or `"Redis key prefixed with /basket/"` + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No data access layer found**: Output: `> ERROR: No recognized data access patterns or entities found at {workspace-path}. Verify the path is correct.` +- **Insufficient info**: Generate a best-effort diagram from available data. Add a note: `> Note: Some entities or relationships could not be fully identified.` + +## Success Criteria + +- Database configuration table lists all discovered databases with type, profile, driver, and migration tools +- Data ownership table maps each service to its owned tables, ORM, and caching layer +- Mermaid ER diagram renders correctly showing entity relationships with cardinality and key fields +- Repository methods table documents custom query methods with purposes, especially cross-service aggregation enablers +- Caching strategy section describes cache providers, patterns, and rationale +- Data ownership boundaries describe shared vs isolated stores and cross-service data access patterns +- Data Classification & Sensitivity table identifies PII/PHI/PCI fields and documents presence or absence of controls +- File saved to `.github/modernize/assessment/engines/data-architecture.md` diff --git a/.github/skills/dependency-map/SKILL.md b/.github/skills/dependency-map/SKILL.md new file mode 100644 index 000000000..60a929e78 --- /dev/null +++ b/.github/skills/dependency-map/SKILL.md @@ -0,0 +1,180 @@ +--- +name: dependency-map +description: Generate dependency map diagram from project build files +--- + +# Dependency Map + +Analyze project build and package files to generate a visual map of all external dependencies grouped by functional category. Save to `.github/modernize/assessment/engines/dependency-map.md`. + +This skill focuses exclusively on **declared external dependencies** (libraries, frameworks, packages). For internal application structure and component relationships, see the `architecture-diagram` skill. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Execution Steps + +### Step 1: Generate Dependencies Section + +Analyze build files and produce the complete `## Dependencies` section in one pass: + +**Analysis — examine only build and package management files** (do NOT scan source code — that is the `architecture-diagram` skill's job): + +- Java: pom.xml, build.gradle, settings.gradle, gradle.properties, gradle lockfiles +- .NET: *.csproj, Directory.Build.props, packages.config, Directory.Packages.props +- JavaScript/TypeScript: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml + +For each dependency extract: +- Group/package name and artifact name +- Declared version (or version range) +- Scope (compile, runtime, test, provided) + +Also detect: +- Parent POM / BOM imports (Java) +- Central package management (.NET Directory.Packages.props) +- Transitive dependencies where visible from lock files or BOM + +**Categorize** dependencies into functional groups: + +| Category | Examples | +|----------|----------| +| Web Frameworks | Spring Web, ASP.NET Core MVC, JAX-RS | +| Database / ORM | Hibernate, Entity Framework, JDBC drivers | +| Messaging | Kafka client, RabbitMQ, Azure Service Bus | +| Caching | Redis, EhCache, MemoryCache | +| Logging | SLF4J, Log4j, Serilog, NLog | +| Security | Spring Security, Microsoft.Identity, OAuth libs | +| Observability | Micrometer, OpenTelemetry, Application Insights | +| Utilities | Guava, Apache Commons, Lombok, AutoMapper | + +Rules: +- Exclude test-scoped dependencies (JUnit, xUnit, Mockito, etc.) from the main diagram and Dependency Summary table — they are not relevant for modernization planning +- If a dependency doesn't fit any category, put it under "Utilities" +- Collect test-scoped dependencies separately for the Test Dependencies section (Step 2) + +**Diagram — Mermaid `flowchart LR`:** +- Application as the central left-side node +- One `subgraph` per functional category +- Each dependency as a node showing name and version: `Lib["Library Name v1.2.3"]` +- Arrows from Application to each category subgraph +- If a BOM/parent POM manages versions, show it as a separate node linked to the dependencies it governs + +Example: + +~~~mermaid +flowchart LR + App["MyApplication"] + + subgraph Web["Web Frameworks"] + SpringMVC["Spring MVC 5.3.x"] + Thymeleaf["Thymeleaf 3.0"] + end + subgraph DB["Database / ORM"] + Hibernate["Hibernate 5.6"] + PgDriver["PostgreSQL Driver 42.6"] + end + subgraph Messaging + Kafka["Kafka Client 3.4"] + end + subgraph Cache["Caching"] + Redis["Jedis 4.3"] + end + subgraph Log["Logging"] + SLF4J["SLF4J 1.7"] + Logback["Logback 1.2"] + end + subgraph Sec["Security"] + SpringSec["Spring Security 5.7"] + end + subgraph Util["Utilities"] + Lombok["Lombok 1.18"] + Jackson["Jackson 2.14"] + end + + App -->|"web"| Web + App -->|"persistence"| DB + App -->|"messaging"| Messaging + App -->|"caching"| Cache + App -->|"logging"| Log + App -->|"security"| Sec + App -->|"utilities"| Util + SLF4J -.->|"implementation"| Logback +~~~ + +**Textual explanations (write immediately after the diagram):** +- **Dependency Summary table**: Category | Count | Key Libraries | Notes (e.g., Web Frameworks | 2 | ASP.NET MVC 5.2.7, Razor 3.2.7 | Legacy MVC stack on .NET Framework) +- **Version & Compatibility Risks**: A short paragraph highlighting dependencies that are outdated, end-of-life, or have known migration concerns (e.g., ".NET Framework 4.7.2 is in maintenance mode; Entity Framework 6 has a migration path to EF Core") +- **Notable Observations**: 2-4 bullet points on anything noteworthy — duplicate functionality across libraries, deprecated packages, security-sensitive dependencies, or unusually large transitive trees + +### Step 2: Generate Test Dependencies Section + +Collect all test-scoped dependencies (excluded from the main diagram) and produce the complete `## Test Dependencies` section: + +- List detected test frameworks and supporting libraries with their versions (e.g., JUnit 5, Mockito, AssertJ, Testcontainers, xUnit, Jest) +- Report the total number of test-scope dependencies +- Note any test infrastructure concerns (e.g., outdated test framework version, missing contract-testing library, no integration test framework detected) + +### Step 3: Save Output + +Save to `.github/modernize/assessment/engines/dependency-map.md` with this exact structure: + +``` +# Dependency Map + +A brief introduction (1-2 sentences) stating project name and total dependency count. + +## Dependencies + +< Mermaid flowchart LR here > + +### Dependency Summary + +[Table: Category | Count | Key Libraries | Notes] + +### Version & Compatibility Risks + +[Short paragraph on outdated or end-of-life dependencies] + +### Notable Observations + +[2-4 bullet points on noteworthy findings] + +## Test Dependencies + +[Table: Framework | Version | Notes] + +Total test-scope dependencies: N +[1-2 sentences on test infrastructure observations, or "No test dependencies detected."] +``` + +## Scaling Rules + +- If the project has **more than 50 declared dependencies**, collapse minor utilities into a single aggregate node (e.g., `Utils["12 utility libraries"]`) and only show individually the top dependencies by importance +- Keep the diagram under **40 nodes** to ensure readability and GitHub rendering compatibility +- For multi-module projects (e.g., multi-module Maven/Gradle, multi-project .sln), show shared dependencies once and module-specific dependencies grouped by module + +## Mermaid Syntax Rules + +- Use `flowchart LR` +- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in node labels — use plain text +- Always quote arrow labels with double quotes: `-->|"label"|` +- Use `subgraph` for grouping, with a display name in quotes if it contains spaces +- Use `-.->` (dotted arrow) for transitive/indirect relationships +- Verify all node IDs are unique across the entire diagram + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No build files found**: Output: `> ERROR: No recognized build files found at {workspace-path}. Verify the path is correct.` +- **Incomplete dependency info**: Generate a best-effort diagram from available data. Add a note inside the diagram: `Note["Some dependencies could not be fully resolved"]` + +## Success Criteria + +- Mermaid diagram renders correctly with dependencies grouped by functional category +- Each dependency shows name and version +- Dependency Summary table lists categories with counts and key libraries +- Version & Compatibility Risks paragraph highlights outdated or end-of-life dependencies +- Notable Observations lists 2-4 noteworthy findings +- Test Dependencies section lists detected test frameworks with versions and total count +- File saved to `.github/modernize/assessment/engines/dependency-map.md` diff --git a/.github/skills/execute-java-upgrade-task/SKILL.md b/.github/skills/execute-java-upgrade-task/SKILL.md new file mode 100644 index 000000000..d605768ee --- /dev/null +++ b/.github/skills/execute-java-upgrade-task/SKILL.md @@ -0,0 +1,376 @@ +--- +name: execute-java-upgrade-task +description: Execute a Java upgrade task as part of a modernization plan +--- + +You are an expert Java upgrade agent. **Task**: Upgrade to user-specified target versions by (1) generating an incremental plan and (2) executing it per the rules below. + +You MUST generate the upgrade plan and execute it by yourself following the rules and workflow. You are now in the "modernize-java" agent. You MUST NOT call `#generate-upgrade-plan` or `#redirect-to-upgrade-agent` again as it will redirect to you, causing an infinite loop. + +## Rules + +### Upgrade Success Criteria (ALL must be met) + +- **Goal**: All user-specified target versions met. +- **Compilation**: Both main source code AND test code compile successfully = `mvn clean test-compile` (or equivalent) succeeds. This includes compiling production code and all test classes. +- **Test**: **100% test pass rate** = `mvn clean test` succeeds. Minimum acceptable: test pass rate ≥ baseline (pre-upgrade pass rate). Every test failure MUST be fixed unless proven to be a pre-existing flaky test (documented with evidence from baseline run). **Skip if user set "Run tests before and after the upgrade: false" in plan.md Options.** + +### Anti-Excuse Rules (MANDATORY) + +- **NO premature termination**: Token limits, time constraints, or complexity are NEVER valid reasons to skip fixing test failures. +- **NO "close enough" acceptance**: 95% is NOT 100%. Every failing test requires a fix attempt with documented root cause. +- **NO deferred fixes**: "Fix post-merge", "TODO later", "can be addressed separately" are NOT acceptable. Fix NOW or document as a genuine unfixable limitation with exhaustive justification. +- **NO categorical dismissals**: "Test-specific issues", "doesn't affect production", "sample/demo code", "non-blocking" are NOT valid reasons to skip fixes. ALL tests must pass. +- **NO blame-shifting**: "Known framework issue", "migration behavior change", "infrastructure problem" require YOU to implement the fix or workaround, not document and move on. +- **Genuine limitations ONLY**: A limitation is valid ONLY if: (1) multiple distinct fix approaches were attempted and documented, (2) root cause is clearly identified, (3) fix is technically impossible without breaking other functionality. + +### Review Code Changes (MANDATORY for each step) + +After completing changes in each step, review code changes per the rules in `progress.md` templates BEFORE verification. Key areas: + +- **Sufficiency**: all required upgrade changes are present +- **Necessity**: no CRITICAL unnecessary changes — Unnecessary changes that do not affect behavior may be retained; however, it is essential to ensure that the functional behavior remains consistent and security controls are preserved. + +### Upgrade Strategy + +- **Incremental upgrades**: Stepwise dependency upgrades; use intermediates to avoid large jumps breaking builds. +- **Minimal changes**: Only upgrade dependencies essential for compatibility with target versions. +- **Risk-first**: Handle EOL/challenging deps early in isolated steps. +- **Necessary/Meaningful steps only**: Each step MUST change code/config. NO steps for pure analysis/validation. Merge small related changes. **Test**: "Does this step modify project files?" +- **Automation tools**: Use automation tools like OpenRewrite etc. for efficiency; always verify output. +- **Successor preference**: Compatible successor > Adapter pattern > Code rewrite. +- **Build tool compatibility**: Check Maven/Gradle version compatibility with the target JDK. Upgrade the build tool (including wrapper) if the current version does not support the target JDK. Common minimum versions: Maven 3.9+ / Gradle 8.5+ for Java 21, Maven 4.0+ / Gradle 9.1+ for Java 25. When a wrapper (`mvnw`/`gradlew`) is present, also upgrade the wrapper-defined version in `.mvn/wrapper/maven-wrapper.properties` or `gradle/wrapper/gradle-wrapper.properties`. +- **Temporary errors OK**: Steps may pass with known errors if resolved later or pre-existing. + +### Execution Guidelines + +- **Wrapper preference**: Use Maven Wrapper (`mvnw`/`mvnw.cmd`) or Gradle Wrapper (`gradlew`/`gradlew.bat`) when present in the project root, unless user explicitly specifies otherwise. This ensures consistent build tool versions across environments. +- **Version control via tool**: 🛑 NEVER use direct `git` commands in terminal — ONLY use `#version-control` for ALL version control operations (check status, create branch, commit, stash, discard changes). **ALWAYS pass `sessionId: `** to every `#version-control` call for telemetry tracking. When `GIT_AVAILABLE=false` (git not installed or project is not a git repository), skip ALL version control operations. Files remain uncommitted in the working directory. Use `N/A` for `` and `` placeholders. Record a notice in `plan.md` that changes are not version-controlled during this upgrade. +- **Version control timing**: `#version-control` requires `SESSION_ID` which is only available after Phase 1 (Precheck) succeeds. Do NOT use `#version-control` during Precheck. Git availability detection is deferred to Phase 2 Initialize. +- **Template compliance**: For `plan.md`, follow the **Plan Format Specification** below and write the complete file in a **single `create_file` call** — do NOT read a template or use `insert_edit_into_file` during plan generation. For `progress.md` and `summary.md`, follow the rules and samples in each section's HTML comments of the template files. +- **Uninterrupted run**: Complete each phase fully without pausing for user input, except for the mandatory user confirmation after plan generation (Phase 3). +- **User input**: Prefer `#askQuestions` tool when available to collect user input (e.g., choices, confirmations). Fall back to plain-text prompts only when `#askQuestions` is unavailable. + +### Event Reporting (MANDATORY) + +Call `#report-event` immediately at each key milestone. **NO skipping. NO batching. This is non-negotiable.** + +- **When**: Report at every milestone defined in the Workflow phases — do not wait until the end of a phase. +- **Details**: Pass `details` for `precheckCompleted` (on both success and failure — see Phase 1), `environmentSetup`, `upgradeStepStarted`, and `upgradeStepCompleted`. +- **Status values**: `"succeeded"` | `"failed"` (must include `message`) | `"skipped"` (must include `message`). +- **SILENT**: Event reporting is internal telemetry only — NEVER mention `#report-event` calls, event names, or reporting status in user-facing messages. + +### Efficiency + +- **Targeted reads**: Use `grep` over full file reads; read sections, not entire files. +- **Quiet commands**: Use `-q`, `--quiet` for build/test when appropriate. +- **Single write for plan.md**: Generate the complete `plan.md` in one `create_file` call after gathering all information. Do NOT make multiple edits. +- **Incremental writes for progress.md**: Update `progress.md` incrementally as steps complete. + +### Session ID Consistency (CRITICAL) + +- `SESSION_ID` is generated in Phase 1 (Precheck) on success. Use this **exact** ID for ALL subsequent tool calls — never fabricate or change it. + +### Intermediate Version Strategy + +Use intermediates **when direct upgrade risks breaking builds**. A good intermediate has: + +- **Stability**: Stable LTS release with production track record +- **Compatibility bridge**: Bridges compatibility between current deps AND intermediates of other deps + +**Example**: Spring Boot 2.7.x is an effective intermediate for `Spring Boot 1.x → 3.x` because: + +- Final stable 2.x release (stability ✓) +- Supports Java 8-21 (wide compatibility range ✓) +- Uses javax.servlet (compatible with 1.x/2.x) with migration path to jakarta (3.x) ✓ + +Consider dependencies holistically — use target framework/Java as reference for intermediates. + +### Version Knowledge + +LLM training data may be outdated regarding the latest Java and Spring Boot releases. **Never reject a target version solely based on training data knowledge.** + +1. **Known stable/LTS versions to suggest by default** (non-exhaustive — newer stable or LTS releases may exist beyond this list): + - Java LTS: 11, 17, 21, 25 + - Spring Boot stable release lines: 2.7.x, 3.5.x, 4.0.x +2. **When the user requests a version you don't recognize**: Your training data may be stale. Use the `fetch` tool to verify the latest release information from the web before making any judgment. Only reject a version as invalid if the web lookup confirms it does not exist. Never reject based solely on training data. + +## Plan Format Specification + +When writing `plan.md`, generate the **complete file** in a single `create_file` call to `.github/java-upgrade//plan.md`. Follow this exact structure: + +### Plan Header + +```markdown +# Upgrade Plan: () + +- **Generated**: +- **HEAD Branch**: +- **HEAD Commit ID**: +``` + +### Section: Available Tools + +List ONLY the JDKs and build tools required/used during the upgrade (not all discovered ones). Use `#list-jdks` and `#list-mavens` results to check availability. Mark missing required JDKs as `****` with a note indicating which step needs it. **Exception — base (current) JDK**: If the project's current JDK version is not found, do NOT mark it as ``. The base JDK is only needed for the optional baseline step; if the user doesn't have it, baseline will be skipped. Note it as "not available (baseline will be skipped)". Mark build tools needing upgrade as `****`. If a wrapper is present, check the wrapper-defined version in `.mvn/wrapper/maven-wrapper.properties` or `gradle/wrapper/gradle-wrapper.properties`. Installation/upgrade happens during execution, not planning. + +**Build tool compatibility reference** (non-exhaustive — verify from official docs when uncertain): +- Maven 3.9+: required for Java 21 +- Maven 4.0+: required for Java 25 +- Gradle 8.5+: required for Java 21 +- Gradle 8.8+: required for Java 22 +- Gradle 9.1+: required for Java 25 +- maven-compiler-plugin 3.11+: required for Java 21 +- maven-surefire-plugin 3.1+: recommended for Java 17+ + +This section is finalized during Design & Review (after step sequence is known), not during Initialize & Analyze. + +Sample: +```markdown +## Available Tools + +**JDKs** +- JDK 1.8.0: /path/to/jdk-8 (current project JDK, used by step 2) +- JDK 17: **** (required by step 3) +- JDK 21: **** (required by step 6) + +**Build Tools** +- Maven 3.9.6: /path/to/maven +- Maven Wrapper: 3.8.1 → **** to 3.9.6+ (current version incompatible with Java 21) +``` + +### Section: Guidelines + +User-specified guidelines or constraints in bullet points. Extract from user's prompt if provided, or leave empty. + +Always include this user-facing note: +```markdown +> Note: You can add any specific guidelines or constraints for the upgrade process here if needed, bullet points are preferred. +``` + +### Section: Options + +```markdown +## Options + +- Working branch: appmod/java-upgrade- +- Run tests before and after the upgrade: true +``` + +These are user-configurable options. Never remove them. + +### Section: Upgrade Goals + +List ONLY user-requested target versions. These drive all other decisions. + +### Section: Technology Stack + +Table of core dependencies and compatibility with upgrade goals. Analyze ALL modules in multi-module projects. Only include direct dependencies + those critical for upgrade compatibility. Flag EOL dependencies with "⚠️ EOL" suffix. Include build tools and plugins. + +Columns: Technology/Dependency | Current | Min Compatible Version | Why Incompatible + +Sample: +```markdown +| Technology/Dependency | Current | Min Compatible | Why Incompatible | +| ------------------------ | ------- | -------------- | ---------------------------------------------- | +| Java | 8 | 21 | User requested | +| Spring Boot | 2.5.0 | 3.2.0 | User requested | +| Maven (wrapper) | 3.6.3 | 3.9.0 | Maven 3.6.x does not support Java 21 | +| maven-compiler-plugin | 3.8.1 | 3.11.0 | Older versions cannot compile Java 21 bytecode | +| javax.servlet ⚠️ EOL | 4.0 | N/A | Replaced by jakarta.servlet in Spring Boot 3.x | +| Lombok | 1.18.20 | 1.18.20 | - | +``` + +### Section: Derived Upgrades + +Required upgrades inferred from user targets based on compatibility rules. Each must have justification. + +Common derivations: +- Spring Boot 3.x → Java 17+, Jakarta EE 9+, Hibernate 6.x, Spring Framework 6.x +- Spring Boot 3.2+ → Spring Framework 6.1+ +- Spring Boot 4.x → Java 17+, Jakarta EE 10+, Spring Framework 7.x +- Java 21 → Maven 3.9+, Gradle 8.5+, maven-compiler-plugin 3.11+ +- Java 25 → Maven 4.0+, Gradle 9.1+ +- Build tool upgrade → update wrapper version + +### Section: Upgrade Steps + +Step format: +```markdown +- Step N: + - **Rationale**: Why this step is needed and why at this position + - **Changes to Make**: ≤5 bullet points (concise) + - **Verification**: Command, JDK, Expected Result +``` + +**Verification expectations:** +- Steps 1-N (Setup/Upgrade): Focus on COMPILATION SUCCESS. Tests may fail during intermediate steps. +- Final step: COMPILATION SUCCESS + TEST PASS (if tests enabled in Options) through iterative fix loop. + +**Mandatory steps:** + +- **Step 1 (MANDATORY)**: Setup Environment — Install required JDKs/build tools marked `` (do NOT install the base JDK if it is unavailable — it is only needed for the optional baseline). Verify with `#list-jdks`. Expected: All required JDKs available. +- **Step 2 (MANDATORY)**: Setup Baseline — If the base (current) JDK is available, run baseline compilation and tests with current JDK. Command: `mvn clean compile test-compile -q && mvn clean test -q`. Document SUCCESS/FAILURE, test pass rate (forms acceptance criteria). **If the base JDK is not available, skip this step** with status `"skipped"` and proceed to upgrade steps. +- **Steps 3-N**: Upgrade steps — dependency order, high-risk early, isolated breaking changes. Verify with `mvn clean test-compile -q` (compile only). +- **Final step (MANDATORY)**: Final Validation — Verify all goals met, resolve ALL TODOs and workarounds, clean rebuild with target JDK, run full test suite and fix ALL failures (iterative fix loop until 100% pass). Skip tests if disabled in Options. **For files flagged by the JDK source-code compatibility scan that lack test coverage, "compile + test pass" is NOT sufficient** — either (a) apply the deterministic rewrite as part of an upgrade step, or (b) document the residual runtime risk in `summary.md` Key Risks. Do not silently ship a latent JDK-version runtime bug. + +### Section: Key Challenges + +High-risk areas requiring special attention. Each with mitigation strategy. + +Sample: +```markdown +- **Jakarta EE Namespace Migration** + - **Challenge**: Codebase uses javax.* packages that must migrate to jakarta.* in Spring Boot 3+. + - **Strategy**: Use OpenRewrite migration recipes after Spring Boot 2.7.x intermediate. +``` + +## Workflow + +### Phase 1: Precheck + +| Category | Scenario | Action (use `#askQuestions` tool when available and appropriate) | +| ------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Unsupported Project | Not a Java project | This path should not be reached — the upgrade agent is only invoked for Java projects. Do NOT call `#report-event`. Simply STOP and inform the user: "This project does not appear to be a Java project. The Java upgrade agent only supports Java projects." | +| Unsupported Project | Not a Maven/Gradle project | Check for alternative build systems: look for `build.xml` (Ant), `BUILD`/`BUILD.bazel` (Bazel), or other build files. If detected, call `#report-event` with details, then inform the user: "Detected [Ant/Bazel/other] build system. Maven and Gradle are fully supported; [Ant/Bazel/other] support is experimental and results may vary." Attempt to continue with best-effort analysis. If no recognizable build system is found, call `#report-event`, then STOP with error listing supported build systems (Maven, Gradle). | +| Invalid Goal | Missing target version | Do NOT call `#report-event` yet. Instead, analyze project dependencies (read `pom.xml`/`build.gradle` to detect current Java version, Spring Boot version, and other key deps), derive feasible upgrade options (e.g., Java 17, Java 21, Java 25, Spring Boot 3.2, Spring Boot 3.5, Spring Boot 4.0), and use `#askQuestions` to present those options as selectable choices for the user to pick the desired target(s). Only report `precheckCompleted` (succeeded or failed) after the user has selected a target or the interaction concludes. | +| Invalid Goal | Incompatible target combination | Call `#report-event`, then STOP and explain incompatibility | + +**On failure**: → `#report-event(event: "precheckCompleted", phase: "precheck", status: "failed", details: {category: "", scenario: ""}, message: "")` — **Call this FIRST** before stopping or asking users. Pass the failed category (e.g., "Unsupported Project", "Invalid Goal") and scenario from the table above. **IMPORTANT**: `details.category` and `details.scenario` are **REQUIRED** when status is "failed" — the tool will reject the call without them. **Exception**: For the "Missing target version" scenario, do NOT report failure immediately — interact with the user first (see table above) and only report `precheckCompleted` (succeeded or failed) after the user has selected a target or the interaction concludes. + +**On success**: → `#report-event(event: "precheckCompleted", phase: "precheck", status: "succeeded", details: {baseJdkVersion: "", targetVersion: ""})` — **This generates a new `SESSION_ID`. Use this `SESSION_ID` for all subsequent tool calls.** + +### Phase 2: Generate Upgrade Plan + +#### 1. Initialize & Analyze + +1. Call tool `#report-event(sessionId, event: "planGenerationStarted", phase: "plan", status: "succeeded")` — **FIRST action, before any file or version control operations** +2. **Detect version control availability**: Use `#version-control(sessionId: , workspacePath, action: "checkStatus")` to detect if git is available. If the response indicates version control is unavailable, set `GIT_AVAILABLE=false`. **Do not ask the user. Do not report failure.** +3. If `GIT_AVAILABLE=true`: Use `#version-control(sessionId: , workspacePath, action: "stashChanges", stashMessage: "java-upgrade-precheck-")` to stash any uncommitted changes. +4. Extract user-specified guidelines from prompt (bulleted list; leave empty if none) +5. Detect all available JDKs/build tools via `#list-jdks(sessionId)`, `#list-mavens(sessionId)`; record discovered versions and paths +6. Detect wrapper presence; if wrapper exists, read wrapper properties file (`.mvn/wrapper/maven-wrapper.properties` or `gradle/wrapper/gradle-wrapper.properties`) to determine the wrapper-defined build tool version +7. Check build tool version compatibility with target JDK — flag incompatible versions +8. Identify core tech stack across **ALL modules** (direct deps + upgrade-critical deps) +9. Include build tool (Maven/Gradle) and build plugins (`maven-compiler-plugin`, `maven-surefire-plugin`, `maven-war-plugin`, etc.) in the technology stack analysis — these are upgrade-critical even though they are not runtime dependencies +10. Flag EOL dependencies (high priority for upgrade) +11. Determine compatibility against upgrade goals +12. **JDK source-code compatibility scan**: For each JDK version jump in the upgrade goals (e.g., 8 → 17 → 21), grep `src/**/*.java` (and other JVM-language sources) for source-level incompatibilities introduced by the JDK jump itself — i.e., code that compiles on the source JDK but breaks at compile or runtime on the target JDK because the language/JDK behavior changed. This is a curated, version-jump-driven scan, NOT a general SAST. In-scope pattern catalog: + - **Reflection into `java.base`**: `getDeclaredField`/`getDeclaredMethod` against `java.lang.*`, `java.util.*`, `java.nio.*`, etc. followed by `setAccessible(true)` → JDK 9+ illegal-access warning, JDK 17+ `InaccessibleObjectException` (strong encapsulation). + - **Internal/encapsulated package imports**: `sun.misc.*`, `sun.reflect.*`, `sun.nio.ch.*`, `jdk.internal.*` → JDK 9+ encapsulated/removed. + - **Removed or terminally deprecated APIs used by the project** (filter to those affecting the target version): e.g., `Thread.stop()`, `Thread.destroy()`, `Class.newInstance()` (deprecated 9+), `SecurityManager` use (deprecated 17, disabled 21+), `Object.finalize()` overrides. + - **JDK-removed modules requiring an explicit dependency** at the target version (JDK 11+): `javax.xml.bind` (JAXB), `javax.activation`, `javax.annotation`, `javax.transaction`, CORBA — flag for explicit dependency add. (Note: distinct from framework migrations like `javax.servlet` → `jakarta.servlet`, which are already handled by the Technology Stack analysis.) + +#### 2. Design & Review + +1. For incompatible deps in the Technology Stack, prefer: Replacement > Adaptation > Rewrite +2. Determine intermediate versions needed (see **Intermediate Version Strategy**) +3. Finalize Available Tools based on the planned step sequence; determine which JDK versions are required and at which steps; mark missing ones as ``, mark build tools needing upgrade as `` (including wrapper version if applicable). **Exception — base (current) JDK**: If the project's current JDK version is not found via `#list-jdks`, do **not** mark it as ``. The base JDK is only needed for the optional baseline step. Instead, note it as "not available (baseline will be skipped)". +4. Design step sequence: + - **Step 1 (MANDATORY)**: Setup Environment - Install all JDKs/build tools marked `` (do NOT install the base JDK if it is unavailable — it is only needed for the optional baseline) + - **Step 2 (MANDATORY)**: Setup Baseline - If the base (current) JDK is available, stash changes via `#version-control(sessionId: )` (if version control available), run compile/test with current JDK, document results. **If the base JDK is not available, skip this step**: report `#report-event(sessionId, event: "baselineSetup", phase: "execute", status: "skipped", message: "Base JDK not available — baseline skipped")` and proceed directly to the upgrade steps. + - **Steps 3-N**: Upgrade steps - dependency order, high-risk early, isolated breaking changes. Compilation must pass (both main and test code); test failures documented for Final Validation. + - **Final step (MANDATORY)**: Final Validation - verify all goals met, all TODOs resolved, achieve **Upgrade Success Criteria** through iterative test & fix loop (if tests are enabled). Rollback on failure after exhaustive fix attempts. +5. Identify high-risk areas for Key Challenges. **All JDK source-code compatibility scan findings from Initialize & Analyze step 12 must be included** — each as a Key Challenge entry with `file:line`, the JDK version it breaks at, and the recommended fix; deterministic rewrites must also be reflected as concrete changes inside the relevant upgrade step. +6. **Write complete `plan.md`** to `.github/java-upgrade//plan.md` using `create_file` — follow the **Plan Format Specification** above. Include all sections (Available Tools, Guidelines, Options, Upgrade Goals, Technology Stack, Derived Upgrades, Upgrade Steps, Key Challenges) in a single write. If `GIT_AVAILABLE=false`, use "N/A" for branch/commit and include a notice about version control. +7. Verify all placeholders are filled, check for missing coverage/infeasibility/limitations. If issues found, rewrite the file. +8. Call tool `#report-event(sessionId, event: "planReviewed", phase: "plan", status: "succeeded")` + +### Phase 3: Confirm Plan with User (MANDATORY) + +1. Call tool `#confirm-upgrade-plan(sessionId)` — awaits user confirmation +2. Call tool `#report-event(sessionId, event: "planConfirmed", phase: "plan", status: "succeeded")` + +### Phase 4: Execute Upgrade Plan + +#### 1. Initialize + +1. Read `.github/java-upgrade//plan.md` for "Options" +2. Use `#version-control(sessionId: , workspacePath, action: "stashChanges")` to stash any uncommitted changes. Then use `#version-control(sessionId: , workspacePath, action: "createBranch", branchName: "appmod/java-upgrade-")` (or the branch defined in `plan.md`). If version control is unavailable (`GIT_AVAILABLE=false`), log warning in `plan.md` that changes are not version-controlled. +3. Update `.github/java-upgrade//progress.md`: + - Replace ``, `` and timestamp placeholders + - Create step entries for each step in `plan.md` (per **Template compliance** rule) +4. Call tool `#report-event(sessionId, event: "planExecutionStarted", phase: "execute", status: "succeeded")` + +#### 2. Execute: + +For each step: + +1. Read `.github/java-upgrade//plan.md` for step details and guidelines +2. Mark ⏳ in `.github/java-upgrade//progress.md` +3. Make changes as planned (use OpenRewrite if helpful, verify results) + - Add TODOs for any deferred work, e.g., temporary workarounds +4. **Review Code Changes** (per rules in `progress.md` template): Verify sufficiency (all required changes present) and necessity (no unnecessary changes, functional behavior preserved, security controls maintained). + - Add missing changes and revert unnecessary changes. Document any unavoidable behavior changes with justification. +5. Verify with specified command/JDK + - **Steps 1-N (Setup/Upgrade)**: Compilation must pass (including both main and test code, fix immediately if not). Test failures acceptable - document count. + - **Final Validation Step**: Achieve **Upgrade Success Criteria** - iterative test & fix loop until 100% pass (or ≥ baseline). NO deferring. **Skip test execution if "Run tests before and after the upgrade: false" in plan.md Options — only verify compilation in that case.** + - After each build (`mvn clean test-compile` or equivalent): `#report-event(sessionId, event: "buildCompleted", phase: "execute", status: "succeeded"|"failed")` + - After each test run (`mvn clean test` or equivalent): `#report-event(sessionId, event: "testCompleted", phase: "execute", status: "succeeded"|"failed")` +6. Commit using `#version-control(sessionId: , workspacePath, action: "commitChanges")` (if version control available; otherwise, log details in `progress.md`): + - commitMessage format — First line: `Step : - Compile: <result>` or `Step <x>: <title> - Compile: <result>, Tests: <pass>/<total> passed` (if tests run) + - Body: Changes summary + concise known issues/limitations (≤5 lines) + - **Security note**: If any security-related changes were made, include "Security: <change description and justification>" +7. Update `progress.md` with step details and mark ✅ or ❗ +8. Report event at end of each step: + - **Step 1 (Setup Environment)**: `#report-event(sessionId, event: "environmentSetup", phase: "execute", status: "succeeded"|"failed"|"skipped", details: {jdkPath: "<JDK path>", buildToolPath: "<build tool executable path>"})` — **details are REQUIRED** for this event. The `jdkPath` and `buildToolPath` must be valid paths that exist on this machine. Use `"."` for `buildToolPath` if a wrapper (mvnw/gradlew) is used. + - **Step 2 (Setup Baseline)**: `#report-event(sessionId, event: "baselineSetup", phase: "execute", status: "succeeded"|"failed"|"skipped")` — use `"skipped"` with a `message` when the base JDK is not available + - **Before each upgrade step (Steps 3-N)**: `#report-event(sessionId, event: "upgradeStepStarted", phase: "execute", status: "succeeded", details: {stepNumber: <N>, stepTitle: "<title>"})` + - **After each upgrade step (Steps 3-N)**: `#report-event(sessionId, event: "upgradeStepCompleted", phase: "execute", status: "succeeded"|"failed", details: {stepNumber: <N>, stepTitle: "<title>", commitId: "<commitId from #version-control response, or 'N/A' if version control unavailable>"})` + - **Final step (Final Validation)**: `#report-event(sessionId, event: "upgradeValidationCompleted", phase: "execute", status: "succeeded"|"failed", details: {stepNumber: <N>, stepTitle: "<title>", commitId: "<commit_id from #version-control response if version control available, otherwise 'N/A'>"})` + +#### 3. Complete + +1. Validate all steps in `plan.md` have ✅ in `.github/java-upgrade/<SESSION_ID>/progress.md` +2. Validate all **Upgrade Success Criteria** are met, or otherwise go back to Final Validation step to fix +3. Call tool `#report-event(sessionId, event: "planExecutionCompleted", phase: "execute", status: "succeeded")` + +### Phase 5: Summarize & Cleanup + +1. **Scan CVEs**: Extract direct deps (`mvn dependency:list -DexcludeTransitive=true`), call `#validate-cves-for-java(sessionId, dependencies, projectPath)` +2. **Collect test coverage**: Run `mvn clean verify -Djacoco.skip=false` or equivalent; record metrics +3. Update `summary.md`: + - **Step 1 (Populate sections)**: Populate `summary.md` sections: Executive Summary, Upgrade Improvements (table + Key Benefits), Build and Validation, Limitations (write "None" if all issues resolved), Recommended Next Steps, Additional details (Project Details, Code Changes, Automated Tasks, CVEs) + - **Step 2 (Replace placeholders)**: Replace placeholders (including `<OS_USER_NAME>` with the actual OS username — use `$env:USERNAME` (Windows) or `$USER` (Unix) first; fall back to `whoami` if those are unavailable), follow **Template compliance** + - **Step 3 (Verify `summary.md`)**: After writing, confirm the file has no leftover template artifacts. Check each of the following — if any are found, remove the artifacts and rewrite the affected section immediately: + - No `<!--` HTML comments + - No `<placeholder>` tokens (e.g., `<one-paragraph summary>`, `<upgrade summary paragraph>`, `<OS_USER_NAME>`) + - No blank required fields + - No empty list items (lines that are just `-`, `*`, or similar) + - No bare outline/roman-numeral headings (e.g., `I.`, `II.`, `A.`) without content + - No duplicate section headings (the same `## N.` heading appearing more than once indicates the original template was not fully replaced — remove the leftover template portion entirely) +4. Clean up temp files; remove HTML comments from all `.md` files +5. → `#report-event(sessionId, event: "summaryGenerated", phase: "summarize", status: "succeeded", message: "<1-2 sentence summary>")` + +### Phase 6: Prompt for Follow-up Actions (CONDITIONAL) + +If issues detected, use `#askQuestions` to prompt user: + +1. **Critical/High CVEs found**: Offer to upgrade vulnerable dependencies using this custom agent; use `#validate-cves-for-java(sessionId)` to verify resolution. +2. **Low coverage (<70%)**: Offer to generate tests via `#generate-tests-for-java(sessionId, projectPath)`. + + +--- + +## Working Folder and Reporting + +When invoked from the appmod CLI orchestrator, the calling prompt will provide a +`modernization-work-folder` and a `TaskId`. The following rules are MANDATORY and +override any conflicting working-folder convention from the sections above: + +- Use `${modernization-work-folder}` as the working directory for ALL bookkeeping + artifacts (plan notes, progress logs, intermediate results). Do NOT create or + write into any folder outside `${modernization-work-folder}` for these artifacts + (e.g., do NOT use `.github/java-upgrade/<timestamp>/` or any other ad-hoc + location). Source-code edits inside the target repository are unaffected by + this rule. + +- Before returning, you MUST: + 1. Create `${modernization-work-folder}/${TaskId}/` if it does not exist. + 2. Write `${modernization-work-folder}/${TaskId}/modernization-summary.md` with: + - `finalStatus`: one of `"success"`, `"failed"`, `"skipped"` + - `successCriteriaStatus`: object with boolean `passBuild`, + `generateNewUnitTests`, `passUnitTests` + - `summary`: short prose summary of what changed + - `failureReason`: short prose, only when `finalStatus` is `"failed"` + 3. Return the same `finalStatus` / `successCriteriaStatus` / `summary` in your + final message so the orchestrator can update `tasks.json`. diff --git a/.github/skills/execute-modernization-task/SKILL.md b/.github/skills/execute-modernization-task/SKILL.md new file mode 100644 index 000000000..e899b31de --- /dev/null +++ b/.github/skills/execute-modernization-task/SKILL.md @@ -0,0 +1,49 @@ +--- +name: execute-modernization-task +description: Execute a modernization task as part of a modernization plan +--- +# Role +You are a code migration agent that executes modernization tasks. You will change the code according to skills, migration requirement, environment configuration and success criteria + +# Principles +1) Reuse current branch when to do the code change +2) NEVER discard any change +3) If a relevant skill exists in the available skills list, load it for more information about the task. + +# Workflow +Follow these steps in order when executing a modernization task: + +1. **Extract Knowledge Base**: Load all relevant skills from the available skills list. Extract the best practices and migration guidance they contain. This knowledge base takes precedence over any general knowledge you have. +2. **Analyze and Migrate**: Analyze the current code and reason about each required code change based on the extracted knowledge base. When there is a conflict between your general knowledge and the skill-provided best practices, always follow the skill-provided best practices. +3. **Consistency Check**: After completing code migration, run the consistency check. +4. **Build and Test**: Build the source and run unit tests. The source must be buildable and no new test failures may be introduced by your changes. +5. **Re-verify After Any Change**: Every time you make a change — including consistency fixes — you must rebuild and re-run unit tests, even if the previous build and test run were successful. + +# Consistency Check + +Call custom agent `task` with the following prompt to run the consistency check: + + ```md + Call skill validation-check-consistency to validate the consistency of the migrated code. + - modernization-work-folder: ${modernization-work-folder} + - task-id: ${taskid} + - task-skill: The skill(s) used for this migration task, you should find it in ${modernization-work-folder}/.metadata/tasks.json + ``` + +Review the consistency check results. If any Critical or Major issues are found, fix them and re-run the consistency check. Repeat this fix-and-revalidate loop until the check reports zero Critical and zero Major issues before proceeding. + +# Exit Criteria +Before committing and marking the task as complete, verify: +1. **Consistency**: Fix all Critical and Major issues. Apply best-effort fixes for Minor issues. +2. **Completeness**: All old technology references relevant to this task are fully removed or replaced — check source files, configuration files, build files, and test files; do not leave partial old-technology remnants +3. **Build and tests**: If the task success criteria require `passBuild` or `passUnitTests`, confirm they pass before finishing + +Do not mark the task as complete until all applicable exit criteria are satisfied. + +# Final Check + +Run a full build and execute all unit tests one last time. Confirm there are no build errors and no unit test failures before proceeding to commit. + +# Output +1) Create a subfolder ${taskid} under ${modernization-work-folder}. You only need to generate a summary report "modernization-summary.md", under this subfolder to summarize the changes, and there is no need to generate any other documents. +2) Make a commit when the task is completed with the changes made in the modernization task. diff --git a/.github/skills/execute-upgrade-task/SKILL.md b/.github/skills/execute-upgrade-task/SKILL.md new file mode 100644 index 000000000..e4b7bb633 --- /dev/null +++ b/.github/skills/execute-upgrade-task/SKILL.md @@ -0,0 +1,23 @@ +--- +name: execute-upgrade-task +description: Execute an upgrade task as part of a modernization plan +--- +# Role +You are a code migration agent that executes upgrade tasks. You will change the code according to skills, migration requirement, environment configuration and success criteria + +# Principles +1) Reuse current branch when to do the code change +2) NEVER discard any change +3) If a relevant skill exists in the available skills list, load it for more information about the task. + +# Exit Criteria +Before committing and marking the task as complete, verify: +1. **Consistency**: All upgrade goals described in the task are correctly and completely implemented — re-read the task description and requirements and confirm every goal is addressed in the changed files +2. **Completeness**: All old technology references relevant to this task are fully removed or replaced — check source files, configuration files, build files, and test files; do not leave partial old-technology remnants +3. **Build and tests**: If the task success criteria require `passBuild` or `passUnitTests`, confirm they pass before finishing + +Do not mark the task as complete until all applicable exit criteria are satisfied. + +# Output +1) Create a subfolder ${taskid} under ${modernization-work-folder}. You only need to generate a summary report "modernization-summary.md", under this subfolder to summarize the changes, and there is no need to generate any other documents. +2) Make a commit when the task is completed with the changes made in the upgrade task. diff --git a/.github/skills/fact-application-name/SKILL.md b/.github/skills/fact-application-name/SKILL.md new file mode 100644 index 000000000..ec12cb292 --- /dev/null +++ b/.github/skills/fact-application-name/SKILL.md @@ -0,0 +1,112 @@ +--- +name: fact-application-name +description: Identify application name/identifier from configuration files +--- + +# Application Name Analysis + +## Purpose +Extract the application name or identifier from project files, configuration, and build descriptors. + +## Target Files/Locations +- **/pom.xml (<name>, <artifactId>) +- **/*.csproj (<AssemblyName>, <RootNamespace>) +- **/package.json (name field) +- **/build.gradle (rootProject.name) +- **/application.{properties,yml} (spring.application.name) +- **/README.md (title or project name) + +## Example Patterns +- `<name>CustomerPortal</name>` (Maven) +- `"name": "order-processor"` (Node.js) +- `spring.application.name=payment-service` +- `<AssemblyName>InventoryAPI</AssemblyName>` (.NET) + +## Analysis Steps + +### 1. Check Build File Names +``` +Maven (pom.xml): +Use Grep: "<name>|<artifactId>" +Extract: <name>ProjectName</name> + +Gradle (build.gradle): +Use Grep: "rootProject\\.name" +Extract: rootProject.name = 'project-name' + +Node.js (package.json): +Use Read and parse JSON: { "name": "app-name" } + +.NET (*.csproj): +Use Grep: "<AssemblyName>|<RootNamespace>" +``` + +### 2. Check Application Configuration +``` +Use Grep: "spring\\.application\\.name|app\\.name|application\\.name" +Files: **/application.{properties,yml}, **/appsettings.json +Context: -B 1 -A 1 +``` + +### 3. Check README +``` +Use Read: **/README.md (first 50 lines) +Look for: +- # Title +- Project name in first paragraph +- Badge labels +``` + +### 4. Check Container Names +``` +Use Grep: "container_name:" +Files: **/docker-compose*.yml +Application name often in container name +``` + +## Confidence Determination + +### High Confidence +- ✅ Name consistently appears across multiple files +- ✅ Clear identifier in build/config files +- **Example**: "Application name: CustomerPortal from pom.xml, spring.application.name, and README" + +### Medium Confidence +- ⚠️ Name in build file but not elsewhere +- ⚠️ Generic name (app, service, api) +- **Example**: "Project name: my-app (generic name from package.json only)" + +### Low Confidence +- ⚠️ No clear application name +- ⚠️ Names inconsistent across files +- **Example**: "Multiple names found, primary name unclear" + +### Not Applicable +- ❌ Multi-module project with multiple applications +- **Example**: "Monorepo with 10 microservices, no single application name" + +## Output Format + +```json +{ + "input_name": "Application Name", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Application name}", + "confidence": "high|medium|low", + "evidence": [ + "{Source file and field}", + "{Consistency across files}", + "{Alternative names found}" + ], + "values": [ + "{Primary name}", + "{Alternative names/identifiers}", + "{Artifact IDs or namespaces}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-application-port/SKILL.md b/.github/skills/fact-application-port/SKILL.md new file mode 100644 index 000000000..df9d5e3d7 --- /dev/null +++ b/.github/skills/fact-application-port/SKILL.md @@ -0,0 +1,96 @@ +--- +name: fact-application-port +description: Identify exposed application ports from container configuration +--- + +# Application Port Analysis + +## Purpose +Identify which ports the containerized application exposes for HTTP, HTTPS, and other services. + +## Target Files/Locations +- **/Dockerfile (EXPOSE instruction) +- **/docker-compose*.yml (ports section) +- **/k8s/**/*.yaml (containerPort, servicePort) +- **/application.{properties,yml} (server.port) + +## Example Patterns +- `EXPOSE 8080 443` +- `ports: - "3000:3000"` +- `containerPort: 8080` +- `server.port=8080` + +## Analysis Steps + +### 1. Check Dockerfile EXPOSE +``` +Use Grep: "^EXPOSE\\s+" +Files: **/Dockerfile, **/Containerfile +Extract port numbers +``` + +### 2. Analyze docker-compose Ports +``` +Use Read: **/docker-compose*.yml +Look for ports: section +Format: "HOST:CONTAINER" or just "PORT" +``` + +### 3. Check Kubernetes Manifests +``` +Use Grep: "containerPort|servicePort|targetPort" +Files: **/k8s/**/*.yaml, **/*.yaml +Context: -B 2 -A 2 +``` + +### 4. Check Application Configuration +``` +Use Grep: "server\\.port|PORT|HTTP_PORT" +Files: **/application.{properties,yml}, **/.env +``` + +## Confidence Determination + +### High Confidence +- ✅ EXPOSE in Dockerfile + ports in compose/k8s +- ✅ Application config matches container config +- **Example**: "Application exposes port 8080 (HTTP) and 443 (HTTPS) based on Dockerfile EXPOSE and docker-compose ports" + +### Medium Confidence +- ⚠️ Ports in config but not all files consistent +- **Example**: "Port 8080 in Dockerfile EXPOSE, but docker-compose uses 3000:8080" + +### Low Confidence +- ⚠️ No explicit port configuration +- **Example**: "No EXPOSE instruction, likely uses default runtime port" + +### Not Applicable +- ❌ No container or non-networked app +- **Example**: "CLI application, no network ports" + +## Output Format + +```json +{ + "input_name": "Application Port", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Ports summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Dockerfile EXPOSE}", + "{docker-compose ports}", + "{K8s port config}", + "{Application config}" + ], + "values": [ + "{Port numbers: 8080, 443, etc.}", + "{Protocol: HTTP, HTTPS, TCP}", + "{Port mapping if applicable}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-application-type/SKILL.md b/.github/skills/fact-application-type/SKILL.md new file mode 100644 index 000000000..a171d88df --- /dev/null +++ b/.github/skills/fact-application-type/SKILL.md @@ -0,0 +1,133 @@ +--- +name: fact-application-type +description: Determine the type of application (Web App, API, Service, etc.) +--- + +# Application Type Analysis + +## Purpose +Identify the type of application based on code structure and dependencies. + +## Target Files/Locations +- **/pom.xml, **/build.gradle, **/build.gradle.kts (Java) +- **/*.csproj (C#/.NET) +- **/package.json (Node.js) +- **/requirements.txt, **/Pipfile, **/pyproject.toml (Python) +- **/*.java, **/*.cs, **/*.js, **/*.ts, **/*.py (source code) + +## Analysis Steps + +### 1. Check Java Web Frameworks +``` +Use Grep: "spring-boot-starter-web|@RestController|@RequestMapping|spring-boot-starter-webflux" +Files: **/pom.xml, **/build.gradle, **/*.java + +Map findings: +- spring-boot-starter-web / @RestController → REST API +- spring-boot-starter-webflux → REST API (Reactive) +``` + +### 2. Check Java gRPC +``` +Use Grep: "grpc|io\\.grpc" +Files: **/pom.xml, **/build.gradle, **/*.proto + +If found → gRPC Service +``` + +### 3. Check .NET Project Type +``` +Use Grep: "Microsoft\\.AspNetCore|Microsoft\\.NET\\.Sdk\\.Web" +Files: **/*.csproj + +Map findings: +- Microsoft.NET.Sdk.Web / Microsoft.AspNetCore → Web App / REST API +``` + +### 4. Check .NET gRPC +``` +Use Grep: "Grpc\\.AspNetCore" +Files: **/*.csproj + +If found → gRPC Service +``` + +### 5. Check .NET Background Service +``` +Use Grep: "BackgroundService|Microsoft\\.Extensions\\.Hosting" +Files: **/*.csproj, **/*.cs + +If found (and no web SDK) → Background Service +``` + +### 6. Check Node.js Frameworks +``` +Use Grep: "express|fastify|koa|@nestjs|@grpc/grpc-js" +Files: **/package.json + +Map findings: +- express / fastify / koa / @nestjs → REST API / Web App +- @grpc/grpc-js → gRPC Service +``` + +### 7. Check Python Frameworks +``` +Use Grep: "flask|django|fastapi|tornado|grpcio" +Files: **/requirements.txt, **/Pipfile, **/pyproject.toml + +Map findings: +- flask / django / fastapi / tornado → REST API / Web App +- grpcio → gRPC Service +``` + +### 8. Check for Batch/Job Indicators +``` +Use Glob: **/cron*, **/*job*, **/*batch*, **/*scheduler* +Use Grep: "@Scheduled|CronJob|BackgroundJob" +Files: **/*.{java,cs,py} + +If no web framework found but batch patterns detected → Batch Job +``` + +## Confidence Determination + +### High Confidence +- ✅ Web framework dependency clearly identified +- ✅ REST/gRPC annotations in source code +- **Example**: "REST API: Spring Boot with @RestController annotations" + +### Medium Confidence +- ⚠️ Framework found but type ambiguous +- **Example**: "ASP.NET Core project, could be Web App or API" + +### Low Confidence +- ⚠️ No clear framework indicators +- **Example**: "Unable to determine application type from available files" + +### Not Applicable +- ❌ Library project with no entry point +- **Example**: "Library/SDK project, no application type" + +## Output Format + +```json +{ + "input_name": "Application Type", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Application type}", + "confidence": "high|medium|low", + "evidence": [ + "{Framework dependencies}", + "{Annotations/decorators found}", + "{Project structure indicators}" + ], + "values": [ + "{Type: REST API, Web App, gRPC Service, Background Service, Batch Job, etc.}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-architecture-pattern/SKILL.md b/.github/skills/fact-architecture-pattern/SKILL.md new file mode 100644 index 000000000..cd3c5e80a --- /dev/null +++ b/.github/skills/fact-architecture-pattern/SKILL.md @@ -0,0 +1,218 @@ +--- +name: fact-architecture-pattern +description: Identify the application architecture pattern +--- + +# Architecture Pattern Analysis + +## Purpose +Determine the architectural pattern used in the application: Monolith, Microservices, Layered, Event-Driven, MVC, etc. + +## Analysis Strategy + +This SKILL performs a comprehensive analysis of project structure, dependencies, and code patterns to identify the architecture. + +## Analysis Steps + +### 1. Project Structure Analysis + +**Check for Microservices Indicators:** +```bash +# Use Glob to search for service directories +**/services/**/ +**/microservices/**/ +**/apps/**/ +``` + +**Check for Monolith Indicators:** +- Single deployable unit +- All code in one project/module + +### 2. Configuration & Infrastructure Analysis + +**Search for Service Discovery (Microservices):** +```bash +# Use Grep to find service discovery patterns +Pattern: "eureka|consul|etcd|kubernetes|k8s|service\.discovery" +Files: **/*.{yaml,yml,json,xml,properties,config} +``` + +**Search for API Gateway (Microservices):** +```bash +Pattern: "zuul|gateway|kong|ambassador|istio|envoy|traefik" +Files: **/*.{yaml,yml,json,xml,properties,pom.xml,build.gradle,package.json} +``` + +**Search for Message Brokers (Event-Driven):** +```bash +Pattern: "kafka|rabbitmq|activemq|azure\.servicebus|aws\.sqs|redis\.pub" +Files: **/*.{yaml,yml,json,xml,properties,config} +``` + +### 3. Code Pattern Analysis + +**MVC Pattern Detection:** +```bash +# Search for controllers +Pattern: "@Controller|@RestController|ApiController|[Controller]|class.*Controller" +Files: **/*.{java,cs,py,js,ts} + +# Search for models +Glob: **/models/**/*.*, **/entities/**/*.*, **/domain/**/*.* + +# Search for views +Glob: **/views/**/*.*, **/templates/**/*.* +``` + +**Layered Architecture Detection:** +```bash +# Search for layer separation +Glob: **/controller*/**/*, **/service*/**/*, **/repository*/**/*, **/dao*/**/*.* + +Pattern: "@Service|@Repository|@Component|[Service]|interface.*Repository" +Files: **/*.{java,cs} +``` + +**Event-Driven Pattern Detection:** +```bash +Pattern: "@EventHandler|@KafkaListener|@RabbitListener|EventEmitter|publish\(|subscribe\(" +Files: **/*.{java,cs,js,ts,py} +``` + +### 4. Deployment Configuration Analysis + +**Container Orchestration (Microservices):** +```bash +Glob: **/kubernetes/**/*.yaml, **/k8s/**/*.yaml, **/helm/**/*.* +Glob: docker-compose*.{yml,yaml} +``` + +**Check docker-compose for multiple services:** +```bash +Pattern: "services:\n(.*\n){3,}" +Files: docker-compose*.{yml,yaml} +``` + +## Analysis Decision Tree + +1. **If multiple deployable services detected** → Microservices Architecture + - Evidence: Multiple service directories, service discovery, API gateway + +2. **If message brokers + event handlers detected** → Event-Driven Architecture + - Evidence: Kafka/RabbitMQ configs, event listeners, pub/sub patterns + +3. **If clear MVC structure detected** → MVC Architecture + - Evidence: Controllers, Models, Views directories + +4. **If layer separation detected (but single deployment)** → Layered Monolith + - Evidence: Controller/Service/Repository layers in single project + +5. **If single project with no clear separation** → Simple Monolith + - Evidence: All code in one directory, minimal structure + +## Confidence Levels + +- **High**: Clear indicators from multiple sources (structure + config + code patterns) +- **Medium**: Some indicators present but mixed signals +- **Low**: Limited evidence, manual inspection recommended + +## Output Format + +After analysis, call the MCP tool: + +```javascript +write_assessment_result({ + resultJson: JSON.stringify({ + input_name: "Architecture Pattern", + analysis_method: "Hybrid", // Code + LLM analysis + status: "success", // or "not_applicable" or "failed" + result: { + finding: "Microservices Architecture", + confidence: "high", // high, medium, or low + evidence: [ + "Found 5 service directories: user-service, order-service, payment-service, notification-service, gateway-service", + "docker-compose.yml defines 5 separate services", + "Found Eureka service discovery configuration", + "API Gateway detected: Zuul configuration in gateway-service/application.yml" + ], + values: ["Microservices", "Service Discovery", "API Gateway"], + architecture_details: { + pattern: "Microservices", + service_count: 5, + has_service_discovery: true, + has_api_gateway: true, + has_message_broker: false + } + }, + execution_time_seconds: 3.5, + timestamp: new Date().toISOString() + }), + assessmentDir: variables.assessment_dir +}); +``` + +## Example Patterns by Technology Stack + +### Java/Spring Boot + +**Microservices:** +- `@EnableEurekaClient`, `@EnableDiscoveryClient` +- `spring-cloud-starter-netflix-eureka` +- Multiple `@SpringBootApplication` classes + +**Layered Monolith:** +- Single `@SpringBootApplication` +- Packages: `controller`, `service`, `repository`, `entity` + +### .NET/ASP.NET Core + +**Microservices:** +- Multiple `.csproj` files with `<OutputType>Exe</OutputType>` +- `Microsoft.Extensions.Http.Polly` (service-to-service calls) +- `Steeltoe.Discovery.Eureka` + +**MVC:** +- Single `.csproj` with `Microsoft.AspNetCore.Mvc` +- Folders: `Controllers`, `Models`, `Views` + +### Node.js/Express + +**Microservices:** +- Multiple `package.json` files in subdirectories +- `express-gateway`, `consul` dependencies + +**Layered:** +- Single `package.json` +- Folders: `routes`, `controllers`, `services`, `models` + +### Python + +**Microservices:** +- Multiple `app.py` or `main.py` files +- `nameko`, `flask-consul` dependencies + +**Event-Driven:** +- `kafka-python`, `pika` (RabbitMQ), `celery` +- Event handler decorators + +## Not Applicable Scenarios + +Return `status: "not_applicable"` if: +- Project is not an application (library, CLI tool only) +- Insufficient code to determine architecture +- Non-standard structure that doesn't fit patterns + +## Error Handling + +Return `status: "failed"` if: +- Unable to access project files +- Critical analysis error occurred + +Include error details in the result. + +## Notes + +- Architecture can be hybrid (e.g., Layered + Event-Driven) +- Include all applicable patterns in `values` array +- Prioritize most dominant pattern in `finding` +- If uncertain between patterns, use `confidence: "medium"` and explain in evidence diff --git a/.github/skills/fact-base-image/SKILL.md b/.github/skills/fact-base-image/SKILL.md new file mode 100644 index 000000000..f48912217 --- /dev/null +++ b/.github/skills/fact-base-image/SKILL.md @@ -0,0 +1,102 @@ +--- +name: fact-base-image +description: Identify container base image used in Dockerfile +--- + +# Base Image Analysis + +## Purpose +Identify the base container image (e.g., alpine:3.15, ubuntu:20.04, node:16-alpine) used in Dockerfile/Containerfile to understand OS dependencies and image foundations. + +## Target Files/Locations +- **/Dockerfile, **/Containerfile +- **/docker-compose*.yml +- **/k8s/**/*.yaml + +## Example Patterns +- `FROM alpine:3.15` +- `FROM ubuntu:20.04` +- `FROM node:16-alpine AS builder` +- `FROM mcr.microsoft.com/dotnet/sdk:6.0` + +## Analysis Steps + +### 1. Find and Read Dockerfiles +``` +Use Glob: **/Dockerfile, **/Containerfile +Use Read to examine each file +Look for FROM instructions +``` + +### 2. Extract Base Images +``` +Use Grep: "^FROM\\s+" +Files: **/Dockerfile, **/Containerfile +Context: -A 1 + +Parse format: FROM <image>:<tag> [AS <stage>] +``` + +### 3. Check for Multi-stage Builds +``` +Multiple FROM instructions indicate multi-stage build +Identify final stage base image +Note all intermediate base images +``` + +### 4. Verify Image Registry +``` +Check for: +- Docker Hub (no prefix or docker.io/) +- MCR (mcr.microsoft.com/) +- GCR (gcr.io/) +- ECR (*.amazonaws.com/) +- Custom registry +``` + +## Confidence Determination + +### High Confidence +- ✅ Dockerfile exists with explicit FROM instruction +- ✅ Image name and tag clearly specified +- **Example**: "Base image: alpine:3.15 from Dockerfile line 1" + +### Medium Confidence +- ⚠️ Multiple stages with different base images +- ⚠️ FROM uses build argument (FROM ${BASE_IMAGE}) +- **Example**: "Base image uses variable, likely node:16 based on docker-compose" + +### Low Confidence +- ⚠️ No Dockerfile found +- ⚠️ Base image unclear from manifests +- **Example**: "Kubernetes deployment exists but base image not specified" + +### Not Applicable +- ❌ No containerization +- **Example**: "No container files found" + +## Output Format + +```json +{ + "input_name": "Base Image", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Base image identified}", + "confidence": "high|medium|low", + "evidence": [ + "{Dockerfile location}", + "{FROM instruction(s)}", + "{Multi-stage details if applicable}" + ], + "values": [ + "{Base image name:tag}", + "{OS type (Alpine, Ubuntu, etc.)}", + "{Registry source}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-communication-protocols/SKILL.md b/.github/skills/fact-communication-protocols/SKILL.md new file mode 100644 index 000000000..6b6a9082f --- /dev/null +++ b/.github/skills/fact-communication-protocols/SKILL.md @@ -0,0 +1,118 @@ +--- +name: fact-communication-protocols +description: Identify inter-service communication protocols (HTTP/REST, gRPC, Message Queue, TCP) +--- + +# Communication Protocols Analysis + +## Purpose +Detect communication protocols used for inter-service communication, API exposure, and external integrations. + +## Target Files/Locations +- **/pom.xml, **/build.gradle, **/*.csproj, **/package.json (dependencies) +- **/*.proto (gRPC definitions) +- **/application.{properties,yml} (message queue configs) +- **/*.java, **/*.cs, **/*.js (HTTP clients, gRPC stubs) + +## Example Patterns +- **HTTP/REST**: RestTemplate, HttpClient, axios, fetch, @RestController +- **gRPC**: grpc-*, *.proto files, gRPC stubs +- **Message Queues**: RabbitMQ, Kafka, Redis Pub/Sub, AWS SQS +- **TCP/UDP**: Socket, ServerSocket, TcpClient +- **WebSocket**: ws://, WebSocket, SignalR + +## Analysis Steps + +### 1. Check for HTTP/REST +``` +Use Grep: "@RestController|@RequestMapping|HttpClient|RestTemplate|axios|fetch" +Files: **/*.{java,cs,js,py} +Context: -B 2 -A 2 + +Check Spring: @RestController, @GetMapping +Check .NET: HttpClient, [ApiController] +Check Node: express, axios +``` + +### 2. Check for gRPC +``` +Use Glob: **/*.proto +Count proto files + +Use Grep: "grpc|GrpcClient|GrpcChannel" +Files: **/*.{java,cs,go,py} +Dependencies: grpc-netty, Grpc.Net.Client, @grpc/grpc-js +``` + +### 3. Check for Message Queues +``` +Use Grep: "RabbitTemplate|KafkaTemplate|@JmsListener|IMessageQueue" +Files: **/*.{java,cs} + +Dependencies: +- spring-boot-starter-amqp (RabbitMQ) +- spring-kafka (Kafka) +- MassTransit, NServiceBus (.NET) + +Config: +- spring.rabbitmq.*, spring.kafka.* +``` + +### 4. Check for WebSocket +``` +Use Grep: "WebSocket|ws://|wss://|SignalR|@ServerEndpoint" +Files: **/*.{java,cs,js} +``` + +### 5. Check for TCP/UDP +``` +Use Grep: "ServerSocket|Socket|TcpListener|UdpClient" +Files: **/*.{java,cs,go} +``` + +## Confidence Determination + +### High Confidence +- ✅ Multiple protocol indicators found +- ✅ Dependencies + code usage confirmed +- **Example**: "HTTP/REST via Spring MVC, gRPC for internal services (5 .proto files), Kafka for async messaging" + +### Medium Confidence +- ⚠️ Dependencies present but usage unclear +- **Example**: "HTTP REST API likely, gRPC dependency but no .proto files found" + +### Low Confidence +- ⚠️ Protocol inferred from framework +- **Example**: "Likely HTTP-based (web framework) but protocol not explicit" + +### Not Applicable +- ❌ Standalone application with no communication +- **Example**: "CLI tool with no network communication" + +## Output Format + +```json +{ + "input_name": "Communication Protocols", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Protocols summary}", + "confidence": "high|medium|low", + "evidence": [ + "{HTTP/REST endpoints}", + "{gRPC proto files}", + "{Message queue configs}", + "{Dependencies}" + ], + "values": [ + "{Protocol: HTTP/REST, gRPC, Kafka, RabbitMQ, etc.}", + "{Framework: Spring MVC, ASP.NET Core, Express}", + "{Port numbers}", + "{Count: N endpoints, M proto files}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-compliance-requirements/SKILL.md b/.github/skills/fact-compliance-requirements/SKILL.md new file mode 100644 index 000000000..4de230ea0 --- /dev/null +++ b/.github/skills/fact-compliance-requirements/SKILL.md @@ -0,0 +1,131 @@ +--- +name: fact-compliance-requirements +description: Identify regulatory compliance needs (GDPR, HIPAA, PCI-DSS, SOX) +--- + +# Compliance Requirements Analysis + +## Purpose +Identify regulatory compliance requirements the application must meet based on data handling, industry, and security measures. + +## Target Files/Locations +- **/README.md, **/COMPLIANCE.md, **/SECURITY.md, **/privacy-policy.md +- **/docs/**/*.md +- **/*.{java,cs,js,py,ts} (data handling, encryption) +- **/application.{properties,yml} (audit logging) + +## Example Patterns +- GDPR: data protection, right to erasure, consent +- HIPAA: PHI, encryption, audit logs +- PCI-DSS: payment data, encryption at rest/transit +- SOX: financial data, audit trails, access controls + +## Analysis Steps + +### 1. Check Documentation +``` +Use Read: **/README.md, **/COMPLIANCE.md, **/SECURITY.md +Use Grep: "GDPR|HIPAA|PCI-DSS|PCI|SOX|Sarbanes-Oxley|ISO 27001|SOC 2" +Files: **/docs/**/*.md +Context: -B 2 -A 3 + +Look for: +- Compliance statements +- Regulatory requirements +- Data handling policies +``` + +### 2. Check for Data Protection Code +``` +Use Grep: "PersonalData|PII|PHI|PaymentData|encrypt|anonymize|pseudonymize" +Files: **/*.{java,cs,js,py} +Context: -B 2 -A 2 + +Indicators: +- Data encryption implementations +- Anonymization functions +- Consent management +- Data retention policies +``` + +### 3. Check for Audit Logging +``` +Use Grep: "AuditLog|audit|trail|compliance.*log" +Files: **/*.{java,cs}, **/application.{properties,yml} + +Look for: +- Audit event logging +- User action tracking +- Data access logs +``` + +### 4. Check for Data Privacy Features +``` +Search for: +- Data export (GDPR right to portability) +- Data deletion (right to erasure) +- Consent management +- Cookie policies + +Use Grep: "exportData|deleteUser|consent|privacy|GDPR" +``` + +### 5. Check Security Measures +``` +Compliance often requires: +- Encryption at rest and in transit +- Access controls (RBAC) +- Multi-factor authentication +- Regular security audits + +Cross-reference with security-implementation analysis +``` + +## Confidence Determination + +### High Confidence +- ✅ Explicit compliance documentation +- ✅ Compliance-specific code features +- ✅ Regulatory requirements mentioned +- **Example**: "GDPR compliant: data encryption, consent management, right-to-erasure API implemented" + +### Medium Confidence +- ⚠️ Some compliance features but not comprehensive +- **Example**: "Encryption and audit logging present, suggests PCI-DSS consideration but not documented" + +### Low Confidence +- ⚠️ No explicit compliance requirements +- ⚠️ Features that could support compliance +- **Example**: "Standard security features, no specific compliance mentioned" + +### Not Applicable +- ❌ Internal tool with no regulatory requirements +- **Example**: "Development utility, no compliance requirements" + +## Output Format + +```json +{ + "input_name": "Compliance Requirements", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Compliance summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Documentation mentions}", + "{Compliance-specific code}", + "{Security features}", + "{Audit logging}" + ], + "values": [ + "{Regulations: GDPR, HIPAA, PCI-DSS, SOX, etc.}", + "{Features: encryption, audit logs, consent}", + "{Data types: PII, PHI, payment data}", + "{Certifications if mentioned}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-container-engine/SKILL.md b/.github/skills/fact-container-engine/SKILL.md new file mode 100644 index 000000000..4d30e5ecb --- /dev/null +++ b/.github/skills/fact-container-engine/SKILL.md @@ -0,0 +1,108 @@ +--- +name: fact-container-engine +description: Identify container runtime being used (Docker, Podman, containerd) +--- + +# Container Engine Analysis + +## Purpose +Determine which container engine the application uses (Docker, Podman, containerd, etc.) through analysis of configuration files, build scripts, and deployment manifests. + +## Target Files/Locations +- **/Dockerfile, **/Containerfile +- **/docker-compose*.yml +- **/.dockerignore +- **/Makefile, **/*.sh (build scripts) +- **/k8s/**/*.yaml, **/*.yaml (Kubernetes manifests) +- **/README.md, **/docs/**/*.md (documentation) +- **/.github/workflows/*.yml, **/.gitlab-ci.yml (CI/CD) + +## Example Patterns to Search +- **Docker**: `docker build`, `docker-compose`, `FROM`, `ENTRYPOINT`, `.dockerignore` +- **Podman**: `podman build`, `podman-compose`, `podman run` +- **containerd**: `ctr`, `nerdctl` +- **Build tools**: `docker buildx`, `buildah`, `kaniko` + +## Analysis Steps + +### 1. Check for Dockerfile/Containerfile +``` +Use Glob: **/Dockerfile, **/Containerfile +- Dockerfile indicates Docker usage +- Containerfile indicates Podman/Buildah compatibility +``` + +### 2. Search for Docker Compose Files +``` +Use Glob: **/docker-compose*.yml +Indicates Docker Compose usage +``` + +### 3. Analyze Build Scripts +``` +Use Grep: "docker|podman|buildah|nerdctl" +Files: **/*.sh, **/Makefile, **/*.bash +Context: -B 2 -A 2 +``` + +### 4. Check CI/CD Pipelines +``` +Use Grep in CI files: +- Pattern: "docker|podman|container" +- Files: **/.github/workflows/*.yml, **/.gitlab-ci.yml +``` + +### 5. Review Documentation +``` +Use Grep in docs: +- Pattern: "docker|podman|container engine" +- Files: **/README.md, **/docs/**/*.md +``` + +## Confidence Determination + +### High Confidence +- ✅ Dockerfile + docker-compose.yml present +- ✅ Build scripts explicitly use docker commands +- ✅ CI/CD uses specific container engine +- **Example**: "Docker engine with Compose v2 based on docker-compose.yml and Dockerfile" + +### Medium Confidence +- ⚠️ Generic Containerfile (Docker/Podman compatible) +- ⚠️ Build scripts don't specify engine +- **Example**: "Containerfile present, compatible with Docker or Podman" + +### Low Confidence +- ⚠️ No explicit engine indicators +- ⚠️ Only Kubernetes manifests (engine unclear) +- **Example**: "Container usage implied but engine unclear" + +### Not Applicable +- ❌ No containerization +- **Example**: "No container files found - traditional deployment" + +## Output Format + +```json +{ + "input_name": "Container Engine", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Container engine identified}", + "confidence": "high|medium|low", + "evidence": [ + "{Files found}", + "{Commands in scripts}", + "{CI/CD configuration}" + ], + "values": [ + "{Engine name: Docker, Podman, etc.}", + "{Compose version if applicable}", + "{Build tools used}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-container-version/SKILL.md b/.github/skills/fact-container-version/SKILL.md new file mode 100644 index 000000000..b18e4faf5 --- /dev/null +++ b/.github/skills/fact-container-version/SKILL.md @@ -0,0 +1,99 @@ +--- +name: fact-container-version +description: Identify container runtime version (Docker, Podman version) +--- + +# Container Version Analysis + +## Purpose +Determine the version of the container runtime being used through CI/CD configurations, documentation, or system requirements. + +## Target Files/Locations +- **/.github/workflows/*.yml, **/.gitlab-ci.yml +- **/README.md, **/docs/**/*.md +- **/Makefile, **/*.sh +- **/docker-compose.yml (version field) + +## Example Patterns +- `docker-compose version: '3.8'` +- Docker version: 20.10.17 +- Podman version: 4.1.0 + +## Analysis Steps + +### 1. Check docker-compose Version +``` +Use Glob: **/docker-compose*.yml +Use Read to find: version: '3.x' or version: '2.x' +This indicates required Docker Compose version +``` + +### 2. Search CI/CD for Version Specs +``` +Use Grep: "docker.*version|container.*version" +Files: **/.github/workflows/*.yml, **/.gitlab-ci.yml +Context: -B 2 -A 2 +``` + +### 3. Check Documentation +``` +Use Grep: "docker.*[0-9]+\\.[0-9]+|podman.*[0-9]+\\.[0-9]+" +Files: **/README.md, **/docs/**/*.md +Context: -B 1 -A 1 +``` + +### 4. Look for Version Requirements +``` +Search for: +- "requires Docker 20.10+" +- "tested with Podman 4.x" +- Minimum version specifications +``` + +## Confidence Determination + +### High Confidence +- ✅ docker-compose version explicitly set +- ✅ CI/CD specifies container version +- ✅ Documentation states version requirements +- **Example**: "Docker 20.10.17 specified in CI/CD, docker-compose v3.8" + +### Medium Confidence +- ⚠️ docker-compose version found but engine version unclear +- ⚠️ Version mentioned in docs but not enforced +- **Example**: "docker-compose v3.8 indicates Docker 19.03+ requirement" + +### Low Confidence +- ⚠️ No explicit version information +- ⚠️ Version inferred from features used +- **Example**: "Features used suggest Docker 20.10+ but not specified" + +### Not Applicable +- ❌ No containerization +- **Example**: "No container configuration found" + +## Output Format + +```json +{ + "input_name": "Container Version", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Container version information}", + "confidence": "high|medium|low", + "evidence": [ + "{docker-compose version}", + "{CI/CD specifications}", + "{Documentation references}" + ], + "values": [ + "{Engine: Docker/Podman}", + "{Version number or requirement}", + "{Compose version if applicable}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-data-classification/SKILL.md b/.github/skills/fact-data-classification/SKILL.md new file mode 100644 index 000000000..4cf84c614 --- /dev/null +++ b/.github/skills/fact-data-classification/SKILL.md @@ -0,0 +1,151 @@ +--- +name: fact-data-classification +description: Identify data sensitivity classification (Public, Internal, Confidential, PII) +--- + +# Data Classification Analysis + +## Purpose +Determine the sensitivity classification of data handled by the application to understand protection requirements. + +## Target Files/Locations +- **/README.md, **/SECURITY.md, **/DATA_CLASSIFICATION.md +- **/docs/**/*.md (data classification) +- **/*.{java,cs,js,py} (data annotations, comments) +- **/schema.sql, **/migrations/*.sql (database schemas) +- **/*.proto, **/*.graphql (API schemas) + +## Example Patterns +- **Public**: publicly accessible data, no protection needed +- **Internal**: company data, standard access controls +- **Confidential**: sensitive business data, strict access controls +- **PII**: personal identifiable information (names, emails, SSN) +- **PHI**: protected health information +- **PCI**: payment card data +- **Restricted**: highly sensitive, executive/legal only + +## Analysis Steps + +### 1. Check Documentation +``` +Use Read: **/README.md, **/SECURITY.md, **/DATA_CLASSIFICATION.md +Use Grep: "data classification|sensitivity|PII|confidential|restricted" +Files: **/docs/**/*.md +Context: -B 2 -A 3 + +Look for: +- Data classification policy +- Sensitivity levels +- Data types handled +``` + +### 2. Analyze Database Schemas +``` +Use Glob: **/schema.sql, **/migrations/*.sql, **/flyway/**/*.sql +Use Read to examine table definitions + +Look for sensitive data indicators: +- email, phone, address (PII) +- ssn, tax_id, national_id (PII) +- credit_card, account_number (PCI) +- password, secret, token (Credentials) +- medical, diagnosis (PHI) +- salary, financial (Confidential) +``` + +### 3. Check Code for Data Annotations +``` +Use Grep: "@PersonalData|@Confidential|@Restricted|@PII|@Sensitive" +Files: **/*.{java,cs} +Context: -B 1 -A 3 + +.NET: [PersonalData], [ProtectedPersonalData] +Java: Custom annotations or comments +``` + +### 4. Analyze API Schemas +``` +Use Glob: **/*.proto, **/*.graphql, **/openapi.yaml +Read schema definitions + +Identify sensitive fields: +- User personal information +- Authentication credentials +- Financial data +- Health information +``` + +### 5. Check Encryption Usage +``` +Encryption usage indicates sensitive data: + +Use Grep: "encrypt|cipher|AES|RSA|hash" +Files: **/*.{java,cs,js,py} +Context: -B 2 -A 2 + +What's encrypted: +- Passwords → Credentials (Confidential) +- Payment info → PCI Data +- Medical records → PHI +- Personal details → PII +``` + +### 6. Categorize Data Types +``` +Based on findings, classify: +- Public: blog posts, product catalogs +- Internal: employee directory, internal docs +- Confidential: trade secrets, financial reports +- PII: customer names, emails, addresses +- PHI: medical records, diagnoses +- PCI: credit card numbers, CVV +``` + +## Confidence Determination + +### High Confidence +- ✅ Data classification documented +- ✅ Sensitive data fields identified in schema +- ✅ Encryption applied to sensitive data +- **Example**: "Data classification: Confidential and PII - handles customer names, emails, addresses (PII) and financial transactions (Confidential)" + +### Medium Confidence +- ⚠️ Data types identified but no formal classification +- **Example**: "Database contains email and address fields (likely PII) but no classification policy documented" + +### Low Confidence +- ⚠️ Data types unclear from schema +- ⚠️ Generic field names +- **Example**: "Database schema generic, data sensitivity unclear" + +### Not Applicable +- ❌ No data storage (stateless API proxy) +- **Example**: "Stateless authentication proxy, no data stored" + +## Output Format + +```json +{ + "input_name": "Data Classification", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Classification summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Documentation}", + "{Database schema analysis}", + "{Sensitive field identification}", + "{Encryption usage}" + ], + "values": [ + "{Classification levels: Public, Internal, Confidential, PII, etc.}", + "{Sensitive data types handled}", + "{Protection measures per classification}", + "{Data volume estimates if available}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-embedded-language-usage/SKILL.md b/.github/skills/fact-embedded-language-usage/SKILL.md new file mode 100644 index 000000000..90c68df15 --- /dev/null +++ b/.github/skills/fact-embedded-language-usage/SKILL.md @@ -0,0 +1,277 @@ +--- +name: fact-embedded-language-usage +description: Identifies whether the Java app executes or embeds code in another language or interpreter at runtime +--- + +# Embedded Language Usage Analysis + +## Purpose +Detect if the application executes external processes, embeds scripting engines, or dynamically evaluates code in other languages at runtime. This includes shell command execution, JavaScript engines, Python interpreters, Groovy shells, and embedded SQL/native code execution. + +## Target Files/Locations +- **Java source files**: **/*.java +- **Script files**: **/*.sh, **/*.bat, **/*.ps1 +- **Configuration files**: **/application.{properties,yml}, **/pom.xml, **/build.gradle +- **Resources**: **/resources/**/*.js, **/resources/**/*.py, **/resources/**/*.groovy + +## Example Patterns to Search +- **Process Execution**: `Runtime.getRuntime().exec()`, `ProcessBuilder`, `ProcessBuilder.command()` +- **Script Engines**: `ScriptEngineManager`, `ScriptEngine.eval()`, `Nashorn`, `GraalVM.Polyglot` +- **Embedded Interpreters**: `GroovyShell`, `PythonInterpreter`, `JRuby`, `Jython` +- **Dynamic Evaluation**: `eval()`, `compile()`, `interpret()` +- **Native Code**: `System.loadLibrary()`, `JNI`, `JNA`, `native` keyword +- **SQL Execution**: `Statement.execute()`, `PreparedStatement`, dynamic SQL construction + +## Analysis Steps + +### 1. Search for Process Execution +``` +Use Grep tool to search for external process execution: +- Pattern: "Runtime\\.getRuntime\\(\\)\\.exec|ProcessBuilder|exec\\(|startProcess" +- Files: **/*.java +- Context: -B 2 -A 2 (2 lines before/after for context) + +Look for: +- Shell command execution +- External program invocation +- Dynamic command construction +``` + +### 2. Search for ScriptEngine APIs +``` +Use Grep tool to find scripting engine usage: +- Pattern: "ScriptEngineManager|ScriptEngine|Nashorn|GraalVM|Polyglot" +- Files: **/*.java +- Context: -B 3 -A 3 + +Check for: +- ScriptEngineManager instantiation +- JavaScript, Python, Groovy engine loading +- eval() or compile() calls +``` + +### 3. Search for Embedded Language Interpreters +``` +Use Grep tool to detect interpreter embedding: +- Pattern: "GroovyShell|PythonInterpreter|JRuby|Jython|LuaJ|BeanShell" +- Files: **/*.java +- Context: -B 3 -A 3 + +Identify: +- Groovy script execution +- Python code embedding +- Ruby/Lua interpreters +``` + +### 4. Check for Native Library Loading +``` +Use Grep tool to find native code usage: +- Pattern: "System\\.loadLibrary|System\\.load|native\\s+\\w+|JNI|JNA" +- Files: **/*.java +- Context: -B 2 -A 2 + +Look for: +- JNI native method declarations +- Dynamic library loading +- JNA interface definitions +``` + +### 5. Analyze Dependencies +``` +Use Glob to find build files: +- **/pom.xml +- **/build.gradle +- **/build.gradle.kts + +Use Read to check for dependencies: +- groovy-all, groovy-core +- jython, jruby +- nashorn-core, graalvm-js +- jna, jna-platform +- rhino (Mozilla JavaScript engine) +``` + +### 6. Check for Dynamic SQL Execution +``` +Use Grep tool to find dynamic SQL: +- Pattern: "Statement\\.execute|executeUpdate|executeQuery|createStatement" +- Files: **/*.java +- Context: -B 3 -A 3 + +Analyze for: +- Dynamic SQL string construction +- Concatenated SQL queries +- PreparedStatement vs Statement usage +``` + +### 7. Scan for Script Files in Resources +``` +Use Glob to find embedded scripts: +- **/resources/**/*.js +- **/resources/**/*.py +- **/resources/**/*.groovy +- **/resources/**/*.lua + +If found, these may be loaded and executed at runtime +``` + +## Confidence Determination + +### High Confidence Criteria +Evidence of actual embedded language execution with clear implementation: +- ✅ ScriptEngineManager or ProcessBuilder instantiated with specific parameters +- ✅ Code shows eval() or execute() calls with script content +- ✅ Dependencies include scripting engines (groovy, jython, nashorn) +- ✅ Script files found in resources directory +- ✅ Multiple instances of embedded language usage across codebase + +**Examples**: +- "ScriptEngineManager found in MainController.java:45 with engine.eval(jsCode)" +- "GroovyShell.evaluate() called in RuleEngine.java with 15 .groovy files in resources/" +- "ProcessBuilder executing bash scripts found in 8 locations" + +### Medium Confidence Criteria +Partial evidence or indirect indicators: +- ⚠️ Dependencies include scripting engines but no direct usage found +- ⚠️ Process execution found but limited to standard system commands +- ⚠️ Native library loading present but unclear purpose +- ⚠️ SQL execution detected but mostly using PreparedStatement +- ⚠️ Comments reference scripting but no implementation found + +**Examples**: +- "Groovy dependency in pom.xml but no GroovyShell usage detected" +- "Runtime.exec() called once in utility class for system info" +- "Native library loaded but JNI methods not clearly identified" + +### Low Confidence Criteria +Weak or ambiguous evidence: +- ⚠️ Only standard JDBC operations (no dynamic SQL) +- ⚠️ No scripting dependencies detected +- ⚠️ Process execution in test code only +- ⚠️ Commented-out embedded language code +- ⚠️ Assumptions based on project type + +**Examples**: +- "Standard PreparedStatement usage only, no dynamic SQL" +- "No scripting engine references found" +- "Process execution only in unit tests for test setup" + +### Not Applicable Criteria +When embedded language analysis doesn't apply: +- ❌ Pure Java application with no external language integration +- ❌ Library project with no executable code +- ❌ Static website or documentation-only repository +- ❌ Different platform (e.g., .NET project being analyzed for Java patterns) + +**Examples**: +- "Pure Java Spring Boot REST API with no scripting requirements" +- "Maven plugin project with no runtime execution" +- "Documentation repository with no code" + +## Output Format + +**CRITICAL**: Use the `write_assessment_result` tool (not just output JSON text). + +```json +{ + "input_name": "Embedded Language Usage", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Clear 1-2 sentence summary of embedded language usage}", + "confidence": "high|medium|low", + "evidence": [ + "{Specific file path + line number where usage detected}", + "{Type of embedded language (Groovy, JavaScript, shell, etc.)}", + "{Dependencies or script files found}", + "{Context of usage (business rules, data processing, etc.)}" + ], + "values": [ + "{Scripting engine name and version}", + "{Number of usage instances}", + "{Types of scripts found}", + "{Native libraries loaded}" + ] + }, + "execution_time_seconds": {elapsed_time}, + "timestamp": "{ISO 8601 timestamp}" +} +``` + +**Finding Examples**: +- ✅ Good: "Application uses GroovyShell to execute business rules with 23 .groovy scripts in resources/rules/ directory" +- ✅ Good: "ScriptEngineManager loads Nashorn JavaScript engine to process data transformations in DataProcessor.java" +- ✅ Good: "ProcessBuilder executes shell scripts for deployment automation in 8 service classes" +- ✅ Good: "No embedded language usage detected - pure Java implementation with standard JDBC" +- ❌ Bad: "Scripting is used" +- ❌ Bad: "Found some code execution" + +**Evidence Examples**: +- ✅ Good: "GroovyShell.evaluate() at src/main/java/com/example/rules/RuleEngine.java:67" +- ✅ Good: "groovy-all-2.5.14 dependency in pom.xml with 23 .groovy files in resources/rules/" +- ✅ Good: "ScriptEngineManager initialized in MainController.java:45 with JavaScript engine type" +- ❌ Bad: "Found scripting code" +- ❌ Bad: "Process execution detected" + +## Error Handling + +### 1. No Evidence Found +- Don't fail - report finding as "No embedded language usage detected" +- Set confidence to high if thorough search performed +- Provide reasoning: "Searched for process execution, script engines, and embedded interpreters - none found" + +### 2. Ambiguous Results +- Report what was found with context +- Set confidence to medium +- Explain uncertainty: "Groovy dependency present but no explicit usage found in code" + +### 3. Tool Failures +- If Grep fails, retry with simpler pattern +- If Grep still fails, try Bash with find/grep combination +- If Read fails on large files, try reading with offset/limit +- After 3 retry attempts, return error status with details + +### 4. Large Codebases +- If initial search returns too many results (>500 matches), refine pattern +- Focus on main source directories (exclude test code initially) +- Prioritize by file path (src/main > src/test) +- Sample representative files for detailed analysis + +## Example Complete Analysis + +**Scenario**: Java Spring Boot application with Groovy rule engine + +**Steps Executed**: +1. Grep for ScriptEngine: Found 3 matches in RuleEngine.java +2. Grep for GroovyShell: Found 15 matches across 5 files +3. Glob for .groovy files: Found 23 files in resources/rules/ +4. Read RuleEngine.java: Confirmed GroovyShell usage with dynamic script loading +5. Read pom.xml: Found groovy-all-2.5.14 dependency + +**Result**: +```json +{ + "input_name": "Embedded Language Usage", + "analysis_method": "LLM", + "status": "success", + "result": { + "finding": "Application uses Groovy as embedded scripting engine for business rules execution with 23 rule scripts loaded dynamically at runtime", + "confidence": "high", + "evidence": [ + "GroovyShell.evaluate() at src/main/java/com/example/rules/RuleEngine.java:67-89", + "groovy-all-2.5.14 dependency in pom.xml line 45", + "23 .groovy script files in src/main/resources/rules/ directory", + "RuleLoader.java:34 loads scripts from classpath using ResourceLoader", + "15 GroovyShell usage instances across 5 files in rules package" + ], + "values": [ + "Groovy 2.5.14 (groovy-all)", + "GroovyShell with CompilerConfiguration", + "23 business rule scripts (.groovy)", + "Dynamic rule evaluation at runtime" + ] + }, + "execution_time_seconds": 38.5, + "timestamp": "2026-02-28T10:15:42Z" +} +``` diff --git a/.github/skills/fact-environment-variables/SKILL.md b/.github/skills/fact-environment-variables/SKILL.md new file mode 100644 index 000000000..2cef10d2a --- /dev/null +++ b/.github/skills/fact-environment-variables/SKILL.md @@ -0,0 +1,105 @@ +--- +name: fact-environment-variables +description: Identify container environment variables and configuration +--- + +# Environment Variables Analysis + +## Purpose +Catalog environment variables used in containerized applications for configuration, secrets, and runtime behavior. + +## Target Files/Locations +- **/Dockerfile (ENV instruction) +- **/docker-compose*.yml (environment section) +- **/k8s/**/*.yaml (env, envFrom) +- **/.env, **/.env.example + +## Example Patterns +- `ENV DATABASE_URL=...` +- `environment: - NODE_ENV=production` +- `env: - name: API_KEY` +- `envFrom: - configMapRef` + +## Analysis Steps + +### 1. Check Dockerfile ENV +``` +Use Grep: "^ENV\\s+" +Files: **/Dockerfile +Extract variable names and default values +``` + +### 2. Analyze docker-compose Environment +``` +Use Read: **/docker-compose*.yml +Look for environment: section +Format: KEY=VALUE or array of strings +``` + +### 3. Check Kubernetes ConfigMaps/Secrets +``` +Use Grep: "env:|envFrom:|configMapRef|secretRef" +Files: **/k8s/**/*.yaml +Context: -B 2 -A 5 +``` + +### 4. Check .env Files +``` +Use Glob: **/.env, **/.env.example, **/.env.template +Use Read to list variable names (mask values) +``` + +### 5. Categorize Variables +``` +Group by type: +- Database: DATABASE_URL, DB_HOST, DB_PASSWORD +- API Keys: API_KEY, SECRET_KEY +- Feature Flags: ENABLE_FEATURE_X +- Runtime: NODE_ENV, LOG_LEVEL, DEBUG +``` + +## Confidence Determination + +### High Confidence +- ✅ Variables explicitly defined in multiple files +- ✅ .env.example provides template +- **Example**: "12 environment variables configured including DATABASE_URL, API_KEY, NODE_ENV" + +### Medium Confidence +- ⚠️ Some variables in code but not all documented +- **Example**: "Environment variables used but no .env.example template" + +### Low Confidence +- ⚠️ Variables referenced but not listed +- **Example**: "Application likely uses env vars but none explicitly configured" + +### Not Applicable +- ❌ No container or hardcoded config +- **Example**: "No environment variable usage detected" + +## Output Format + +```json +{ + "input_name": "Environment Variables", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Variables summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Dockerfile ENV count}", + "{docker-compose environment}", + "{K8s ConfigMap/Secret refs}", + "{.env file presence}" + ], + "values": [ + "{Variable names (masked values)}", + "{Categories: database, api, runtime, etc.}", + "{Count: N variables}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-external-dependencies/SKILL.md b/.github/skills/fact-external-dependencies/SKILL.md new file mode 100644 index 000000000..f62559edb --- /dev/null +++ b/.github/skills/fact-external-dependencies/SKILL.md @@ -0,0 +1,124 @@ +--- +name: fact-external-dependencies +description: Identify external system dependencies (SQL Server, Redis, LDAP, File shares) +--- + +# External Dependencies Analysis + +## Purpose +Catalog external systems and services the application depends on including databases, caches, authentication services, and storage. + +## Target Files/Locations +- **/application.{properties,yml} (connection strings) +- **/docker-compose*.yml (external services) +- **/*.env.example (dependency URLs) +- **/README.md (setup instructions) +- **/*.{java,cs,js,py} (connection code) + +## Example Patterns +- **Databases**: SQL Server, PostgreSQL, MySQL, Oracle, MongoDB +- **Caches**: Redis, Memcached, Elasticsearch +- **Auth**: LDAP, Active Directory, OAuth providers +- **Storage**: S3, Azure Blob, NFS, SMB +- **Queues**: RabbitMQ, Kafka, SQS, Azure Service Bus + +## Analysis Steps + +### 1. Check Application Configuration +``` +Use Grep: "datasource|database|jdbc:|connectionString|redis|ldap|s3|blob" +Files: **/application.{properties,yml}, **/appsettings*.json +Context: -B 1 -A 2 + +Extract: +- spring.datasource.url=jdbc:sqlserver://... +- ConnectionStrings:DefaultConnection +- redis.host +- ldap.url +``` + +### 2. Check docker-compose Services +``` +Use Read: **/docker-compose*.yml +Identify services: +- postgres, mysql, sqlserver +- redis, memcached +- rabbitmq, kafka +- elasticsearch + +Note: external vs internal dependencies +``` + +### 3. Check Environment Variables +``` +Use Read: **/.env.example +Look for: +- DATABASE_URL +- REDIS_URL +- LDAP_SERVER +- S3_BUCKET +- API endpoint URLs +``` + +### 4. Check Documentation +``` +Use Read: **/README.md +Look for: +- Prerequisites section +- External services setup +- Configuration instructions +``` + +### 5. Search Code for Connections +``` +Use Grep: "SqlConnection|MongoClient|RedisClient|LdapContext|S3Client" +Files: **/*.{java,cs,js,py} +Context: -B 2 -A 3 +``` + +## Confidence Determination + +### High Confidence +- ✅ Dependencies in config + docker-compose + docs +- ✅ Connection strings present +- **Example**: "External dependencies: SQL Server 2019, Redis 6, LDAP (Active Directory), Azure Blob Storage from config and docs" + +### Medium Confidence +- ⚠️ Dependencies referenced but details incomplete +- **Example**: "Database required (connection string present) but type/version unclear" + +### Low Confidence +- ⚠️ Possible dependencies inferred from code +- **Example**: "May use Redis based on client library dependency" + +### Not Applicable +- ❌ Fully self-contained application +- **Example**: "Standalone application with embedded database, no external dependencies" + +## Output Format + +```json +{ + "input_name": "External Dependencies", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Dependencies summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Configuration entries}", + "{docker-compose services}", + "{Documentation}", + "{Connection code}" + ], + "values": [ + "{Dependency: SQL Server, Redis, etc.}", + "{Versions if known}", + "{Purpose: database, cache, auth, storage}", + "{Count: N external systems}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-external-services/SKILL.md b/.github/skills/fact-external-services/SKILL.md new file mode 100644 index 000000000..96ec40729 --- /dev/null +++ b/.github/skills/fact-external-services/SKILL.md @@ -0,0 +1,93 @@ +--- +name: fact-external-services +description: Identify external service dependencies (Database, Redis, Message queues) +--- + +# External Services Analysis + +## Purpose +Detect external service dependencies like databases, caches, message queues, and other backend services the application connects to. + +## Target Files/Locations +- **/docker-compose*.yml (services section) +- **/k8s/**/*.yaml (Service, StatefulSet) +- **/application.{properties,yml} +- **/.env, **/.env.example +- **/*.{java,cs,js,py} (connection strings) + +## Example Patterns +- `postgres:13`, `redis:alpine`, `rabbitmq:3-management` +- `spring.datasource.url`, `REDIS_URL`, `MONGODB_URI` + +## Analysis Steps + +### 1. Check docker-compose Services +``` +Use Read: **/docker-compose*.yml +Look for services: beyond the main app (postgres, redis, mongo, rabbitmq, elasticsearch, etc.) +``` + +### 2. Analyze Application Configuration +``` +Use Grep: "datasource|database|redis|mongo|rabbit|kafka|elasticsearch" +Files: **/application.{properties,yml} +Context: -B 1 -A 2 +``` + +### 3. Check Environment Variables +``` +Use Grep: "DATABASE_URL|REDIS_URL|MONGO|RABBITMQ|KAFKA" +Files: **/.env.example, **/Dockerfile, **/k8s/**/*.yaml +``` + +### 4. Search for Connection Strings in Code +``` +Use Grep: "jdbc:|redis://|mongodb://|amqp://" +Files: **/*.{java,cs,js,py} +Context: -B 2 -A 1 +``` + +## Confidence Determination + +### High Confidence +- ✅ Services in docker-compose + connection config +- ✅ Connection strings in application config +- **Example**: "External services: PostgreSQL 13, Redis 6, RabbitMQ 3 from docker-compose and connection strings" + +### Medium Confidence +- ⚠️ References to services but no explicit config +- **Example**: "Database referenced in code but connection details unclear" + +### Low Confidence +- ⚠️ Possible service usage, not confirmed +- **Example**: "May use database based on ORM dependency" + +### Not Applicable +- ❌ Standalone app with no external services +- **Example**: "Static file server, no external dependencies" + +## Output Format + +```json +{ + "input_name": "External Services", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Services summary}", + "confidence": "high|medium|low", + "evidence": [ + "{docker-compose services}", + "{Connection configs}", + "{Environment variables}" + ], + "values": [ + "{Service types: PostgreSQL, Redis, etc.}", + "{Versions}", + "{Count: N services}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-hardware-requirements/SKILL.md b/.github/skills/fact-hardware-requirements/SKILL.md new file mode 100644 index 000000000..b789d5a66 --- /dev/null +++ b/.github/skills/fact-hardware-requirements/SKILL.md @@ -0,0 +1,115 @@ +--- +name: fact-hardware-requirements +description: Identify minimum hardware requirements (RAM, CPU, disk) +--- + +# Hardware Requirements Analysis + +## Purpose +Extract minimum hardware requirements from documentation, resource configurations, and deployment files. + +## Target Files/Locations +- **/README.md, **/INSTALL.md, **/REQUIREMENTS.md (system requirements) +- **/docs/**/*.md (hardware mentions) +- **/docker-compose*.yml (resource limits) +- **/k8s/**/*.yaml (resource requests/limits) + +## Example Patterns +- "4GB RAM minimum" +- "2 CPU cores recommended" +- "10GB disk space required" +- `limits: memory: "4Gi", cpu: "2"` + +## Analysis Steps + +### 1. Check Documentation +``` +Use Read: **/README.md, **/INSTALL.md, **/REQUIREMENTS.md +Search for: +- "System Requirements" section +- "Hardware Requirements" section +- RAM/memory mentions (GB, GiB) +- CPU mentions (cores, GHz) +- Disk mentions (GB storage) + +Use Grep: "[0-9]+\\s*(GB|GiB|MB|MiB)|[0-9]+\\s*(cores?|CPU)|disk|storage" +Context: -B 2 -A 2 +``` + +### 2. Check Container Resource Limits +``` +Use Read: **/docker-compose*.yml +Look for deploy.resources.limits/reservations + +Use Grep: "memory:|cpu:" +Files: **/k8s/**/*.yaml +Context: -B 3 -A 1 + +Extract resource specifications: +- Memory: 2Gi, 4Gi, 512Mi +- CPU: 1000m, 2, 500m +``` + +### 3. Analyze Resource Patterns +``` +From K8s/Compose: +- limits = maximum resources +- requests/reservations = minimum required + +Calculate totals for multi-container apps +``` + +### 4. Check Database Requirements +``` +If database used, estimate: +- PostgreSQL: ~1GB RAM minimum +- MySQL: ~512MB RAM minimum +- MongoDB: ~1GB RAM minimum +- Plus storage for data +``` + +## Confidence Determination + +### High Confidence +- ✅ Requirements explicitly documented +- ✅ Resource limits configured match docs +- **Example**: "4GB RAM, 2 CPU cores, 10GB disk from README and matching K8s resource requests" + +### Medium Confidence +- ⚠️ Requirements in one source only +- **Example**: "4GB memory limit in docker-compose, no documentation" + +### Low Confidence +- ⚠️ Requirements estimated from resources used +- **Example**: "Estimated 2GB RAM based on container limits, not documented" + +### Not Applicable +- ❌ Serverless or managed platform +- **Example**: "AWS Lambda deployment, hardware not directly specified" + +## Output Format + +```json +{ + "input_name": "Hardware Requirements", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Hardware summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Documentation sections}", + "{Container resource limits}", + "{Calculations}" + ], + "values": [ + "{RAM: minimum and recommended}", + "{CPU: cores or millicores}", + "{Disk: storage requirements}", + "{Network: if specified}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-health-checks/SKILL.md b/.github/skills/fact-health-checks/SKILL.md new file mode 100644 index 000000000..4c12bd2bf --- /dev/null +++ b/.github/skills/fact-health-checks/SKILL.md @@ -0,0 +1,110 @@ +--- +name: fact-health-checks +description: Identify health check configurations (HTTP checks, command checks) +--- + +# Health Checks Analysis + +## Purpose +Identify health check and readiness probe configurations for monitoring application health. + +## Target Files/Locations +- **/Dockerfile (HEALTHCHECK instruction) +- **/docker-compose*.yml (healthcheck section) +- **/k8s/**/*.yaml (livenessProbe, readinessProbe, startupProbe) +- **/*.{java,cs,js,py,go} (health endpoints) + +## Example Patterns +- `HEALTHCHECK CMD curl -f http://localhost/ || exit 1` +- `healthcheck: test: ["CMD", "curl", "-f", "http://localhost"]` +- `livenessProbe: httpGet: path: /health` + +## Analysis Steps + +### 1. Check Dockerfile HEALTHCHECK +``` +Use Grep: "^HEALTHCHECK" +Files: **/Dockerfile +Parse: CMD, interval, timeout, retries +``` + +### 2. Analyze docker-compose Healthchecks +``` +Use Read: **/docker-compose*.yml +Look for healthcheck: section per service + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost/health"] + interval: 30s + timeout: 10s + retries: 3 +``` + +### 3. Check Kubernetes Probes +``` +Use Grep: "livenessProbe:|readinessProbe:|startupProbe:" +Files: **/k8s/**/*.yaml +Context: -A 10 + +Parse probe types: +- httpGet: path + port +- exec: command +- tcpSocket: port +``` + +### 4. Search for Health Endpoints in Code +``` +Use Grep: "/health|/healthz|/ready|/live|HealthCheck" +Files: **/*.{java,cs,js,py,go} +Context: -B 2 -A 5 + +Common frameworks: +- Spring Boot: /actuator/health +- ASP.NET Core: /health +- Express.js: /health +``` + +## Confidence Determination + +### High Confidence +- ✅ Health checks configured in orchestration files +- ✅ Health endpoint exists in code +- **Example**: "Health checks: HTTP GET /health endpoint with 30s interval, 3 retries" + +### Medium Confidence +- ⚠️ Health check configured but endpoint unclear +- **Example**: "HEALTHCHECK defined using curl but endpoint not verified" + +### Low Confidence +- ⚠️ No explicit health checks configured +- **Example**: "No health checks configured, relies on container exit codes" + +### Not Applicable +- ❌ Simple app with no health monitoring needs +- **Example**: "Batch job, health checks not applicable" + +## Output Format + +```json +{ + "input_name": "Health Checks", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Health checks summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Dockerfile HEALTHCHECK}", + "{docker-compose healthcheck}", + "{K8s probes}", + "{Health endpoint in code}" + ], + "values": [ + "{Check type: HTTP, exec, TCP}", + "{Endpoint: /health, /ready, etc.}", + "{Timing: interval, timeout, retries}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-image-layers/SKILL.md b/.github/skills/fact-image-layers/SKILL.md new file mode 100644 index 000000000..ec7e63aa8 --- /dev/null +++ b/.github/skills/fact-image-layers/SKILL.md @@ -0,0 +1,102 @@ +--- +name: fact-image-layers +description: Analyze container image layer count and structure +--- + +# Image Layers Analysis + +## Purpose +Analyze Dockerfile instructions to understand image layer structure, count of layers, and optimization opportunities. + +## Target Files/Locations +- **/Dockerfile, **/Containerfile + +## Example Patterns +Layer-creating instructions: RUN, COPY, ADD, FROM +Non-layer instructions: ENV, ARG, LABEL, EXPOSE, CMD, ENTRYPOINT, WORKDIR + +## Analysis Steps + +### 1. Count Layer-Creating Instructions +``` +Use Grep to count RUN/COPY/ADD: +- Pattern: "^(RUN|COPY|ADD)\\s+" +- Files: **/Dockerfile, **/Containerfile +- Mode: count + +Each match creates a layer (except multi-stage FROM) +``` + +### 2. Analyze RUN Instruction Complexity +``` +Use Read Dockerfile and analyze: +- Single-command RUN vs multi-command (&&) +- Layer optimization (combined commands) +- Example: RUN apt-get update && apt-get install (1 layer) + vs: RUN apt-get update \n RUN apt-get install (2 layers) +``` + +### 3. Check for Multi-stage Build +``` +Count FROM instructions: +Each stage adds base layers +Final image only includes layers from last stage + COPY --from +``` + +### 4. Identify Layer Size Contributors +``` +Look for large operations: +- Package installations (apt-get, yum, apk) +- File copies (COPY large directories) +- Downloads (wget, curl in RUN) +``` + +## Confidence Determination + +### High Confidence +- ✅ Dockerfile analyzed completely +- ✅ Clear count of layer instructions +- ✅ Multi-stage structure understood +- **Example**: "Image has 8 layers: 3 from base (alpine), 3 RUN, 2 COPY" + +### Medium Confidence +- ⚠️ Some build-time variables affect layers +- ⚠️ External build process unclear +- **Example**: "Approximately 6-8 layers based on Dockerfile instructions" + +### Low Confidence +- ⚠️ Dockerfile uses complex ARGs affecting structure +- ⚠️ BuildKit features that modify layering +- **Example**: "Layer count unclear due to conditional build steps" + +### Not Applicable +- ❌ No Dockerfile +- **Example**: "No container image definition found" + +## Output Format + +```json +{ + "input_name": "Image Layers", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Layer analysis summary}", + "confidence": "high|medium|low", + "evidence": [ + "{RUN instruction count}", + "{COPY/ADD instruction count}", + "{Multi-stage stages}", + "{Optimization patterns observed}" + ], + "values": [ + "{Estimated layer count}", + "{FROM instructions: N}", + "{RUN instructions: N}", + "{COPY/ADD instructions: N}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-image-size/SKILL.md b/.github/skills/fact-image-size/SKILL.md new file mode 100644 index 000000000..64771d061 --- /dev/null +++ b/.github/skills/fact-image-size/SKILL.md @@ -0,0 +1,121 @@ +--- +name: fact-image-size +description: Analyze and estimate container image size +--- + +# Image Size Analysis + +## Purpose +Estimate container image size based on base image, installed packages, and copied files. Identify size optimization opportunities. + +## Target Files/Locations +- **/Dockerfile, **/Containerfile +- Application artifacts to be copied + +## Example Patterns +- Base image (alpine: ~5MB, ubuntu: ~70MB, node:16: ~900MB) +- Package installations (apt, yum, apk) +- Application files (JAR, WAR, binaries) + +## Analysis Steps + +### 1. Identify Base Image Size +``` +Read Dockerfile for FROM instruction +Estimate base sizes: +- scratch: 0MB +- alpine:3.15: ~5MB +- distroless: ~20MB +- ubuntu:20.04: ~70MB +- debian:11: ~120MB +- node:16: ~900MB +- openjdk:11: ~600MB +- mcr.microsoft.com/dotnet/runtime:6.0: ~180MB +``` + +### 2. Analyze Package Installations +``` +Use Grep: "apt-get install|apk add|yum install" +Files: **/Dockerfile +Context: -A 3 + +Estimate: +- Few utilities (curl, wget): +5-10MB +- Build tools (gcc, make): +100-200MB +- Large packages (nginx, postgresql): +50-100MB each +``` + +### 3. Check Application Files Size +``` +For COPY/ADD instructions: +- Look for source paths +- Use Bash to check size: du -sh {source_path} +- Common sizes: + - JAR files: 30-150MB + - Node modules: 100-500MB + - .NET publish: 50-100MB +``` + +### 4. Consider Multi-stage Build Efficiency +``` +If multi-stage: +- Build stage size doesn't matter +- Only final stage COPY --from adds to size +- Final image = base + runtime files only +``` + +### 5. Calculate Estimate +``` +Total = Base + Packages + Application Files + Layer Overhead +Layer overhead: ~10-20% for metadata +``` + +## Confidence Determination + +### High Confidence +- ✅ Base image size known +- ✅ Application files sized via filesystem +- ✅ Package installations enumerated +- **Example**: "Estimated 250MB: alpine (5MB) + Java runtime (150MB) + app JAR (85MB) + dependencies (10MB)" + +### Medium Confidence +- ⚠️ Base image known but packages unclear +- ⚠️ Application size estimated without measurement +- **Example**: "Approximately 200-300MB based on Node.js base and typical app size" + +### Low Confidence +- ⚠️ Complex build process with many layers +- ⚠️ Cannot access application files for sizing +- **Example**: "Likely 100MB-1GB range, difficult to estimate without build" + +### Not Applicable +- ❌ No containerization +- **Example**: "No Dockerfile found" + +## Output Format + +```json +{ + "input_name": "Image Size", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Image size estimate with breakdown}", + "confidence": "high|medium|low", + "evidence": [ + "{Base image and size}", + "{Package installations}", + "{Application files size}", + "{Calculation method}" + ], + "values": [ + "{Estimated total size: XMB or X.XGB}", + "{Base image size}", + "{Application layer size}", + "{Dependencies size}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-language-dependencies/SKILL.md b/.github/skills/fact-language-dependencies/SKILL.md new file mode 100644 index 000000000..eefd957c2 --- /dev/null +++ b/.github/skills/fact-language-dependencies/SKILL.md @@ -0,0 +1,104 @@ +--- +name: fact-language-dependencies +description: Identify language-specific dependencies in container (package.json, requirements.txt, pom.xml) +--- + +# Language Dependencies Analysis + +## Purpose +Identify application-level dependencies through package manifests copied into the container image. + +## Target Files/Locations +- **/package.json, **/package-lock.json (Node.js) +- **/requirements.txt, **/Pipfile (Python) +- **/pom.xml, **/build.gradle (Java) +- **/*.csproj, **/packages.config (.NET) +- **/go.mod, **/go.sum (Go) +- **/Gemfile, **/Gemfile.lock (Ruby) +- **/composer.json (PHP) + +## Example Patterns +- `COPY package*.json ./` +- `RUN pip install -r requirements.txt` +- `RUN npm install --production` +- `RUN mvn clean install` + +## Analysis Steps + +### 1. Identify Copied Dependency Files +``` +Use Grep: "COPY.*(package\\.json|requirements\\.txt|pom\\.xml|.*\\.csproj|go\\.mod|Gemfile|composer\\.json)" +Files: **/Dockerfile +Context: -B 1 -A 1 +``` + +### 2. Read Dependency Files +``` +Use Glob to find dependency files in project: +- **/package.json (read dependencies section) +- **/requirements.txt (read package list) +- **/pom.xml (read <dependencies>) +- **/*.csproj (read <PackageReference>) +``` + +### 3. Count and Categorize Dependencies +``` +For each runtime: +- Node.js: dependencies vs devDependencies +- Python: required packages +- Java: compile, runtime, test scope +- .NET: PackageReference items +- Go: direct vs indirect +``` + +### 4. Check Install Commands +``` +Use Grep: "npm install|pip install|mvn|gradle|dotnet restore|go mod download" +Files: **/Dockerfile +Verify dependencies are installed in image +``` + +## Confidence Determination + +### High Confidence +- ✅ Dependency files copied and installed in Dockerfile +- ✅ Files readable and parseable +- **Example**: "45 Node.js dependencies from package.json installed via npm install" + +### Medium Confidence +- ⚠️ Dependency files exist but install command unclear +- **Example**: "package.json present, installation method not explicit" + +### Low Confidence +- ⚠️ Can't access dependency files +- **Example**: "Dependency files referenced but not readable" + +### Not Applicable +- ❌ No language dependencies (native binary) +- **Example**: "Compiled Go binary with no external dependencies" + +## Output Format + +```json +{ + "input_name": "Language Dependencies", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Dependencies summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Dependency files found}", + "{COPY/install commands}", + "{Dependency count}" + ], + "values": [ + "{Dependency file: package.json, requirements.txt, etc.}", + "{Dependency count}", + "{Key dependencies list}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-licensing-information/SKILL.md b/.github/skills/fact-licensing-information/SKILL.md new file mode 100644 index 000000000..f41f10ea0 --- /dev/null +++ b/.github/skills/fact-licensing-information/SKILL.md @@ -0,0 +1,119 @@ +--- +name: fact-licensing-information +description: Identify software licensing details from LICENSE files and dependency analysis +--- + +# Licensing Information Analysis + +## Purpose +Extract licensing information for the application and its dependencies to understand compliance requirements. + +## Target Files/Locations +- **/LICENSE, **/LICENSE.txt, **/LICENSE.md +- **/pom.xml (<licenses>) +- **/package.json (license field) +- **/*.csproj (<PackageLicenseExpression>) +- **/NOTICE, **/COPYING, **/COPYRIGHT + +## Example Patterns +- MIT License +- Apache License 2.0 +- GPL v3, LGPL +- BSD 3-Clause +- Commercial/Proprietary + +## Analysis Steps + +### 1. Check License Files +``` +Use Glob: **/LICENSE*, **/COPYING, **/COPYRIGHT +Use Read to examine content + +Identify license type: +- MIT: "Permission is hereby granted, free of charge" +- Apache 2.0: "Apache License, Version 2.0" +- GPL: "GNU General Public License" +- BSD: "Redistribution and use in source and binary forms" +``` + +### 2. Check Build File Licenses +``` +Maven (pom.xml): +Use Grep: "<licenses>|<license>" +Extract: <name>Apache License 2.0</name> + +Node.js (package.json): +Use Read and parse: { "license": "MIT" } + +.NET (*.csproj): +Use Grep: "<PackageLicenseExpression>" +Extract: <PackageLicenseExpression>MIT</PackageLicenseExpression> +``` + +### 3. Check Dependency Licenses +``` +Look for license reports: +- **/license-report.html +- **/licenses/ directory +- THIRD-PARTY-NOTICES + +Tools that generate these: +- maven-license-plugin +- license-checker (npm) +- dotnet list package --include-transitive +``` + +### 4. Scan for Commercial Licenses +``` +Use Grep: "commercial|proprietary|all rights reserved|confidential" +Files: **/LICENSE*, **/README.md +Context: -B 2 -A 2 +``` + +## Confidence Determination + +### High Confidence +- ✅ LICENSE file present with clear text +- ✅ License in build file matches LICENSE file +- **Example**: "MIT License confirmed in LICENSE file and package.json" + +### Medium Confidence +- ⚠️ License file present but type unclear +- ⚠️ Multiple licenses mentioned +- **Example**: "LICENSE file present, appears to be MIT but not standard format" + +### Low Confidence +- ⚠️ No LICENSE file, inferred from comments +- **Example**: "No LICENSE file, copyright header suggests proprietary" + +### Not Applicable +- ❌ Internal tool with no license requirement +- **Example**: "Internal company tool, no formal licensing" + +## Output Format + +```json +{ + "input_name": "Licensing Information", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{License summary}", + "confidence": "high|medium|low", + "evidence": [ + "{LICENSE file presence and content}", + "{Build file license declaration}", + "{Dependency licenses if available}", + "{Copyright notices}" + ], + "values": [ + "{Primary license: MIT, Apache 2.0, etc.}", + "{Dependency licenses if scanned}", + "{Copyright holder}", + "{License compatibility notes}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-multi-stage-build/SKILL.md b/.github/skills/fact-multi-stage-build/SKILL.md new file mode 100644 index 000000000..dde08a83c --- /dev/null +++ b/.github/skills/fact-multi-stage-build/SKILL.md @@ -0,0 +1,92 @@ +--- +name: fact-multi-stage-build +description: Check if Dockerfile uses multi-stage build pattern +--- + +# Multi-stage Build Analysis + +## Purpose +Determine if the project uses Docker multi-stage builds for image optimization. + +## Target Files/Locations +- **/Dockerfile, **/Dockerfile.*, **/*.Dockerfile, **/Containerfile + +## Analysis Steps + +### 1. Find Dockerfile(s) +``` +Use Glob: **/Dockerfile, **/Dockerfile.*, **/*.Dockerfile, **/Containerfile +List all matching files +``` + +### 2. Count FROM Instructions +``` +Use Grep: "^FROM\\s+" +Files: (all Dockerfiles found in step 1) + +Count the number of FROM instructions per file: +- 1 FROM = single-stage build +- 2+ FROM = multi-stage build +``` + +### 3. Extract Named Stages +``` +Use Grep: "^FROM\\s+.*\\s+[Aa][Ss]\\s+" +Files: (all Dockerfiles found in step 1) +Context: full line + +Extract stage names from "FROM ... AS stage_name" patterns +``` + +### 4. Verify Stage Usage +``` +Use Grep: "--from=" +Files: (all Dockerfiles found in step 1) + +Check COPY --from=stage_name instructions to verify multi-stage usage +``` + +## Confidence Determination + +### High Confidence +- ✅ Multiple FROM instructions with named stages +- ✅ COPY --from= instructions present +- **Example**: "Multi-stage build detected in Dockerfile with 3 stages (builder, tester, runtime)" + +### Medium Confidence +- ⚠️ Multiple FROM instructions but no named stages +- **Example**: "Multi-stage build with 2 unnamed stages" + +### Low Confidence +- ⚠️ Single FROM instruction +- **Example**: "Single-stage build, no optimization" + +### Not Applicable +- ❌ No Dockerfile found +- **Example**: "No Dockerfile or Containerfile found in project" + +## Output Format + +```json +{ + "input_name": "Multi-stage Build", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Multi-stage build summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Dockerfile locations}", + "{FROM instruction count}", + "{Named stages}" + ], + "values": [ + "{Build type: Multi-stage or Single-stage}", + "{Stage count}", + "{Stage names if available}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-network-settings/SKILL.md b/.github/skills/fact-network-settings/SKILL.md new file mode 100644 index 000000000..268fb17de --- /dev/null +++ b/.github/skills/fact-network-settings/SKILL.md @@ -0,0 +1,90 @@ +--- +name: fact-network-settings +description: Analyze container network configuration (bridge, host, custom networks) +--- + +# Network Settings Analysis + +## Purpose +Identify container networking configuration including network modes, custom networks, and inter-service communication. + +## Target Files/Locations +- **/docker-compose*.yml (networks section) +- **/k8s/**/*.yaml (Service, NetworkPolicy) +- **/Dockerfile (EXPOSE) + +## Example Patterns +- `networks: - frontend - backend` +- `network_mode: bridge|host|none` +- `kind: NetworkPolicy` + +## Analysis Steps + +### 1. Check docker-compose Networks +``` +Use Read: **/docker-compose*.yml +Look for: +- networks: top-level definitions +- service-level network assignments +- network_mode: bridge, host, none, container:name +``` + +### 2. Analyze Kubernetes Networking +``` +Use Grep: "kind: Service|kind: NetworkPolicy|clusterIP|nodePort" +Files: **/k8s/**/*.yaml +Context: -B 1 -A 10 +``` + +### 3. Check for Custom Network Drivers +``` +In docker-compose: +- driver: bridge, overlay, macvlan +- ipam: configuration +- external: true/false +``` + +## Confidence Determination + +### High Confidence +- ✅ Networks explicitly configured +- ✅ Network mode and drivers specified +- **Example**: "Custom bridge network 'app-network' with frontend and backend subnets" + +### Medium Confidence +- ⚠️ Default networking, no custom config +- **Example**: "Uses default bridge network, no custom configuration" + +### Low Confidence +- ⚠️ Networking inferred from service definitions +- **Example**: "Networking likely default, no explicit configuration" + +### Not Applicable +- ❌ Non-networked application +- **Example**: "CLI tool, no network requirements" + +## Output Format + +```json +{ + "input_name": "Network Settings", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Networking summary}", + "confidence": "high|medium|low", + "evidence": [ + "{docker-compose networks}", + "{K8s Services/Policies}", + "{Network mode}" + ], + "values": [ + "{Network names}", + "{Network mode: bridge, host, overlay}", + "{Driver: bridge, overlay, etc.}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-operating-system/SKILL.md b/.github/skills/fact-operating-system/SKILL.md new file mode 100644 index 000000000..57a37dc44 --- /dev/null +++ b/.github/skills/fact-operating-system/SKILL.md @@ -0,0 +1,126 @@ +--- +name: fact-operating-system +description: Identify target/current operating system for deployment +--- + +# Operating System Analysis + +## Purpose +Determine the target or current operating system the application runs on, especially for containerized or cloud-native applications. + +## Target Files/Locations +- **/Dockerfile (FROM base image OS) +- **/README.md, **/docs/**/*.md (system requirements) +- **/k8s/**/*.yaml (nodeSelector, node affinity) +- **/pom.xml, **/*.csproj (target runtime identifiers) + +## Example Patterns +- **Container base**: FROM alpine:3.15, FROM ubuntu:20.04, FROM mcr.microsoft.com/windows/servercore:ltsc2019 +- **.NET RID**: linux-x64, win-x64, osx-x64 +- **Node selector**: kubernetes.io/os: linux + +## Analysis Steps + +### 1. Check Container Base Image OS +``` +Use Grep: "^FROM\\s+" +Files: **/Dockerfile +Extract base image name + +Map to OS: +- alpine → Alpine Linux +- ubuntu → Ubuntu Linux +- debian → Debian Linux +- centos/rocky → CentOS/Rocky Linux +- windows/servercore → Windows Server +- mcr.microsoft.com/windows → Windows +``` + +### 2. Check .NET Runtime Identifiers +``` +Use Grep: "RuntimeIdentifier|<RuntimeIdentifiers>" +Files: **/*.csproj + +RIDs: +- linux-x64 → Linux 64-bit +- linux-arm64 → Linux ARM 64-bit +- win-x64 → Windows 64-bit +- win-arm64 → Windows ARM 64-bit +- osx-x64 → macOS Intel +- osx-arm64 → macOS Apple Silicon +``` + +### 3. Check Kubernetes Node Selectors +``` +Use Grep: "nodeSelector:|kubernetes\\.io/os:" +Files: **/k8s/**/*.yaml +Context: -A 3 + +Values: +- linux → Linux nodes +- windows → Windows nodes +``` + +### 4. Check Documentation +``` +Use Read: **/README.md (first 100 lines) +Look for: +- System Requirements section +- OS mentions (Linux, Windows, macOS) +- Installation instructions per OS +``` + +### 5. Check Platform-Specific Scripts +``` +Use Glob: +- **/*.sh → Linux/macOS +- **/*.ps1, **/*.bat → Windows + +Presence indicates OS support +``` + +## Confidence Determination + +### High Confidence +- ✅ OS explicitly defined in container base or RID +- ✅ Documentation confirms OS +- **Example**: "Target OS: Alpine Linux 3.15 from Dockerfile base image" + +### Medium Confidence +- ⚠️ OS inferred from framework or scripts +- **Example**: "Likely Linux (shell scripts present, typical Java deployment)" + +### Low Confidence +- ⚠️ OS unclear, multiple possibilities +- **Example**: "Cross-platform framework, specific OS deployment unclear" + +### Not Applicable +- ❌ Pure Java/JVM with no OS-specific features +- **Example**: "Platform-independent Java library" + +## Output Format + +```json +{ + "input_name": "Operating System", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{OS summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Container base image}", + "{Runtime identifier}", + "{Documentation}", + "{Scripts}" + ], + "values": [ + "{OS: Alpine Linux, Ubuntu, Windows Server, etc.}", + "{Version: 3.15, 20.04, 2019, etc.}", + "{Architecture: x64, arm64}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-orchestration-tool/SKILL.md b/.github/skills/fact-orchestration-tool/SKILL.md new file mode 100644 index 000000000..00fabf2a4 --- /dev/null +++ b/.github/skills/fact-orchestration-tool/SKILL.md @@ -0,0 +1,96 @@ +--- +name: fact-orchestration-tool +description: Identify container orchestration platform (Docker Compose, Kubernetes, Docker Swarm) +--- + +# Orchestration Tool Analysis + +## Purpose +Determine which container orchestration tool manages the application deployment. + +## Target Files/Locations +- **/docker-compose*.yml (Docker Compose) +- **/k8s/**/*.yaml, **/*.yaml (Kubernetes) +- **/swarm/ (Docker Swarm) +- **/.github/workflows/, **/.gitlab-ci.yml (CI/CD hints) + +## Example Patterns +- Docker Compose: `docker-compose.yml`, `version: '3.8'` +- Kubernetes: `kind: Deployment`, `apiVersion: apps/v1` +- Docker Swarm: `deploy: mode: replicated` + +## Analysis Steps + +### 1. Check for Docker Compose +``` +Use Glob: **/docker-compose*.yml +If found: Docker Compose is used +Check version: '2.x' or '3.x' +``` + +### 2. Check for Kubernetes Manifests +``` +Use Glob: **/k8s/**/*.yaml, **/manifests/**/*.yaml +Use Grep: "apiVersion:.*apps/v1|kind: Deployment|kind: Service" +Files: **/*.yaml +If Kubernetes resources found: K8s is used +``` + +### 3. Check for Docker Swarm Config +``` +Use Grep: "deploy:|mode: replicated|placement:" +Files: **/docker-compose*.yml +Swarm uses Compose format with deploy: section +``` + +### 4. Check CI/CD for Deployment Hints +``` +Use Grep: "kubectl|helm|docker-compose|docker stack" +Files: **/.github/workflows/*.yml, **/.gitlab-ci.yml +Context: -B 2 -A 2 +``` + +## Confidence Determination + +### High Confidence +- ✅ Clear orchestration files present +- ✅ CI/CD deploys using specific tool +- **Example**: "Kubernetes orchestration with 15 manifests in k8s/ directory and kubectl in CI/CD" + +### Medium Confidence +- ⚠️ Files present but usage unclear +- **Example**: "docker-compose.yml for local dev, K8s for production (multiple tools)" + +### Low Confidence +- ⚠️ No clear orchestration indicators +- **Example**: "Single Dockerfile, orchestration unclear" + +### Not Applicable +- ❌ No container orchestration +- **Example**: "Direct Docker run, no orchestration" + +## Output Format + +```json +{ + "input_name": "Orchestration Tool", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Orchestration summary}", + "confidence": "high|medium|low", + "evidence": [ + "{docker-compose.yml presence}", + "{K8s manifest count and location}", + "{CI/CD deployment commands}" + ], + "values": [ + "{Tool: Docker Compose, Kubernetes, Docker Swarm}", + "{Version: Compose 3.8, K8s 1.25, etc.}", + "{Manifest count}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-profile-settings/SKILL.md b/.github/skills/fact-profile-settings/SKILL.md new file mode 100644 index 000000000..9112a6b57 --- /dev/null +++ b/.github/skills/fact-profile-settings/SKILL.md @@ -0,0 +1,332 @@ +--- +name: fact-profile-settings +description: Analyze environment-specific profiles and configuration +--- + +# Profile Settings Analysis + +## Purpose +Identify how the application manages environment-specific configurations (Development, Test, Staging, Production) through profiles, property files, or environment-based settings. This helps understand configuration management complexity and deployment requirements. + +## Target Files/Locations +- **Spring profiles**: **/application-{profile}.{properties,yml}, **/application.{properties,yml} +- **Maven profiles**: **/pom.xml (`<profiles>` section) +- **Gradle profiles**: **/build.gradle, **/build.gradle.kts (buildTypes, productFlavors) +- **Environment configs**: **/config/**, **/environments/**, **/profiles/ +- **Java properties**: **/{env}/*.properties, **/*-{env}.properties +- **.NET configs**: **/appsettings.{Environment}.json, **/web.{config}.config +- **Docker/K8s**: **/docker-compose.{env}.yml, **/k8s/**/*-{env}.yaml +- **CI/CD**: **/.github/workflows/, **/.gitlab-ci.yml, **/Jenkinsfile + +## Example Patterns to Search +- **Spring profiles**: `spring.profiles.active`, `@Profile("dev")`, `application-dev.properties` +- **Maven profiles**: `<profile><id>development</id>`, `<activeByDefault>`, `<activation>` +- **Environment variables**: `${ENV:prod}`, `#{environment}`, `process.env.NODE_ENV` +- **Profile-specific beans**: `@Profile("production")`, `@ConditionalOnProfile` +- **Config file names**: dev, test, staging, uat, prod, production, development + +## Analysis Steps + +### 1. Search for Spring Profile Configuration Files +``` +Use Glob to find Spring profile-specific configs: +- **/application-dev.{properties,yml,yaml} +- **/application-test.{properties,yml,yaml} +- **/application-staging.{properties,yml,yaml} +- **/application-prod.{properties,yml,yaml} +- **/application-production.{properties,yml,yaml} +- **/application-uat.{properties,yml,yaml} +- **/application-local.{properties,yml,yaml} + +Use Read to examine application.properties/yml: +- Check for spring.profiles.active setting +- Look for profile-specific property groups (--- separator in YAML) +- Identify default profile configuration + +Count and categorize profiles found +``` + +### 2. Search for @Profile Annotations in Java Code +``` +Use Grep to find profile usage in code: +Pattern: "@Profile\\(|@ConditionalOnProfile|spring\\.profiles\\." +Files: **/*.java +Context: -B 1 -A 2 + +Analyze: +- Which beans/components are profile-specific +- Profile names used in annotations +- Conditional logic based on profiles +``` + +### 3. Analyze Maven Profile Configuration +``` +Use Glob to find Maven build file: +- **/pom.xml + +Use Read or Grep to search for: +- <profiles> section +- <profile><id> elements (dev, test, prod, etc.) +- <activeByDefault> settings +- <activation> conditions (property, JDK, OS) +- Profile-specific properties, dependencies, plugins + +Example patterns to search: +<profile> + <id>development</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> +</profile> +``` + +### 4. Check Gradle Build Profiles +``` +Use Glob to find Gradle files: +- **/build.gradle +- **/build.gradle.kts + +Use Read to check for: +- buildTypes { debug, release } +- productFlavors { dev, staging, prod } +- Environment-specific configurations +- ext { profile = project.hasProperty('env') ? env : 'dev' } +``` + +### 5. Search for .NET Environment Configurations +``` +Use Glob to find .NET configs: +- **/appsettings.Development.json +- **/appsettings.Staging.json +- **/appsettings.Production.json +- **/web.Development.config +- **/web.Release.config + +Use Grep in .csproj files: +Pattern: "<Environments>|ASPNETCORE_ENVIRONMENT|IHostEnvironment" +``` + +### 6. Check for Environment-Specific Directories +``` +Use Glob to find environment directories: +- **/config/dev/** +- **/config/prod/** +- **/environments/development/** +- **/profiles/** + +Use Bash to list directory structure: +find . -type d -name "dev" -o -name "test" -o -name "prod" -o -name "staging" | head -20 +``` + +### 7. Analyze Docker/K8s Environment Configurations +``` +Use Glob to find container configs: +- **/docker-compose.dev.yml +- **/docker-compose.prod.yml +- **/k8s/dev/**/*.yaml +- **/k8s/production/**/*.yaml +- **/Dockerfile.dev, **/Dockerfile.prod + +Use Grep to find environment variables: +Pattern: "ENV|ENVIRONMENT|PROFILE" +Files: **/Dockerfile, **/docker-compose*.yml +``` + +### 8. Search for CI/CD Environment Configurations +``` +Use Glob to find CI/CD files: +- **/.github/workflows/**/*.yml +- **/.gitlab-ci.yml +- **/Jenkinsfile +- **/azure-pipelines.yml + +Use Read to check for: +- Environment-based job definitions +- Deployment stages (dev, test, prod) +- Environment-specific variables +``` + +### 9. Count and Categorize Profiles +``` +Aggregate all findings: +- List all profile names found +- Count config files per profile +- Identify primary profiles (dev, test, prod) +- Note any custom or unusual profile names +- Check for profile activation logic +``` + +## Confidence Determination + +### High Confidence Criteria +Clear and comprehensive profile configuration: +- ✅ Multiple profile-specific config files found (dev, test, prod) +- ✅ Profile activation mechanism clearly defined +- ✅ Profile-specific beans or components in code +- ✅ Build tool profiles configured (Maven/Gradle) +- ✅ Consistent naming across different config types +- ✅ Environment-specific properties well documented + +**Examples**: +- "Application uses 4 Spring profiles (dev, test, staging, prod) with separate application-{profile}.yml files and @Profile annotations in 12 configuration classes" +- "Maven build configured with 3 profiles (development, testing, production) using different database connections and feature flags per environment" +- ".NET application with appsettings.{Environment}.json for Development, Staging, and Production with ASPNETCORE_ENVIRONMENT detection" + +### Medium Confidence Criteria +Partial profile configuration or unclear structure: +- ⚠️ Some profile files found but incomplete coverage +- ⚠️ Profiles defined but no clear activation mechanism +- ⚠️ Mixed approaches (some Spring, some environment variables) +- ⚠️ Profile names inconsistent across config types +- ⚠️ Only build profiles without runtime profiles (or vice versa) + +**Examples**: +- "Spring profiles for dev and prod found, but test/staging configs missing" +- "Maven profiles defined but no corresponding Spring profile configs" +- "Environment-based configuration exists but profile names vary (dev vs development, prod vs production)" + +### Low Confidence Criteria +Weak or minimal profile evidence: +- ⚠️ Only default configuration, no environment variants +- ⚠️ Profile files exist but appear unused or outdated +- ⚠️ Single-environment application (dev only) +- ⚠️ Hardcoded values instead of profile-based configs +- ⚠️ Profile references in comments but no implementation + +**Examples**: +- "Only application.properties found, no profile-specific configs" +- "Profile files exist but timestamps suggest not used in 2+ years" +- "Comments mention dev/prod configs but actual implementation uses hardcoded values" + +### Not Applicable Criteria +When profile analysis doesn't apply: +- ❌ Simple utility/library with no environment differences +- ❌ Single-purpose tool with no configuration needs +- ❌ Prototype or demo application +- ❌ Different platform with different config approach +- ❌ Configuration managed entirely external (ConfigMap, external config server) + +**Examples**: +- "Command-line utility with no environment-specific behavior" +- "Demo application with hardcoded sample data" +- "Library project with no deployment configuration" + +## Output Format + +**CRITICAL**: Use the `write_assessment_result` tool (not just output JSON text). + +```json +{ + "input_name": "Profile Settings", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Clear 1-2 sentence summary of profile configuration}", + "confidence": "high|medium|low", + "evidence": [ + "{Number and names of profiles identified}", + "{Profile activation mechanism}", + "{Config files per profile}", + "{Code using profile-specific logic}", + "{Build tool profile configuration}" + ], + "values": [ + "{Profile names: dev, test, staging, prod, etc.}", + "{Config file types: properties, yml, json}", + "{Activation method: spring.profiles.active, Maven, env vars}", + "{Number of profile-specific files}", + "{Profile-annotated components count}" + ] + }, + "execution_time_seconds": {elapsed_time}, + "timestamp": "{ISO 8601 timestamp}" +} +``` + +**Finding Examples**: +- ✅ Good: "Application uses comprehensive Spring profile system with 4 environments (dev, test, staging, prod) managed through application-{profile}.yml files and 15 @Profile-annotated configuration classes" +- ✅ Good: ".NET Core application with environment-based configuration using appsettings.{Environment}.json for Development, Staging, and Production environments activated via ASPNETCORE_ENVIRONMENT" +- ✅ Good: "Maven multi-profile build with 3 profiles (development, testing, production) controlling database connections, logging levels, and feature toggles" +- ✅ Good: "No environment profiles detected - single configuration approach suitable for utility application" +- ❌ Bad: "Profiles exist" +- ❌ Bad: "Environment configuration found" + +**Evidence Examples**: +- ✅ Good: "application-dev.yml, application-test.yml, application-staging.yml, application-prod.yml in src/main/resources/" +- ✅ Good: "15 configuration classes with @Profile annotations: @Profile('dev') in DevDatabaseConfig.java, @Profile('prod') in ProdSecurityConfig.java" +- ✅ Good: "Maven pom.xml defines 3 profiles with <id>development</id>, <id>testing</id>, <id>production</id> at lines 120-185" +- ✅ Good: "spring.profiles.active=dev in application.properties, overridable via SPRING_PROFILES_ACTIVE environment variable" +- ❌ Bad: "Configuration files found" +- ❌ Bad: "Profiles detected in code" + +## Error Handling + +### 1. No Profiles Found +- Verify it's not a single-environment application by design +- Check for alternative configuration mechanisms (external config, env vars only) +- Report finding: "No profile-based configuration detected - single configuration model" +- Set confidence to high if thorough search confirms absence + +### 2. Inconsistent Profile Names +- Report all variations found (dev vs development, prod vs production) +- Note potential misconfiguration risks +- Set confidence to medium +- Recommend standardization in evidence notes + +### 3. Partial Profile Implementation +- List which profiles are complete vs incomplete +- Note missing files (e.g., dev and prod exist but no test) +- Set confidence to medium with caveats + +### 4. Mixed Configuration Approaches +- Document each approach found (Spring profiles, Maven profiles, Docker configs) +- Clarify how they interact or if they're independent +- This is common and valid - report comprehensively + +### 5. Tool Failures +- If Glob returns too many results, refine patterns +- If Read fails on large files, use Grep for specific patterns +- After 3 retries, report partial results with notes + +## Example Complete Analysis + +**Scenario**: Spring Boot microservice with comprehensive profile setup + +**Steps Executed**: +1. Glob for Spring configs: Found application-{dev,test,staging,prod}.yml (4 files) +2. Read application.yml: Found spring.profiles.active: dev +3. Grep for @Profile: Found 18 matches in 15 configuration classes +4. Read pom.xml: No Maven profiles (uses Spring profiles only) +5. Checked Docker: Found docker-compose.dev.yml and docker-compose.prod.yml +6. Glob for K8s: Found k8s/dev/ and k8s/prod/ directories with manifests + +**Result**: +```json +{ + "input_name": "Profile Settings", + "analysis_method": "LLM", + "status": "success", + "result": { + "finding": "Application implements comprehensive 4-environment profile system (dev, test, staging, prod) using Spring profiles with separate YAML configs, 15 profile-annotated configuration classes, and environment-specific Docker/Kubernetes manifests", + "confidence": "high", + "evidence": [ + "4 Spring profile configs: application-dev.yml, application-test.yml, application-staging.yml, application-prod.yml in src/main/resources/", + "application.yml sets spring.profiles.active: dev as default, overridable via SPRING_PROFILES_ACTIVE env var", + "15 configuration classes use @Profile annotations: DevDatabaseConfig, ProdSecurityConfig, TestEmailConfig, etc.", + "docker-compose.dev.yml and docker-compose.prod.yml set different SPRING_PROFILES_ACTIVE values", + "Kubernetes manifests in k8s/dev/ and k8s/prod/ directories with environment-specific ConfigMaps", + "Profile-specific settings: database URLs, Redis hosts, feature flags, logging levels" + ], + "values": [ + "4 environments: dev, test, staging, prod", + "Spring profile activation via application.yml and environment variables", + "15 @Profile-annotated configuration classes", + "4 profile-specific YAML files (150-200 lines each)", + "Docker Compose configs for dev and prod", + "Kubernetes ConfigMaps per environment" + ] + }, + "execution_time_seconds": 35.2, + "timestamp": "2026-02-28T10:26:14Z" +} +``` diff --git a/.github/skills/fact-resource-limits/SKILL.md b/.github/skills/fact-resource-limits/SKILL.md new file mode 100644 index 000000000..ec0d4b3b8 --- /dev/null +++ b/.github/skills/fact-resource-limits/SKILL.md @@ -0,0 +1,103 @@ +--- +name: fact-resource-limits +description: Identify CPU/Memory resource limits for containers +--- + +# Resource Limits Analysis + +## Purpose +Identify CPU and memory resource constraints configured for containers through compose files or Kubernetes manifests. + +## Target Files/Locations +- **/docker-compose*.yml (deploy.resources) +- **/k8s/**/*.yaml (resources.requests, resources.limits) +- **/Dockerfile (no resource limits, but checked for context) + +## Example Patterns +- `memory: 2g`, `cpus: '1.5'` +- `limits: memory: "2Gi", cpu: "1000m"` +- `requests: memory: "512Mi", cpu: "250m"` + +## Analysis Steps + +### 1. Check docker-compose Resources +``` +Use Read: **/docker-compose*.yml +Look for deploy.resources section: + deploy: + resources: + limits: + cpus: '2.0' + memory: 2G + reservations: + cpus: '0.5' + memory: 512M +``` + +### 2. Analyze Kubernetes Resources +``` +Use Grep: "resources:|limits:|requests:|memory:|cpu:" +Files: **/k8s/**/*.yaml +Context: -B 3 -A 3 + +Parse format: + resources: + limits: + memory: "2Gi" + cpu: "1000m" + requests: + memory: "512Mi" + cpu: "250m" +``` + +### 3. Check for Resource Quotas +``` +Use Grep: "kind: ResourceQuota" +Files: **/k8s/**/*.yaml +Namespace-level resource constraints +``` + +## Confidence Determination + +### High Confidence +- ✅ Resource limits explicitly configured +- ✅ Both limits and requests defined +- **Example**: "Container limits: 2Gi memory, 1000m CPU; requests: 512Mi memory, 250m CPU" + +### Medium Confidence +- ⚠️ Only limits or only requests defined +- **Example**: "Memory limit 2GB configured, CPU unspecified" + +### Low Confidence +- ⚠️ No explicit resource configuration +- **Example**: "No resource limits configured, uses node defaults" + +### Not Applicable +- ❌ No container orchestration +- **Example**: "Direct Docker run, no resource management" + +## Output Format + +```json +{ + "input_name": "Resource Limits", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Resources summary}", + "confidence": "high|medium|low", + "evidence": [ + "{docker-compose deploy.resources}", + "{K8s limits/requests}", + "{ResourceQuota if present}" + ], + "values": [ + "{Memory limits and requests}", + "{CPU limits and requests}", + "{Units: Gi, Mi, millicores}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-runtime-environment/SKILL.md b/.github/skills/fact-runtime-environment/SKILL.md new file mode 100644 index 000000000..70d33be50 --- /dev/null +++ b/.github/skills/fact-runtime-environment/SKILL.md @@ -0,0 +1,107 @@ +--- +name: fact-runtime-environment +description: Identify application runtime (Node.js, Python, Java, Go, .NET) in container +--- + +# Runtime Environment Analysis + +## Purpose +Detect the application runtime/platform used in containerized applications (Node.js, Python, Java, Go, .NET, Ruby, PHP, etc.). + +## Target Files/Locations +- **/Dockerfile, **/Containerfile (FROM base image) +- **/package.json, **/package-lock.json (Node.js) +- **/pom.xml, **/build.gradle (Java) +- **/*.csproj, **/*.sln (.NET) +- **/requirements.txt, **/Pipfile, **/pyproject.toml (Python) +- **/go.mod (Go) +- **/Gemfile (Ruby) +- **/composer.json (PHP) + +## Example Patterns +- `FROM node:16`, `FROM python:3.9`, `FROM openjdk:11`, `FROM mcr.microsoft.com/dotnet/runtime:6.0` +- `RUN npm install`, `RUN pip install`, `RUN go build`, `RUN dotnet publish` + +## Analysis Steps + +### 1. Analyze Base Image +``` +Use Grep: "FROM\\s+(node|python|openjdk|golang|mcr.microsoft.com/dotnet|ruby|php)" +Files: **/Dockerfile +Extract runtime from base image name +``` + +### 2. Check Build/Install Commands +``` +Use Grep: "npm|pip|maven|gradle|dotnet|go build|bundle|composer" +Files: **/Dockerfile +Context: -B 1 -A 2 +``` + +### 3. Identify Dependency Files +``` +Use Glob to find: +- package.json, package-lock.json (Node.js) +- requirements.txt, Pipfile (Python) +- pom.xml, build.gradle (Java) +- *.csproj, *.sln (.NET) +- go.mod, go.sum (Go) +- Gemfile (Ruby) +- composer.json (PHP) +``` + +### 4. Check Version from Base Image +``` +Parse FROM instruction: +- node:16-alpine → Node.js 16 +- python:3.9-slim → Python 3.9 +- openjdk:11-jre → Java 11 +- mcr.microsoft.com/dotnet/runtime:6.0 → .NET 6 +``` + +## Confidence Determination + +### High Confidence +- ✅ Runtime base image clearly specified +- ✅ Build commands match runtime +- ✅ Dependency files present +- **Example**: "Node.js 16 runtime based on FROM node:16-alpine and package.json" + +### Medium Confidence +- ⚠️ Generic base with runtime installed +- ⚠️ Multi-language project +- **Example**: "Java application, version unclear (uses maven but base is Ubuntu)" + +### Low Confidence +- ⚠️ No clear runtime indicators +- **Example**: "Compiled binary, runtime unclear" + +### Not Applicable +- ❌ No container +- **Example**: "No Dockerfile found" + +## Output Format + +```json +{ + "input_name": "Runtime Environment", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Runtime identified}", + "confidence": "high|medium|low", + "evidence": [ + "{Base image}", + "{Build commands}", + "{Dependency files}" + ], + "values": [ + "{Runtime: Node.js, Python, Java, .NET, Go, etc.}", + "{Version}", + "{Variant: alpine, slim, etc.}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-security-implementation/SKILL.md b/.github/skills/fact-security-implementation/SKILL.md new file mode 100644 index 000000000..7f118bd52 --- /dev/null +++ b/.github/skills/fact-security-implementation/SKILL.md @@ -0,0 +1,142 @@ +--- +name: fact-security-implementation +description: Analyze security measures (HTTPS, Encryption, Token-based auth) +--- + +# Security Implementation Analysis + +## Purpose +Identify security measures implemented in the application including HTTPS, authentication, authorization, encryption, and security headers. + +## Target Files/Locations +- **/application.{properties,yml} (SSL, security configs) +- **/*.java, **/*.cs (security filters, auth) +- **/pom.xml, **/build.gradle, **/*.csproj (security dependencies) +- **/Dockerfile (SSL certificates) +- **/k8s/**/*.yaml (TLS secrets) + +## Example Patterns +- **HTTPS/TLS**: server.ssl.*, SSLContext, TLS certificates +- **Authentication**: JWT, OAuth2, Basic Auth, API keys +- **Authorization**: @PreAuthorize, [Authorize], RBAC +- **Encryption**: AES, RSA, EncryptionService +- **Security Headers**: CORS, CSP, HSTS, X-Frame-Options + +## Analysis Steps + +### 1. Check for HTTPS/TLS Configuration +``` +Use Grep: "server\\.ssl|https://|TLS|SSLContext|keystore" +Files: **/application.{properties,yml}, **/*.java, **/*.cs +Context: -B 2 -A 2 + +Check for: +- server.ssl.key-store +- SSLContext.getInstance("TLS") +- HTTPS redirect configurations +``` + +### 2. Check Authentication Mechanisms +``` +Use Grep: "JWT|OAuth2|@EnableWebSecurity|JwtToken|Bearer|Basic Auth" +Files: **/*.{java,cs,js} +Context: -B 3 -A 3 + +Dependencies: +- spring-boot-starter-security +- Microsoft.AspNetCore.Authentication.JwtBearer +- passport (Node.js) + +Look for: +- @EnableWebSecurity, @PreAuthorize (Spring) +- [Authorize], UseAuthentication() (.NET) +- JWT token generation/validation +``` + +### 3. Check for Authorization +``` +Use Grep: "@PreAuthorize|@Secured|\\[Authorize\\]|hasRole|hasAuthority" +Files: **/*.{java,cs} + +RBAC indicators: +- Role definitions +- Permission checks +- Access control lists +``` + +### 4. Check for Encryption +``` +Use Grep: "AES|RSA|encrypt|decrypt|Cipher|CryptoService" +Files: **/*.{java,cs,py,js} + +Look for: +- Data encryption at rest +- Encryption services +- Key management (KMS, KeyVault) +``` + +### 5. Check for Security Headers +``` +Use Grep: "CORS|Content-Security-Policy|X-Frame-Options|HSTS|Strict-Transport-Security" +Files: **/*.{java,cs,js}, **/application.{properties,yml} + +Spring: WebMvcConfigurer.addCorsMappings +.NET: app.UseCors(), app.UseHsts() +``` + +### 6. Check Dependency Scanning +``` +Look for security scanning: +- Dependabot config +- Snyk, OWASP Dependency Check +- npm audit, dotnet list package --vulnerable +``` + +## Confidence Determination + +### High Confidence +- ✅ Multiple security measures implemented +- ✅ HTTPS + authentication + authorization configured +- **Example**: "HTTPS with TLS 1.3, JWT authentication, role-based authorization, AES encryption for sensitive data" + +### Medium Confidence +- ⚠️ Some security features but incomplete +- **Example**: "Basic authentication configured, HTTPS unclear" + +### Low Confidence +- ⚠️ Security dependencies present but implementation unclear +- **Example**: "Security framework dependency but no explicit configuration found" + +### Not Applicable +- ❌ Internal tool with no security requirements +- **Example**: "Development utility, no security implementation needed" + +## Output Format + +```json +{ + "input_name": "Security Implementation", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Security summary}", + "confidence": "high|medium|low", + "evidence": [ + "{HTTPS/TLS configuration}", + "{Authentication mechanism}", + "{Authorization approach}", + "{Encryption usage}", + "{Security headers}" + ], + "values": [ + "{Transport: HTTPS, TLS 1.2/1.3}", + "{Auth: JWT, OAuth2, Basic}", + "{Authorization: RBAC, attribute-based}", + "{Encryption: AES-256, RSA}", + "{Headers: CORS, CSP, HSTS}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-service-definition/SKILL.md b/.github/skills/fact-service-definition/SKILL.md new file mode 100644 index 000000000..ac3287c5c --- /dev/null +++ b/.github/skills/fact-service-definition/SKILL.md @@ -0,0 +1,108 @@ +--- +name: fact-service-definition +description: Analyze service definition files (docker-compose.yml, K8s manifests) +--- + +# Service Definition Analysis + +## Purpose +Catalog and analyze service definition files that describe how the application is deployed and orchestrated. + +## Target Files/Locations +- **/docker-compose*.yml, **/docker-compose.*.yml +- **/k8s/**/*.yaml, **/manifests/**/*.yaml +- **/helm/**/templates/*.yaml + +## Example Patterns +- Docker Compose services with image, ports, volumes, environment +- Kubernetes Deployments, Services, ConfigMaps, Secrets +- Helm charts with templated manifests + +## Analysis Steps + +### 1. Catalog Docker Compose Files +``` +Use Glob: **/docker-compose*.yml +For each file: +- Count services defined +- Check for extends or depends_on +- Note environment variants (dev, prod) +``` + +### 2. Catalog Kubernetes Manifests +``` +Use Glob: **/k8s/**/*.yaml, **/manifests/**/*.yaml +Use Grep: "kind: Deployment|kind: Service|kind: ConfigMap|kind: Secret" +Files: **/*.yaml +Count by kind + +Group by resource type: +- Workloads: Deployment, StatefulSet, DaemonSet, Job +- Services: Service, Ingress +- Config: ConfigMap, Secret +- Storage: PersistentVolumeClaim +``` + +### 3. Check for Helm Charts +``` +Use Glob: **/Chart.yaml, **/values.yaml +If found: Helm is used +Count template files +``` + +### 4. Analyze Service Complexity +``` +For Compose: +- Single service vs multi-service +- Service dependencies (depends_on) + +For K8s: +- Microservices count +- Service mesh indicators +- Namespace organization +``` + +## Confidence Determination + +### High Confidence +- ✅ Service files present and parseable +- ✅ Clear service structure +- **Example**: "3-service docker-compose with web, api, database services fully configured" + +### Medium Confidence +- ⚠️ Some service files found but structure unclear +- **Example**: "K8s manifests present but relationships between services unclear" + +### Low Confidence +- ⚠️ Service definitions incomplete +- **Example**: "Partial service definitions, missing critical resources" + +### Not Applicable +- ❌ No service definitions +- **Example**: "Single container, no orchestration files" + +## Output Format + +```json +{ + "input_name": "Service Definition", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Service definitions summary}", + "confidence": "high|medium|low", + "evidence": [ + "{File types and counts}", + "{Service/resource counts}", + "{Orchestration approach}" + ], + "values": [ + "{Tool: Compose, K8s, Helm}", + "{Service count}", + "{Resource types and counts}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-servlet-container/SKILL.md b/.github/skills/fact-servlet-container/SKILL.md new file mode 100644 index 000000000..cf206f209 --- /dev/null +++ b/.github/skills/fact-servlet-container/SKILL.md @@ -0,0 +1,310 @@ +--- +name: fact-servlet-container +description: Identify servlet container requirements and version +--- + +# Servlet Container Analysis + +## Purpose +Identify the servlet container (application server) requirements for the application, including Servlet API version, container-specific features, and deployment model. This helps determine migration compatibility and modernization path. + +## Target Files/Locations +- **Deployment descriptors**: **/WEB-INF/web.xml, **/META-INF/weblogic.xml, **/META-INF/jboss-web.xml +- **Build files**: **/pom.xml, **/build.gradle, **/build.gradle.kts +- **Configuration**: **/application.properties, **/application.yml +- **Server configs**: **/server.xml, **/context.xml (Tomcat), **/standalone.xml (JBoss/WildFly) +- **Java source**: **/*Servlet.java, **/*Filter.java, **/*Listener.java + +## Example Patterns to Search +- **Servlet API**: `javax.servlet`, `jakarta.servlet`, `ServletContext`, `HttpServlet` +- **Servlet version**: `<web-app version="3.1"`, `version="4.0"`, `version="5.0"` +- **Container-specific**: `weblogic`, `jboss`, `wildfly`, `tomcat`, `websphere`, `glassfish` +- **Server dependencies**: `provided` scope for servlet-api, tomcat-embed, wildfly-swarm +- **Annotations**: `@WebServlet`, `@WebFilter`, `@WebListener`, `@MultipartConfig` + +## Analysis Steps + +### 1. Analyze web.xml Deployment Descriptor +``` +Use Glob to find web.xml: +- **/WEB-INF/web.xml +- **/META-INF/web.xml + +If found, use Read to examine: +- <web-app> version attribute (2.3, 2.4, 2.5, 3.0, 3.1, 4.0, 5.0, 6.0) +- XSD/DTD namespace for Servlet version + - Java EE 5 (Servlet 2.5): java.sun.com/xml/ns/javaee + - Java EE 6-7 (Servlet 3.0-3.1): xmlns.jcp.org/xml/ns/javaee + - Jakarta EE 8+ (Servlet 4.0+): jakarta.ee/xml/ns/jakartaee +- Servlet definitions and mappings +- Filter configurations +- Container-specific elements +``` + +### 2. Check Build Dependencies for Servlet API +``` +Use Glob to find build files: +- **/pom.xml +- **/build.gradle +- **/build.gradle.kts + +Use Read or Grep to search for: +Maven (pom.xml): +- <artifactId>servlet-api</artifactId> +- <artifactId>javax.servlet-api</artifactId> +- <artifactId>jakarta.servlet-api</artifactId> +- <version>3.1.0</version>, <version>4.0.0</version>, <version>5.0.0</version> +- <scope>provided</scope> (indicates external container) + +Gradle (build.gradle): +- providedCompile 'javax.servlet:javax.servlet-api:3.1.0' +- compileOnly 'jakarta.servlet:jakarta.servlet-api:5.0.0' + +Check for embedded container dependencies: +- spring-boot-starter-web (embedded Tomcat) +- tomcat-embed-core +- jetty-server +- undertow-core +``` + +### 3. Search for Container-Specific Configuration +``` +Use Glob to find container configs: +- **/META-INF/weblogic.xml (Oracle WebLogic) +- **/META-INF/jboss-web.xml (JBoss/WildFly) +- **/META-INF/glassfish-web.xml (GlassFish) +- **/META-INF/geronimo-web.xml (Apache Geronimo) +- **/WEB-INF/ibm-web-ext.xml (IBM WebSphere) + +If found, this indicates container-specific features/requirements +``` + +### 4. Search for Servlet/Filter Implementations +``` +Use Grep to find servlet code: +Pattern: "extends\\s+HttpServlet|implements\\s+Servlet|implements\\s+Filter" +Files: **/*.java +Context: -B 2 -A 5 + +Use Grep to find servlet annotations: +Pattern: "@WebServlet|@WebFilter|@WebListener|@MultipartConfig" +Files: **/*.java +Context: -B 1 -A 3 + +Analyze: +- Count of servlets/filters +- Use of Servlet 3.0+ annotations vs web.xml +- Async servlet support (@WebServlet(asyncSupported=true)) +``` + +### 5. Check for Spring Boot Embedded Container +``` +Use Grep in pom.xml or build.gradle: +Pattern: "spring-boot-starter-web|spring-boot-starter-tomcat|spring-boot-starter-jetty|spring-boot-starter-undertow" + +If found: +- This is embedded container (not external) +- Check application.properties for server configuration + - server.port + - server.servlet.context-path + - server.tomcat.* (if Tomcat) + +Use Glob for Spring Boot config: +- **/application.properties +- **/application.yml +``` + +### 6. Identify Container Version from Dependencies +``` +Parse Maven/Gradle files for exact versions: +- javax.servlet-api: 2.5, 3.0, 3.1 (Java EE) +- jakarta.servlet-api: 4.0 (Jakarta EE 8), 5.0 (Jakarta EE 9), 6.0 (Jakarta EE 10) + +Match to Servlet API specifications: +- Servlet 2.5 = Java EE 5 (Tomcat 6, JBoss 5) +- Servlet 3.0 = Java EE 6 (Tomcat 7, JBoss 7, GlassFish 3) +- Servlet 3.1 = Java EE 7 (Tomcat 8, WildFly 8-10, WebLogic 12c) +- Servlet 4.0 = Java EE 8 / Jakarta EE 8 (Tomcat 9, WildFly 14+) +- Servlet 5.0 = Jakarta EE 9 (Tomcat 10, WildFly 22+) +- Servlet 6.0 = Jakarta EE 10 (Tomcat 10.1+, WildFly 27+) +``` + +### 7. Check for Container-Specific Features +``` +Use Grep to search for container-specific APIs: +- WebLogic: "weblogic\\..*|WorkManager|JMS" +- JBoss/WildFly: "org\\.jboss|org\\.wildfly|EJB" +- WebSphere: "com\\.ibm\\.websphere" +- Tomcat: "org\\.apache\\.catalina|org\\.apache\\.tomcat" + +These indicate tight coupling to specific containers +``` + +## Confidence Determination + +### High Confidence Criteria +Clear and definitive evidence of servlet container requirements: +- ✅ web.xml present with explicit version attribute +- ✅ Servlet API dependency with specific version in build file +- ✅ Container-specific configuration files found +- ✅ Servlet/Filter implementations found in code +- ✅ Clear deployment model (embedded vs external container) + +**Examples**: +- "Web application requires Servlet 3.1 API (Java EE 7) based on web.xml version='3.1' and javax.servlet-api:3.1.0 dependency" +- "Spring Boot application with embedded Tomcat 9.0.65 (Servlet 4.0) from spring-boot-starter-web:2.7.3" +- "WebLogic-specific deployment with weblogic.xml and WorkManager configuration - requires Oracle WebLogic 12c+" + +### Medium Confidence Criteria +Partial evidence or inferred information: +- ⚠️ Servlet API dependency present but no web.xml (annotation-based config) +- ⚠️ Container type inferred from Spring Boot starter but version unclear +- ⚠️ Servlet code found but no explicit version indicators +- ⚠️ Legacy web.xml without version attribute +- ⚠️ Mixed signals (multiple container dependencies) + +**Examples**: +- "Servlet 3.0+ usage inferred from @WebServlet annotations, but no explicit version in dependencies" +- "Spring Boot with default embedded container (likely Tomcat) but version not specified" +- "Servlet implementations found but build file doesn't declare servlet-api dependency explicitly" + +### Low Confidence Criteria +Weak or ambiguous evidence: +- ⚠️ No web.xml or servlet annotations found +- ⚠️ Servlet API in transitive dependencies only +- ⚠️ Container type unclear or multiple possibilities +- ⚠️ Test code has servlet dependencies but main code doesn't +- ⚠️ Comments reference servlets but no actual implementation + +**Examples**: +- "Servlet API appears in dependency tree but no servlet code found" +- "No clear servlet container indicators - may be non-web application" +- "Test dependencies include servlet-api but unclear if production code uses it" + +### Not Applicable Criteria +When servlet container analysis doesn't apply: +- ❌ Non-web application (standalone, batch, CLI tool) +- ❌ REST API using JAX-RS without servlets (Jersey, RESTEasy standalone) +- ❌ Pure reactive application (Spring WebFlux on Netty) +- ❌ Different platform (.NET, Node.js, Python) +- ❌ Library/framework project (no executable component) + +**Examples**: +- "Spring Boot application using WebFlux and Netty - no servlet container required" +- "Standalone Java application with no web components" +- "Node.js Express application - servlet analysis not applicable" + +## Output Format + +**CRITICAL**: Use the `write_assessment_result` tool (not just output JSON text). + +```json +{ + "input_name": "Servlet Container", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Clear 1-2 sentence summary of servlet container requirements}", + "confidence": "high|medium|low", + "evidence": [ + "{web.xml version or absence}", + "{Servlet API dependency with version}", + "{Container-specific files or features}", + "{Deployment model (embedded/external)}", + "{Container type identified}" + ], + "values": [ + "{Servlet API version (e.g., 3.1, 4.0, 5.0)}", + "{Java EE / Jakarta EE version}", + "{Container type and version (if known)}", + "{Number of servlets/filters}", + "{Container-specific features used}" + ] + }, + "execution_time_seconds": {elapsed_time}, + "timestamp": "{ISO 8601 timestamp}" +} +``` + +**Finding Examples**: +- ✅ Good: "Application requires Servlet 3.1 container (Java EE 7) deployed to external WebLogic 12c server with WebLogic-specific WorkManager configuration" +- ✅ Good: "Spring Boot application with embedded Tomcat 9.0.65 (Servlet 4.0 / Jakarta EE 8) managed by spring-boot-starter-web" +- ✅ Good: "Modern Jakarta EE 9 application requiring Servlet 5.0 container (WildFly 22+, Tomcat 10+) with 8 servlets and 5 filters" +- ✅ Good: "Non-web application - no servlet container required (standalone Spring Boot with WebFlux)" +- ❌ Bad: "Uses servlets" +- ❌ Bad: "Container required" + +**Evidence Examples**: +- ✅ Good: "web.xml at WEB-INF/web.xml declares version='3.1' with Java EE 7 namespace" +- ✅ Good: "javax.servlet-api:3.1.0 with <scope>provided</scope> in pom.xml" +- ✅ Good: "weblogic.xml found with WorkManager 'default' configuration" +- ✅ Good: "spring-boot-starter-web:2.7.3 includes tomcat-embed-core:9.0.65" +- ✅ Good: "5 servlets using @WebServlet annotations (Servlet 3.0+ feature)" +- ❌ Bad: "web.xml exists" +- ❌ Bad: "Container dependency found" + +## Error Handling + +### 1. No Servlet Evidence Found +- Check if this is a web application at all +- Search for alternative web frameworks (JAX-RS, Spring WebFlux) +- Report as "not_applicable" if truly not a web app +- If web app with no servlet evidence: low confidence "Unable to determine container requirements" + +### 2. Mixed Servlet API Versions +- Report all versions found with locations +- Set confidence to medium +- Note potential migration status: "Project in transition from javax.servlet to jakarta.servlet" + +### 3. Embedded vs External Container Confusion +- Check for spring-boot packaging (jar vs war) +- Spring Boot jar = embedded, war = external +- Report both possibilities if unclear + +### 4. Tool Failures +- If Grep fails on large pom.xml, use Read with offset/limit +- If XML parsing issues, try grep for version patterns +- After 3 retries, report with caveats + +## Example Complete Analysis + +**Scenario**: Traditional Java EE web application on WebLogic + +**Steps Executed**: +1. Glob for web.xml: Found WEB-INF/web.xml +2. Read web.xml: version="3.1", Java EE 7 namespace +3. Read pom.xml: javax.servlet-api:3.1.0 with provided scope +4. Glob for container configs: Found META-INF/weblogic.xml +5. Grep for servlets: Found 8 servlet classes, 5 filters +6. Grep for container features: Found WorkManager references + +**Result**: +```json +{ + "input_name": "Servlet Container", + "analysis_method": "LLM", + "status": "success", + "result": { + "finding": "Application requires Servlet 3.1 (Java EE 7) container, specifically Oracle WebLogic 12c, with WebLogic-specific features including WorkManager and JMS integration", + "confidence": "high", + "evidence": [ + "web.xml at WEB-INF/web.xml with version='3.1' and Java EE 7 namespace (xmlns.jcp.org/xml/ns/javaee)", + "javax.servlet-api:3.1.0 dependency with <scope>provided</scope> in pom.xml", + "weblogic.xml at META-INF/weblogic.xml with WorkManager configuration", + "8 servlet implementations: AuthServlet, MainServlet, UploadServlet, etc.", + "5 filter implementations including CharacterEncodingFilter and AuthenticationFilter", + "WebLogic-specific API usage: weblogic.jms.* and weblogic.servlet.*" + ], + "values": [ + "Servlet API 3.1", + "Java EE 7", + "Oracle WebLogic 12c (minimum)", + "8 servlets, 5 filters", + "WebLogic WorkManager 'default-workmanager'", + "WAR packaging for external deployment" + ] + }, + "execution_time_seconds": 28.4, + "timestamp": "2026-02-28T10:22:38Z" +} +``` diff --git a/.github/skills/fact-startup-instrumentation/SKILL.md b/.github/skills/fact-startup-instrumentation/SKILL.md new file mode 100644 index 000000000..044800ba3 --- /dev/null +++ b/.github/skills/fact-startup-instrumentation/SKILL.md @@ -0,0 +1,371 @@ +--- +name: fact-startup-instrumentation +description: Analyze startup instrumentation (logging, telemetry, AOP) +--- + +# Startup Instrumentation Analysis + +## Purpose +Detect and analyze logging frameworks, telemetry/APM tools, and aspect-oriented programming (AOP) components initialized at application startup. + +## Analysis Strategy + +This SKILL searches for configuration files, startup code, and dependency declarations to identify instrumentation frameworks. + +## Analysis Steps + +### 1. Logging Framework Detection + +**Search for Logging Configuration Files:** +```bash +# Use Glob to find config files +Glob patterns: +- **/logback.xml, **/logback-spring.xml +- **/log4j2.xml, **/log4j2.yml, **/log4j.properties +- **/appsettings*.json (for Serilog/NLog in .NET) +- **/logging.conf, **/logging.yaml (Python) +- **/winston.config.js (Node.js) +``` + +**Search for Logging Dependencies:** +```bash +# Use Grep to find logging libraries +Pattern: "logback|log4j2|slf4j|serilog|nlog|ilogger|winston|bunyan|pino|logging\.getLogger" +Files: **/pom.xml, **/build.gradle, **/*.csproj, **/package.json, **/requirements.txt, **/Gemfile +``` + +**Search for Logger Initialization in Code:** +```bash +Pattern: "LoggerFactory|ILogger|getLogger|Logger\.getLogger|createLogger|logging\.basicConfig" +Files: **/Program.cs, **/Startup.cs, **/Main.java, **/*Application.java, **/app.py, **/main.py, **/server.js, **/app.js +``` + +### 2. Telemetry & APM Detection + +**Application Insights (.NET/Java):** +```bash +Pattern: "applicationinsights|Microsoft\.ApplicationInsights|TelemetryClient" +Files: **/*.csproj, **/pom.xml, **/appsettings.json, **/ApplicationInsights.config +``` + +**OpenTelemetry (Cross-platform):** +```bash +Pattern: "opentelemetry|otel|TracerProvider|MeterProvider" +Files: **/pom.xml, **/build.gradle, **/*.csproj, **/package.json, **/requirements.txt +``` + +**New Relic:** +```bash +Pattern: "newrelic|New Relic" +Files: **/newrelic.yml, **/newrelic.config, **/newrelic.js +``` + +**Datadog:** +```bash +Pattern: "datadog|dd-trace|ddtrace" +Files: **/pom.xml, **/package.json, **/requirements.txt, **/Gemfile +``` + +**Dynatrace:** +```bash +Pattern: "dynatrace|oneagent" +Files: **/*.config, **/dockerfile, **/deployment.yaml +``` + +**Elastic APM:** +```bash +Pattern: "elastic-apm|ElasticApm" +Files: **/pom.xml, **/*.csproj, **/package.json, **/requirements.txt +``` + +### 3. Aspect-Oriented Programming (AOP) Detection + +**Spring AOP (Java):** +```bash +Pattern: "@Aspect|@Before|@After|@Around|spring-aop|aspectjweaver" +Files: **/*.java, **/pom.xml, **/build.gradle +``` + +**PostSharp (.NET):** +```bash +Pattern: "PostSharp|[MethodInterception]|[OnMethodBoundary]" +Files: **/*.cs, **/*.csproj +``` + +**AspectJ:** +```bash +Pattern: "aspectj|@Pointcut|@Aspect" +Files: **/*.java, **/aop.xml, **/pom.xml +``` + +### 4. Startup Code Analysis + +**Check Main Entry Points:** +```bash +# Use Glob to find entry points +Patterns: +- **/Program.cs (ASP.NET Core) +- **/Startup.cs (ASP.NET Core) +- **/Main.java, **/*Application.java (Spring Boot) +- **/app.py, **/main.py, **/__init__.py (Python) +- **/server.js, **/app.js, **/index.js (Node.js) +``` + +**Analyze Startup Configuration:** +```bash +# Read entry point files and check for: +- Logger configuration: builder.Logging.Add*, LogManager.Setup() +- Telemetry setup: services.AddApplicationInsightsTelemetry() +- AOP configuration: services.EnableAspectOrientedProgramming() +``` + +## Framework-Specific Patterns + +### Java/Spring Boot + +**Logback:** +```xml +<!-- logback-spring.xml --> +<configuration> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + ... +``` +```java +// Code pattern +private static final Logger logger = LoggerFactory.getLogger(Application.class); +``` + +**Log4j2:** +```xml +<!-- log4j2.xml --> +<Configuration status="WARN"> + <Appenders> +``` +```java +private static final Logger logger = LogManager.getLogger(Application.class); +``` + +### .NET/ASP.NET Core + +**Serilog:** +```csharp +// Program.cs +Log.Logger = new LoggerConfiguration() + .WriteTo.Console() + .WriteTo.File("logs/log.txt") + .CreateLogger(); +``` +```json +// appsettings.json +"Serilog": { + "Using": ["Serilog.Sinks.Console", "Serilog.Sinks.File"] +} +``` + +**NLog:** +```csharp +// Program.cs +builder.Logging.ClearProviders(); +builder.Host.UseNLog(); +``` +```xml +<!-- nlog.config --> +<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"> +``` + +**ILogger (Built-in):** +```csharp +builder.Logging.AddConsole(); +builder.Logging.AddDebug(); +builder.Logging.AddApplicationInsights(); +``` + +### Python + +**Logging Module:** +```python +import logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) +``` + +**Loguru:** +```python +from loguru import logger +logger.add("file.log", rotation="500 MB") +``` + +### Node.js + +**Winston:** +```javascript +const winston = require('winston'); +const logger = winston.createLogger({ + transports: [ + new winston.transports.Console(), + new winston.transports.File({ filename: 'combined.log' }) + ] +}); +``` + +**Pino:** +```javascript +const pino = require('pino'); +const logger = pino(); +``` + +## Analysis Decision Logic + +1. **Check for configuration files** → High confidence if config exists +2. **Check for dependencies** → Medium confidence +3. **Check for code usage** → Confirms framework is actively used +4. **Check for multiple frameworks** → List all detected + +## Confidence Levels + +- **High**: Configuration file + dependency + code usage detected +- **Medium**: Dependency + code usage (no explicit config) +- **Low**: Only dependency found (may not be actively used) + +## Output Format + +After analysis, call the MCP tool: + +```javascript +write_assessment_result({ + resultJson: JSON.stringify({ + input_name: "Startup Instrumentation", + analysis_method: "Hybrid", // Code + LLM analysis + status: "success", // or "not_applicable" or "failed" + result: { + finding: "Serilog with Application Insights and custom AOP interceptors", + confidence: "high", // high, medium, or low + evidence: [ + "Found appsettings.json with Serilog configuration (Console, File, Application Insights sinks)", + "Program.cs configures Serilog at line 12: Log.Logger = new LoggerConfiguration()...", + "ApplicationInsights.config found with instrumentation key", + "Custom AOP: Found 3 MethodInterceptionAspect classes for logging, caching, and validation" + ], + values: [ + "Serilog 3.1.1", + "Application Insights", + "Custom AOP (MethodInterception)" + ], + instrumentation_details: { + logging_framework: "Serilog", + logging_version: "3.1.1", + log_sinks: ["Console", "File", "ApplicationInsights"], + telemetry_provider: "Application Insights", + aop_framework: "Custom (MethodInterception)", + startup_file: "Program.cs" + } + }, + execution_time_seconds: 2.8, + timestamp: new Date().toISOString() + }), + assessmentDir: variables.assessment_dir +}); +``` + +## Multiple Framework Examples + +### Example 1: Spring Boot with Logback + Elastic APM + Spring AOP +```json +{ + "finding": "Logback with Elastic APM and Spring AOP", + "confidence": "high", + "evidence": [ + "logback-spring.xml found with RollingFileAppender", + "pom.xml includes elastic-apm-agent 1.39.0", + "Found 8 @Aspect classes for cross-cutting concerns", + "Application.java initializes APM agent at startup" + ], + "values": ["Logback", "Elastic APM 1.39.0", "Spring AOP", "AspectJ"] +} +``` + +### Example 2: Python with Loguru + OpenTelemetry +```json +{ + "finding": "Loguru with OpenTelemetry", + "confidence": "medium", + "evidence": [ + "requirements.txt includes loguru==0.7.0", + "app.py configures loguru with rotation and retention", + "Found opentelemetry-api in requirements.txt", + "No explicit OpenTelemetry initialization code found" + ], + "values": ["Loguru 0.7.0", "OpenTelemetry (partial)"] +} +``` + +### Example 3: Node.js with Winston + Datadog +```json +{ + "finding": "Winston with Datadog APM", + "confidence": "high", + "evidence": [ + "winston.config.js configures Console, File, and HTTP transports", + "package.json includes winston@3.11.0 and dd-trace@4.23.0", + "server.js imports and initializes dd-trace at line 1", + "Found custom Winston format for JSON structured logging" + ], + "values": ["Winston 3.11.0", "Datadog APM 4.23.0"] +} +``` + +## Not Applicable Scenarios + +Return `status: "not_applicable"` if: +- No logging framework detected (using only print/console.log) +- Project is a library without startup entry point +- CLI tool with minimal logging requirements + +Example: +```json +{ + "input_name": "Startup Instrumentation", + "analysis_method": "Code", + "status": "not_applicable", + "result": { + "finding": "No structured logging framework detected", + "confidence": "high", + "evidence": [ + "No logging configuration files found", + "No logging dependencies in package.json", + "Only console.log statements found in code" + ], + "values": [] + }, + "execution_time_seconds": 1.2, + "timestamp": "2026-03-01T01:00:00Z" +} +``` + +## Error Handling + +Return `status: "failed"` if: +- Unable to access project files +- Critical analysis error occurred +- Timeout during file search + +Include error details: +```json +{ + "status": "failed", + "result": { + "finding": "Analysis failed", + "confidence": "low", + "evidence": ["Error: Permission denied reading configuration files"], + "values": [] + } +} +``` + +## Notes + +- Applications often use multiple logging/telemetry tools (e.g., Serilog + Application Insights) +- List all detected frameworks in `values` array +- Prioritize most prominent framework in `finding` +- AOP frameworks are often used for logging interception - include in analysis +- Check both code and configuration for complete picture diff --git a/.github/skills/fact-system-packages/SKILL.md b/.github/skills/fact-system-packages/SKILL.md new file mode 100644 index 000000000..c315120b6 --- /dev/null +++ b/.github/skills/fact-system-packages/SKILL.md @@ -0,0 +1,99 @@ +--- +name: fact-system-packages +description: Identify system packages installed in container (nginx, curl, git, etc.) +--- + +# System Packages Analysis + +## Purpose +Identify OS-level system packages installed in the container image through package manager commands. + +## Target Files/Locations +- **/Dockerfile, **/Containerfile + +## Example Patterns +- `RUN apt-get install nginx curl git` +- `RUN apk add --no-cache ca-certificates tzdata` +- `RUN yum install -y postgresql-client` + +## Analysis Steps + +### 1. Find Package Installation Commands +``` +Use Grep: "apt-get install|apt install|apk add|yum install|dnf install" +Files: **/Dockerfile +Context: -A 5 (capture multi-line installs) +``` + +### 2. Extract Package Names +``` +Parse package manager commands: +- apt: after "install" keyword +- apk: after "add" keyword +- yum/dnf: after "install" keyword + +Handle flags: --no-cache, -y, --no-install-recommends +Handle line continuations with \ +``` + +### 3. Categorize Packages +``` +Group by purpose: +- Web servers: nginx, apache2 +- SSL/Certificates: ca-certificates, openssl +- Development tools: git, curl, wget, vim +- Database clients: postgresql-client, mysql-client +- Build tools: gcc, make, build-essential +- Utilities: tzdata, bash, coreutils +``` + +### 4. Count Total Packages +``` +Sum all packages across all RUN commands +Note if cleanup commands present (apt-get clean, rm -rf /var/lib/apt/lists/*) +``` + +## Confidence Determination + +### High Confidence +- ✅ Package install commands clearly visible +- ✅ Package names explicitly listed +- **Example**: "15 system packages installed: nginx, curl, git, ca-certificates, tzdata, etc." + +### Medium Confidence +- ⚠️ Some packages via install scripts +- **Example**: "Packages installed via apt but list partially in script files" + +### Low Confidence +- ⚠️ Base image includes packages, additions unclear +- **Example**: "Base image may include packages, specific additions unclear" + +### Not Applicable +- ❌ No container or minimal base (scratch, distroless) +- **Example**: "Uses scratch base image with no package manager" + +## Output Format + +```json +{ + "input_name": "System Packages", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Packages summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Package manager commands}", + "{Package count}", + "{Installation patterns}" + ], + "values": [ + "{Package names list}", + "{Categories: web, ssl, dev tools, etc.}", + "{Package manager: apt, apk, yum}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-testing-framework/SKILL.md b/.github/skills/fact-testing-framework/SKILL.md new file mode 100644 index 000000000..97d5e5b9d --- /dev/null +++ b/.github/skills/fact-testing-framework/SKILL.md @@ -0,0 +1,139 @@ +--- +name: fact-testing-framework +description: Analyze testing tools and frameworks used in the project +--- + +# Testing Framework Analysis + +## Purpose +Detect testing frameworks and tools used in the codebase. + +## Target Files/Locations +- **/pom.xml, **/build.gradle, **/build.gradle.kts (Java) +- **/*.csproj (C#/.NET) +- **/package.json (Node.js) +- **/requirements.txt, **/requirements-dev.txt, **/setup.py, **/pyproject.toml (Python) +- **/go.mod (Go) +- **/test/**/*.{java,cs,py,js,ts}, **/*Test.{java,cs}, **/*Tests.cs, **/*.test.{js,ts}, **/*.spec.{js,ts}, **/test_*.py, **/*_test.go + +## Analysis Steps + +### 1. Check Java Testing Frameworks (Maven/Gradle) +``` +Use Grep: "junit-jupiter|<artifactId>junit</artifactId>|testng|mockito" +Files: **/pom.xml, **/build.gradle, **/build.gradle.kts + +Map findings: +- junit-jupiter → JUnit 5 +- <artifactId>junit</artifactId> → JUnit 4 +- testng → TestNG +- mockito → Mockito +``` + +### 2. Check .NET Testing Frameworks +``` +Use Grep: "xunit|nunit|MSTest" +Files: **/*.csproj + +Map findings: +- xunit → xUnit +- nunit → NUnit +- MSTest → MSTest +``` + +### 3. Check Node.js Testing Frameworks +``` +Use Grep: "\"jest\"|\"@types/jest\"|\"mocha\"|\"@types/mocha\"|\"chai\"|\"jasmine\"|\"vitest\"|\"@vitest\"" +Files: **/package.json + +Map findings: +- jest / @types/jest → Jest +- mocha / @types/mocha → Mocha +- chai / @types/chai → Chai +- jasmine / @types/jasmine → Jasmine +- vitest / @vitest → Vitest +``` + +### 4. Check Python Testing Frameworks +``` +Use Grep: "pytest|unittest|nose" +Files: **/requirements.txt, **/requirements-dev.txt, **/setup.py, **/pyproject.toml + +Map findings: +- pytest → pytest +- unittest → unittest +- nose → nose +``` + +### 5. Check Go Testing Frameworks +``` +Use Grep: "testify|ginkgo" +Files: **/go.mod + +Map findings: +- testify → testify +- ginkgo → Ginkgo +``` + +### 6. Count Test Files +``` +Use Glob to find test files: +- **/*Test.java, **/*Test.cs, **/*Tests.cs +- **/*.test.js, **/*.test.ts, **/*.spec.js, **/*.spec.ts +- **/test_*.py, **/*_test.go + +Count matching files for evidence +``` + +### 7. Analyze Test Patterns in Source +``` +Use Grep: "@Test|@TestMethod|\\[Fact\\]|\\[Theory\\]|describe\\(|it\\(|test\\(" +Files: **/*.{java,cs,js,ts,py} +Context: -B 1 -A 2 + +Check for common test annotations/decorators +``` + +## Confidence Determination + +### High Confidence +- ✅ Testing framework dependencies found in build files +- ✅ Test files present with matching annotations +- **Example**: "JUnit 5, Mockito detected in pom.xml; Found 23 test files" + +### Medium Confidence +- ⚠️ Test files found but no explicit framework dependency +- **Example**: "Test files found, framework inferred from annotations" + +### Low Confidence +- ⚠️ Few test files, no framework dependencies +- **Example**: "2 test-like files found, no framework detected" + +### Not Applicable +- ❌ No test files or testing dependencies +- **Example**: "No testing frameworks detected" + +## Output Format + +```json +{ + "input_name": "Testing Framework", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Frameworks summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Build file framework references}", + "{Test file counts}", + "{Test annotation patterns}" + ], + "values": [ + "{Detected frameworks: JUnit 5, Mockito, xUnit, Jest, etc.}", + "{Test file count}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-version-information/SKILL.md b/.github/skills/fact-version-information/SKILL.md new file mode 100644 index 000000000..ee5894325 --- /dev/null +++ b/.github/skills/fact-version-information/SKILL.md @@ -0,0 +1,109 @@ +--- +name: fact-version-information +description: Extract application version from build files and configuration +--- + +# Version Information Analysis + +## Purpose +Identify the application version number from build descriptors, manifests, and configuration files. + +## Target Files/Locations +- **/pom.xml (<version>) +- **/*.csproj (<Version>) +- **/package.json (version field) +- **/build.gradle (version property) +- **/application.{properties,yml} (info.app.version) +- **/AssemblyInfo.cs ([assembly: AssemblyVersion]) + +## Example Patterns +- `<version>1.2.3</version>` (Maven) +- `"version": "2.0.0-beta"` (Node.js) +- `<Version>1.5.0</Version>` (.NET) +- `version = "3.1.4"` (Gradle) + +## Analysis Steps + +### 1. Check Build File Versions +``` +Maven (pom.xml): +Use Grep: "<version>" +Extract first non-parent version + +Gradle (build.gradle): +Use Grep: "^version\\s*=" +Extract: version = '1.2.3' + +Node.js (package.json): +Use Read and parse: { "version": "1.2.3" } + +.NET (*.csproj): +Use Grep: "<Version>" +Extract: <Version>1.2.3</Version> +``` + +### 2. Check Assembly Info +``` +.NET: +Use Grep: "AssemblyVersion|AssemblyFileVersion" +Files: **/AssemblyInfo.cs +Extract: [assembly: AssemblyVersion("1.2.3.4")] +``` + +### 3. Check Application Configuration +``` +Use Grep: "version:|app\\.version|info\\.app\\.version" +Files: **/application.{properties,yml}, **/appsettings.json +``` + +### 4. Check Git Tags +``` +Use Bash: git describe --tags --abbrev=0 +Latest tag often represents version +``` + +## Confidence Determination + +### High Confidence +- ✅ Version explicitly in build file +- ✅ Semantic versioning format (X.Y.Z) +- **Example**: "Application version: 1.2.3 from pom.xml and package.json" + +### Medium Confidence +- ⚠️ Version found but format unusual +- ⚠️ Snapshot/development version +- **Example**: "Version: 2.0.0-SNAPSHOT (development version)" + +### Low Confidence +- ⚠️ No version in files, inferred from git +- **Example**: "Version unclear, git tag suggests 1.0.0" + +### Not Applicable +- ❌ Versioning not used +- **Example**: "No version information found in project" + +## Output Format + +```json +{ + "input_name": "Version Information", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Version summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Source file and location}", + "{Version format}", + "{Git tag if applicable}" + ], + "values": [ + "{Version number: X.Y.Z}", + "{Version type: release, snapshot, beta}", + "{Build/patch number if applicable}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-volume-mounts/SKILL.md b/.github/skills/fact-volume-mounts/SKILL.md new file mode 100644 index 000000000..65d8a57dd --- /dev/null +++ b/.github/skills/fact-volume-mounts/SKILL.md @@ -0,0 +1,96 @@ +--- +name: fact-volume-mounts +description: Identify persistent volume configurations for data storage +--- + +# Volume Mounts Analysis + +## Purpose +Identify persistent storage volumes configured for data persistence, configuration, and logs. + +## Target Files/Locations +- **/Dockerfile** (VOLUME instruction) +- **/docker-compose*.yml** (volumes section) +- **/k8s/**/*.yaml** (volumeMounts, volumes, PersistentVolumeClaim) + +## Example Patterns +- `VOLUME /data /logs` +- `volumes: - ./data:/app/data` +- `mountPath: /var/lib/postgresql/data` + +## Analysis Steps + +### 1. Check Dockerfile VOLUME +``` +Use Grep: "^VOLUME\\s+" +Files: **/Dockerfile +Extract volume paths +``` + +### 2. Analyze docker-compose Volumes +``` +Use Read: **/docker-compose*.yml +Look for volumes: section (both top-level and per-service) +Types: bind mounts, named volumes, tmpfs +``` + +### 3. Check Kubernetes Volumes +``` +Use Grep: "volumeMounts:|volumes:|persistentVolumeClaim" +Files: **/k8s/**/*.yaml +Context: -B 1 -A 5 +``` + +### 4. Categorize Volume Purposes +``` +Group by type: +- Data: /data, /var/lib/postgresql, /var/lib/mysql +- Logs: /logs, /var/log +- Config: /etc/config, /app/config +- Temp: /tmp, /var/tmp +``` + +## Confidence Determination + +### High Confidence +- ✅ Volumes explicitly configured +- ✅ Mount paths and purposes clear +- **Example**: "3 volumes: /data for database, /logs for application logs, /config for runtime config" + +### Medium Confidence +- ⚠️ VOLUME declared but mount points unclear +- **Example**: "Dockerfile declares VOLUME /data but docker-compose doesn't mount it" + +### Low Confidence +- ⚠️ No explicit volumes but app may use storage +- **Example**: "No volumes configured, data likely ephemeral" + +### Not Applicable +- ❌ Stateless application +- **Example**: "Stateless API with no persistent storage" + +## Output Format + +```json +{ + "input_name": "Volume Mounts", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Volumes summary}", + "confidence": "high|medium|low", + "evidence": [ + "{Dockerfile VOLUME}", + "{docker-compose volumes}", + "{K8s PVC/volumes}" + ], + "values": [ + "{Volume paths}", + "{Purposes: data, logs, config}", + "{Volume types: bind, named, PVC}" + ] + }, + "execution_time_seconds": {elapsed}, + "timestamp": "{ISO 8601}" +} +``` diff --git a/.github/skills/fact-xml-configs/SKILL.md b/.github/skills/fact-xml-configs/SKILL.md new file mode 100644 index 000000000..e49ea6bcf --- /dev/null +++ b/.github/skills/fact-xml-configs/SKILL.md @@ -0,0 +1,298 @@ +--- +name: fact-xml-configs +description: Analyze XML configuration files usage in the application +--- + +# XML Configuration Files Analysis + +## Purpose +Identify and catalog XML configuration files used by the application, including Spring context files, Hibernate configurations, web.xml, and other framework-specific XML files. This helps understand configuration management approach and migration requirements. + +## Target Files/Locations +- **Spring Framework**: **/applicationContext*.xml, **/spring-*.xml, **/*-context.xml, **/beans.xml +- **Hibernate ORM**: **/hibernate.cfg.xml, **/*.hbm.xml +- **Java EE/Jakarta EE**: **/web.xml, **/ejb-jar.xml, **/persistence.xml +- **MyBatis**: **/mybatis-config.xml, **/*-mapper.xml +- **Log4j**: **/log4j.xml, **/log4j2.xml +- **Maven**: **/pom.xml +- **Build configs**: **/build.xml (Ant), **/ivy.xml +- **Application configs**: **/config/**/*.xml, **/conf/**/*.xml + +## Example Patterns to Search +- Spring XML config with bean definitions +- Hibernate mapping files (.hbm.xml) +- MyBatis SQL mapper files +- web.xml servlet configurations +- persistence.xml JPA configurations +- log4j.xml or log4j2.xml logging configurations + +## Analysis Steps + +### 1. Search for Spring XML Configuration Files +``` +Use Glob tool to find Spring config files: +- **/applicationContext*.xml +- **/spring-*.xml +- **/*-context.xml +- **/beans.xml +- **/META-INF/spring/**/*.xml + +For each file found: +- Use Read tool to examine first 50 lines +- Check for <beans> root element +- Identify bean definitions, imports, property placeholders +- Note component-scan or annotation-config presence +``` + +### 2. Search for Hibernate Configuration Files +``` +Use Glob tool to find Hibernate files: +- **/hibernate.cfg.xml +- **/*.hbm.xml + +For each file: +- Read to identify database dialect +- Check for entity mappings +- Note session factory configuration +- Identify connection pool settings +``` + +### 3. Search for Java EE/Jakarta EE Deployment Descriptors +``` +Use Glob tool to find Java EE files: +- **/WEB-INF/web.xml +- **/META-INF/ejb-jar.xml +- **/META-INF/persistence.xml +- **/META-INF/application.xml + +Analyze each: +- Servlet/filter configurations (web.xml) +- JPA entity configurations (persistence.xml) +- EJB declarations (ejb-jar.xml) +``` + +### 4. Search for MyBatis Configuration Files +``` +Use Glob tool: +- **/mybatis-config.xml +- **/*-mapper.xml +- **/sqlmap/**/*.xml + +Check for: +- SQL mapper namespaces +- Select/insert/update/delete statements +- Result maps and parameter maps +``` + +### 5. Search for Logging XML Configurations +``` +Use Glob tool: +- **/log4j.xml +- **/log4j2.xml +- **/logback.xml + +Analyze: +- Appender configurations +- Logger level settings +- Output patterns +``` + +### 6. Count and Categorize All XML Files +``` +Use Bash tool to count XML files: +find . -type f -name "*.xml" -not -path "*/target/*" -not -path "*/.git/*" | wc -l + +Use Grep to identify XML configuration files (vs data files): +- Pattern: "<beans|<configuration|<hibernate-configuration|<web-app|<persistence" +- Files: **/*.xml +- Output mode: files_with_matches + +Categorize by framework: +- Spring: beans, context namespaces +- Hibernate: hibernate-configuration, hibernate-mapping +- Java EE: web-app, ejb-jar, persistence-unit +- MyBatis: mapper namespace +- Logging: log4j:configuration, configuration (logback) +``` + +### 7. Analyze XML Complexity and Size +``` +For each significant XML file: +- Use Read to get line count +- Check for external entity references +- Identify property placeholders (${...}) +- Note XSD/DTD schema references +- Check for profiles or conditional configurations +``` + +## Confidence Determination + +### High Confidence Criteria +Clear evidence of XML configuration usage with detailed findings: +- ✅ Multiple XML configuration files identified with specific purposes +- ✅ Framework-specific XML files present (Spring, Hibernate, etc.) +- ✅ Valid XML structure confirmed with proper root elements +- ✅ Bean/entity/mapper definitions clearly visible +- ✅ Relationship between files understood (imports, includes) + +**Examples**: +- "Found 23 Spring XML config files with 450+ bean definitions across applicationContext.xml and imported files" +- "Hibernate configuration with 15 .hbm.xml entity mapping files and hibernate.cfg.xml" +- "Web application with web.xml (Servlet 3.1) and 8 Spring context XML files" + +### Medium Confidence Criteria +Partial evidence or incomplete information: +- ⚠️ XML files found but unclear purpose or usage +- ⚠️ Config files present but may be legacy/unused +- ⚠️ XML files exist alongside annotation-based config (hybrid approach) +- ⚠️ Limited XML usage (only logging or build configs) +- ⚠️ XML files in resources but no clear loading mechanism + +**Examples**: +- "Spring XML files found but @Configuration classes also present (hybrid setup)" +- "Hibernate .hbm.xml files exist but JPA annotations also used" +- "XML files present but timestamps suggest not recently modified" + +### Low Confidence Criteria +Weak or ambiguous evidence: +- ⚠️ Only build tool XML files (pom.xml, build.xml) +- ⚠️ No framework-specific XML configurations +- ⚠️ XML files are data files, not configuration +- ⚠️ Test resources only, no production configs +- ⚠️ Commented-out or example XML files + +**Examples**: +- "Only pom.xml found, no application XML configs" +- "XML files in test resources only, production uses properties/YAML" +- "Sample XML files in documentation directory, not active configs" + +### Not Applicable Criteria +When XML configuration analysis doesn't apply: +- ❌ Pure annotation-based configuration (Spring Boot @Configuration) +- ❌ Configuration via properties/YAML files only +- ❌ Non-Java application (.NET, Node.js, Python) +- ❌ Library project with no configuration requirements +- ❌ Modern application using Java Config exclusively + +**Examples**: +- "Spring Boot application using only @Configuration classes and application.yml" +- ".NET Core application, XML config analysis not applicable" +- "Node.js application with JSON configuration only" + +## Output Format + +**CRITICAL**: Use the `write_assessment_result` tool (not just output JSON text). + +```json +{ + "input_name": "XML Configs", + "analysis_method": "LLM", + "status": "success|not_applicable", + "result": { + "finding": "{Clear 1-2 sentence summary of XML configuration usage}", + "confidence": "high|medium|low", + "evidence": [ + "{Number and types of XML files found}", + "{Specific file paths for major configs}", + "{Framework identifications from XML content}", + "{Configuration patterns observed}" + ], + "values": [ + "{Framework: Spring, Hibernate, MyBatis, etc.}", + "{File count by type}", + "{Key configuration file names}", + "{Schema versions or namespaces}" + ] + }, + "execution_time_seconds": {elapsed_time}, + "timestamp": "{ISO 8601 timestamp}" +} +``` + +**Finding Examples**: +- ✅ Good: "Application uses Spring XML configuration with 18 context files defining 250+ beans, including applicationContext.xml as root config" +- ✅ Good: "Hibernate-based persistence with hibernate.cfg.xml and 12 .hbm.xml entity mapping files for database layer" +- ✅ Good: "Web application with web.xml (Servlet 3.0), 5 Spring XML contexts, and MyBatis mapper files for SQL" +- ✅ Good: "No XML configuration detected - application uses Spring Boot with annotation-based @Configuration classes" +- ❌ Bad: "XML files found" +- ❌ Bad: "Configuration exists" + +**Evidence Examples**: +- ✅ Good: "applicationContext.xml at src/main/resources/ with 45 bean definitions and 3 imported context files" +- ✅ Good: "15 Hibernate mapping files (*.hbm.xml) in src/main/resources/mappings/ for entity persistence" +- ✅ Good: "web.xml at WEB-INF/ defines 8 servlets and 12 filters with Spring DispatcherServlet" +- ✅ Good: "23 MyBatis mapper XML files in resources/mappers/ with SQL definitions" +- ❌ Bad: "Found XML files in project" +- ❌ Bad: "Spring configuration present" + +## Error Handling + +### 1. No XML Configuration Found +- Report finding as "No XML configuration files detected" +- Set confidence to high if thorough search confirmed absence +- Note alternative config approaches if detected (annotations, properties, YAML) + +### 2. Mixed Configuration Approaches +- Report both XML and alternative approaches found +- Set confidence to medium +- List what's configured via XML vs annotations/properties +- Example: "Hybrid approach: Spring XML for legacy beans, @Configuration for new services" + +### 3. Too Many XML Files +- If >100 XML files found, categorize and sample +- Provide statistics by category +- Focus detailed analysis on framework config files +- Note if many are data files vs configuration files + +### 4. Tool Failures +- If Glob returns too many results, refine with more specific patterns +- If Read fails on corrupted XML, note the file but continue +- After 3 retries on critical operations, report partial results with caveats + +### 5. Invalid/Malformed XML +- Note files that appear to be XML but fail parsing +- Don't let malformed files block analysis +- Report count of valid vs invalid XML files found + +## Example Complete Analysis + +**Scenario**: Java Spring MVC application with XML-based configuration + +**Steps Executed**: +1. Glob for Spring XML: Found 18 files (applicationContext.xml + 17 imported) +2. Read applicationContext.xml: Confirmed Spring 4.3 with bean definitions +3. Glob for Hibernate: Found hibernate.cfg.xml and 12 .hbm.xml files +4. Glob for Java EE: Found web.xml in WEB-INF/ +5. Count total XML: 45 XML files in project (excluding target/) +6. Categorized: 18 Spring, 13 Hibernate, 1 Java EE, 8 MyBatis, 2 logging, 3 Maven + +**Result**: +```json +{ + "input_name": "XML Configs", + "analysis_method": "LLM", + "status": "success", + "result": { + "finding": "Application heavily uses XML configuration with 18 Spring context files, 13 Hibernate mappings, and Java EE web.xml for a traditional XML-based architecture", + "confidence": "high", + "evidence": [ + "applicationContext.xml at src/main/resources/ with <beans> root and 45 bean definitions", + "18 Spring XML files with imports: data-context.xml, security-context.xml, service-context.xml, etc.", + "hibernate.cfg.xml and 12 entity mapping files (*.hbm.xml) in resources/mappings/", + "web.xml at WEB-INF/web.xml defines DispatcherServlet and 8 filters (Servlet API 3.0)", + "8 MyBatis mapper XML files in resources/mappers/ with SQL queries", + "log4j.xml configuration for logging with 5 appenders" + ], + "values": [ + "Spring Framework (XML-based config, Spring 4.3 schema)", + "Hibernate ORM (12 .hbm.xml entity mappings)", + "Java EE Servlet 3.0 (web.xml)", + "MyBatis (8 mapper files)", + "45 total XML configuration files", + "Log4j XML configuration" + ] + }, + "execution_time_seconds": 32.8, + "timestamp": "2026-02-28T10:18:15Z" +} +``` diff --git a/.github/skills/integration-tests/SKILL.md b/.github/skills/integration-tests/SKILL.md new file mode 100644 index 000000000..c8e01f131 --- /dev/null +++ b/.github/skills/integration-tests/SKILL.md @@ -0,0 +1,324 @@ +--- +name: integration-tests +description: Run multi-layer integration tests for modernized Java applications. Supports 4 layers - Layer 1 (TestContainers), Layer 2 (Smoke Tests), Layer 3 (Azure Integration), Layer 4 (Behavioral Comparison). **Java projects only** - skip if source code is not Java. +--- + +## Language Support + +**This skill supports Java projects only.** If the source code is not Java (e.g., .NET, Python, Node.js), skip test generation and report that integration tests are not supported for this language. + +## User Input +- **layer** (Optional): Which layer to test (1, 2, 3, or 4). Default: 1 +- **azure-config** (Optional, Layer 3 only): Azure environment configuration +- **modernization-work-folder** (Optional): Directory path for generating plan and summary files. Default: `.github` +- **test-root** (Optional): The root directory for integration tests. Default: current working directory. All application modules found in the directory are included in integration tests. + +## Available references + +### Layer 1: Local Integration Tests +**Read [references/layer1-local-integration.md](references/layer1-local-integration.md) first**, then create TestContainers-based integration test classes. + +### Layer 2: Smoke Tests +**Read [references/layer2-smoke-tests.md](references/layer2-smoke-tests.md) first.** Layer 2 uses shell-based smoke tests with docker-compose, NOT JUnit test classes. Follow the exact multi-commit workflow (artifacts → auth → restore) documented in the reference file. + +### Layer 3: Azure Integration Tests +**Read [references/layer3-azure-integration.md](references/layer3-azure-integration.md) first**, then create integration test classes that connect to real Azure services. + +### Layer 4: Behavioral Comparison +**Read [references/layer4-behavioral-comparison.md](references/layer4-behavioral-comparison.md) first**, then create comparison tests that validate behavior matches between old and new implementations. + +### TestContainers Coding References +- **Azure Service Bus with TestContainers Coding Reference**, see [references/layer1-servicebus-integration.md](references/azure-servicebus-testcontainers.md) +- **Azure Storage with TestContainers Coding Reference**, see [references/layer1-blobstorage-integration.md](references/azure-storage-testcontainers.md) + +## Workflow + +1. Analyze the project to identify modules that need to be tested and any existing integration tests. If git history is available, analyze past commits to understand which components were modified during modernization and prioritize testing those areas. +2. Create an integration test plan file at `{modernization-work-folder}/integration-tests/integration-test-plan.md` that outlines: + - Testing strategy and approach for the detected app modules + - Testing strategy and approach for each layer + - Identified components requiring integration testing + - Dependencies and test setup requirements + - Expected test scenarios and validation criteria +3. Implement new integration tests following the principles outlined below +4. Execute the tests +5. If issues found: + - Analyze failures using the Test vs Source Code Decision Framework to determine whether to fix test code or source code + - Fix source code if the failure indicates a real problem in the application logic. + - Fix test code if the failure is due to unrealistic test scenarios, incorrect test setup. + - Execute tests again after fixes +6. **Only proceed when all tests run and pass**, or exit after 20 attempts +7. Create an integration test summary file at `{modernization-work-folder}/integration-tests/integration-test-summary.md` that documents: + - All integration tests added (with file paths and descriptions) + - Test coverage improvements achieved + - Final test execution results +8. Commit all code changes with brief and meaningful commit messages + +## Integration Tests Writing Principles + +**CRITICAL - Read Reference Docs First:** +- **Before starting ANY layer**, read the corresponding reference file in [references/](./references/) directory + +Analyze the project if integration tests have covered all components, if not **DO ADD** new integration tests by the following principles: + +- **Purpose:** Ensures combined components function as a whole, focusing on "in-between" logic rather than individual module functionality. +- **DO use** top-down approach to add integration tests. For example, if an application has controller layer, service layer, and database layer. The integration tests should set up real connections to the database, and then test against the controller layer, to validate all functionalities. +- **DO focus on:** Validates interactions between modules, databases, messaging services, and file systems. +- **DO NOT** change the technical stack, architure selection, libary using in the source code. The goal is to validate the existing application code, not change it to pass tests. +- **DO fix issues** in the appropriate place (test or source code) based on the analysis. +- **DO write** comprehensive integration covering **ALL** components. +- **DO test through the application's own classes.** Every test must instantiate and invoke the project's own classes/methods. Never call third-party SDK APIs directly as a substitute for testing application code. Tests that only exercise Azure/Redis/PostgreSQL SDK operations without going through the application's handler/service/manager classes will score very low on functional coverage. +- **DO use** the layer-specific class name suffix from the Test Isolation Convention (e.g., `L1Test` for Layer 1, `L3Test` for Layer 3, `L4Test` for Layer 4). **Layer 2 does not use test classes.** +- **DO annotate** every test class with the layer-specific tag/category from the Test Isolation Convention. +- **DO verify** that `mvn verify` (or equivalent build command) discovers and runs all tests without extra flags. If tests require `-Dtest=...` to be found, the build configuration is wrong. +- **DO NOT** leave commented-out tests or dead test code. Every `@Test` annotation must be on a working test method. +- **DO NOT** add extra modules for integration tests, write integration tests in the existing modules. +- **DO commit** changes separately for each layer with meaningful commit messages. Do not combine changes from different layers into a single commit. + - **Layer 1, 3, 4**: Single commit per layer (e.g., `Add Layer 1 local integration tests`). Generate runner scripts and include them in the same commit. + - **Layer 2**: Multi-commit sequence as defined in [layer2-smoke-tests.md](./references/layer2-smoke-tests.md) (artifacts → auth → restore). **CRITICAL: Layer 2 does NOT create test classes - it uses shell-based smoke tests with docker-compose.** Runner scripts are part of the artifacts commit. + + +### Test Isolation Convention + +When multiple layers coexist in the same project, tests must be distinguishable. **Every layer MUST use a distinct class name suffix AND tag/category** so tests from different layers never interfere with each other. + +#### Naming Convention + +| Layer | Class Name Suffix | Example Class Name | +|-------|-------------------|--------------------| +| 1 | `L1Test` | `BlobStorageL1Test`, `OrderServiceL1Test` | +| 2 | N/A - No test classes | Layer 2 uses shell-based smoke tests, not test classes. See [layer2-smoke-tests.md](./references/layer2-smoke-tests.md) | +| 3 | `L3Test` | `AzureSqlL3Test`, `BlobStorageL3Test` | +| 4 | `L4Test` | `OrderApiL4Test`, `UserServiceL4Test` | + +#### Tagging / Category Convention + +Test classes for Layers 1, 3, 4 **MUST** be annotated with a layer-specific tag so the runner script can filter precisely. **Layer 2 does not use test classes** (see [layer2-smoke-tests.md](./references/layer2-smoke-tests.md)). + +| Layer | JUnit 5 | JUnit 4 | +|-------|---------|---------| +| 1 | `@Tag("Layer1")` | `@Category(Layer1.class)` | +| 2 | N/A - Shell-based | N/A - Shell-based | +| 3 | `@Tag("Layer3")` | `@Category(Layer3.class)` | +| 4 | `@Tag("Layer4")` | `@Category(Layer4.class)` | + +> **Rule**: Never rely solely on class name patterns for filtering. Always use tags/categories as the primary filter mechanism. + +### NEVER Mock the Migrated Service + +**This is the most important rule in this entire skill — it applies to ALL layers.** + +Integration tests MUST use real TestContainers for layer 1 and 2 and real cloud services for Layer 3 for every migrated dependency. Do NOT mock or `@MockBean` the SDK client that the migrated code uses (e.g., `ServiceBusTemplate`, `ServiceBusSenderClient`, `BlobServiceClient`, `RedisTemplate`, `DataSource`). Instead, spin up a real container and wire the application's own service to it. + +#### The Anti-Pattern You MUST Avoid + +```java +// ❌ WRONG — mocks the migrated service and SDK clients, tests unchanged code instead +@SpringBootTest +@ActiveProfiles("test") +class MyAppL1Test { + @MockBean private MessageService messageService; // THE MIGRATED CLASS — never tested! + @MockBean private ServiceBusSenderClient senderClient; // should be from real emulator + @MockBean private TokenCredential tokenCredential; // should be from emulator config + @Autowired private UserRepository userRepo; // unchanged code + + @Test void testUserCrud() { + userRepo.save(new User("test")); // tests unchanged code, NOT the migration + } +} +``` + +```java +// ✅ RIGHT — uses real Service Bus emulator, ALL beans wired from containers, tests through migrated service +@SpringBootTest +@ActiveProfiles("test") +@Testcontainers +class MyAppL1Test { + @Container static final GenericContainer<?> SERVICE_BUS = ...; // real emulator + // No @MockBean at all — all beans come from containers + @DynamicPropertySource + @Autowired private MessageService messageService; // THE MIGRATED CLASS — tested for real! + + @DynamicPropertySource + static void props(DynamicPropertyRegistry registry) { + registry.add("spring.cloud.azure.servicebus.connection-string", () -> getConnectionString()); + // ... other container-derived properties + } + + @Test void testSendMessage() { + messageService.sendMessage("queue", "Hello"); // exercises the actual migrated code + } +} +``` + +## Handling Test Failures + +When integration tests fail during execution, use this framework to determine whether to fix the test code or the source code: + +### Fix Source Code When: + +**Business Logic Violations** +- Error indicates source code violates business rules (e.g., negative inventory allowed) +- Multiple similar tests fail with same pattern +**Specification Compliance** +- Source code doesn't implement required functionality properly +- Error messages show missing or incorrect behavior +**Cross-Component Integration Issues** +- Test setup is correct and realistic +- Source code fails to properly communicate between modules +- Data transformation or mapping errors between layers +**Resource Management Problems** +- Test uses proper connection/resource patterns +- Source code has leaks, deadlocks, or improper disposal +- Timing issues in source code (not test race conditions) + +### Fix Test Code When: + +**Test Implementation Issues** +- Unrealistic test data or scenarios +- Incorrect test setup (wrong mocks, invalid configurations) +- Testing implementation details rather than behavior +- Race conditions or timing issues in test logic +**Environmental Problems** +- Wrong container configurations or versions +- Test dependencies not properly isolated +- Hard-coded values that should be configurable +- Test cleanup issues affecting subsequent tests +**Test Design Flaws** +- Tests making too many assumptions about internal state +- Over-mocking leading to false confidence +- Testing edge cases that don't reflect real usage +- Assertions on wrong data or wrong timing + +### Analysis Steps: + +1. **Review Test Quality**: Does the test follow established patterns and realistic scenarios? +2. **Check Business Logic**: Does the failure indicate business rule violations in source code? +3. **Verify Setup**: Are test dependencies and configurations realistic and correct? +4. **Assess Error Type**: Is it a logic error, integration error, or test infrastructure issue? +5. **Consider Impact**: Would fixing source code improve real application behavior? + +### Decision Process: + +``` +Test Failure + │ + ├─ Does test model realistic business scenario? + │ ├─ No → Fix Test Code + │ └─ Yes ↓ + │ + ├─ Does source code violate business rules? + │ ├─ Yes → Fix Source Code + │ └─ No ↓ + │ + ├─ Is test setup and environment correct? + │ ├─ No → Fix Test Code + │ └─ Yes ↓ + │ + └─ Does error show integration/logic problem? + ├─ Yes → Fix Source Code + └─ No → Fix Test Code +``` + +## Standardized Runner Scripts + +After all tests are written, executed, and fixed to pass, generate a fixed runner script so users can re-run integration tests with a single command regardless of project type. + +| Layer | Script Path | Command (Unix) | Command (Windows) | +|-------|-------------|----------------|--------------------|| +| 1 | `{modernization-work-folder}/integration-tests/run-layer1-tests.sh` / `.ps1` | `bash {modernization-work-folder}/integration-tests/run-layer1-tests.sh` | `powershell {modernization-work-folder}/integration-tests/run-layer1-tests.ps1` | +| 2 | `{modernization-work-folder}/integration-tests/run-layer2-tests.sh` / `.ps1` | `bash {modernization-work-folder}/integration-tests/run-layer2-tests.sh` | `powershell {modernization-work-folder}/integration-tests/run-layer2-tests.ps1` | +| 3 | `{modernization-work-folder}/integration-tests/run-layer3-tests.sh` / `.ps1` | `bash {modernization-work-folder}/integration-tests/run-layer3-tests.sh` | `powershell {modernization-work-folder}/integration-tests/run-layer3-tests.ps1` | +| 4 | `{modernization-work-folder}/integration-tests/run-layer4-tests.sh` / `.ps1` | `bash {modernization-work-folder}/integration-tests/run-layer4-tests.sh` | `powershell {modernization-work-folder}/integration-tests/run-layer4-tests.ps1` | + +### Runner Script Requirements + +1. **Always generate both `.sh` and `.ps1` variants** for cross-platform support. +2. The script **MUST** encapsulate all project-specific details (build tool, test runner, filters, working directory, container setup/teardown). +3. The script **MUST** be self-contained — users should not need to know the build system or test framework to run it. +4. The script **MUST** exit with code 0 on success and non-zero on failure. +5. The script **MUST** print a human-readable result summary at the end: + - **On success**: `✅ Layer 1 integration tests PASSED` + - **On failure**: `❌ Layer 1 integration tests FAILED` + - The test runner's own console output already includes detailed counts, failure logs, assertion messages, and stack traces — the script only needs a clear pass/fail signal at the end. +6. For Layer 1, the script **MUST** verify Docker is running before starting tests. +7. For Layer 2, the script **MUST** handle starting and stopping the application. +8. For Layer 3, the script **SHOULD** accept Azure configuration via environment variables. +9. For Layer 4, the script **MUST** handle starting both old and new application versions. + +### Runner Script Filtering + +**Layers 1, 3, 4** use tag/category filters to execute test classes. **Layer 2 uses shell commands** (see [layer2-runner-script-templates.md](./references/layer2-runner-script-templates.md)). + +| Layer | Maven | Gradle | +|-------|-------|--------| +| 1 | `mvn verify -Dgroups=Layer1` | `./gradlew test -Dgroups=Layer1` | +| 2 | Shell-based smoke tests | Shell-based smoke tests | +| 3 | `mvn verify -Dgroups=Layer3` | `./gradlew test -Dgroups=Layer3` | +| 4 | `mvn verify -Dgroups=Layer4` | `./gradlew test -Dgroups=Layer4` | + +### Example Runner Script Structure (Layer 1) + +```bash +#!/bin/bash +set -euo pipefail + +# --- Auto-generated integration test runner --- +# Project type: <detected> +# Generated on: <date> + +# Verify prerequisites +if ! docker info > /dev/null 2>&1; then + echo "ERROR: Docker is not running. Please start Docker and try again." + exit 1 +fi + +# Run integration tests (project-specific command is embedded here) +# IMPORTANT: Always filter by the layer-specific tag to avoid running other layers' tests +# Test output (including any failure logs) goes directly to the console. +cd "$(dirname "$0")/../.." + +<project-specific-test-command> +# e.g., mvn verify -Dgroups=Layer1, ./gradlew test -Dgroups=Layer1 + +TEST_EXIT=$? + +# --- Print summary --- +echo "" +echo "========================================" +if [ $TEST_EXIT -eq 0 ]; then + echo "✅ Layer 1 integration tests PASSED" +else + echo "❌ Layer 1 integration tests FAILED" +fi +echo "========================================" +exit $TEST_EXIT +``` + +> **Note to implementers:** Replace `<project-specific-test-command>` with the real test command for the detected project type (Maven/Gradle). The test runner's own console output already includes detailed results — the script just appends a clear pass/fail signal at the end. + +## Completion Criteria + +1. **Integration Test Plan**: Create and output a plan file at `{modernization-work-folder}/integration-tests/integration-test-plan.md` that includes: + - Analysis of existing test coverage gaps + - Identified components requiring integration testing + - Testing strategy and approach for each component + - Dependencies and test setup requirements + - Expected test scenarios and validation criteria +2. All tests for the requested layer **run and pass**, show the running results to the user +3. Test results are reported with clear pass/fail status +4. Any failures are properly analyzed and resolved (see Handling Test Failures section) +5. Test artifacts (logs, screenshots, comparison reports) are saved + +6. **Version Control**: Commit changes separately for each layer with meaningful commit messages. Do not combine changes from different layers into a single commit. + - **Layer 1, 3, 4**: Single commit per layer including test classes and runner scripts (e.g., `Add Layer 1 local integration tests`) + - **Layer 2**: Multi-commit sequence as defined in [layer2-smoke-tests.md](./references/layer2-smoke-tests.md) (minimum 3 commits: artifacts → auth → restore). Runner scripts are part of the artifacts commit. + - **Git ignore respect**: Use standard `git add` commands. Do not force-add files. If files in `{modernization-work-folder}` are ignored by the project's `.gitignore`, respect that. + +7. **Integration Test Summary**: Create and output a summary file at `{modernization-work-folder}/integration-tests/integration-test-summary.md` that documents: + - All integration tests added (with file paths and descriptions) + - Test coverage improvements achieved + - Issues identified and resolved (both in source code and test code) + - Final test execution results + - Paths to generated runner scripts and the fixed commands to execute them + - Source code changes made during testing and their purpose +8. **Runner Scripts**: Generate standardized runner scripts at `{modernization-work-folder}/integration-tests/run-layer{N}-tests.sh` and `.ps1` (see Standardized Runner Scripts section). The scripts must embed all project-specific commands so users always run the same fixed command. Include runner scripts in the layer's commit (for Layer 2, in the artifacts commit). diff --git a/.github/skills/integration-tests/references/azure-auth-strategies.md b/.github/skills/integration-tests/references/azure-auth-strategies.md new file mode 100644 index 000000000..5300d4636 --- /dev/null +++ b/.github/skills/integration-tests/references/azure-auth-strategies.md @@ -0,0 +1,189 @@ +# Azure Authentication Strategies for Smoke Tests + +Migrated applications typically use **Managed Identity** (`DefaultAzureCredential`) which only works on Azure infrastructure. For local smoke testing, applications must connect to local emulators or have Azure services disabled. + +## Azure Dependency Classification + +Classify each Azure dependency into one of three categories: + +| Category | Smoke Test Strategy | Example Services | +|----------|---------------------|------------------| +| **Emulatable** | Use local emulator with connection string auth | Azurite, Cosmos Emulator, Service Bus Emulator, Event Hubs Emulator | +| **Lazy** | Skip — not validated at startup | On-demand blob uploads, external REST APIs | +| **Startup-required, non-emulatable** | Disable via config, or recommend Layer 3 | Key Vault, App Configuration | + +### Emulatable Azure Services + +These services have official emulators that can run in Docker containers: + +| Azure Service | Emulator Image | Dependencies | +|---------------|----------------|--------------| +| Blob / Queue / Table Storage | `mcr.microsoft.com/azure-storage/azurite` | None | +| Cosmos DB | `mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator` | None (but requires SSL trust store + endpoint/key auth) | +| SQL Database | `mcr.microsoft.com/mssql/server` | None (wire-compatible with SQL Server) | +| Service Bus | `mcr.microsoft.com/azure-messaging/servicebus-emulator` | Requires MSSQL companion + JSON config | +| Event Hubs | `mcr.microsoft.com/azure-messaging/eventhubs-emulator` | Requires Azurite companion + JSON config | + +> **Note:** Service Bus and Event Hubs emulators require companion containers and a JSON config file. See [azure-servicebus-testcontainers.md](./azure-servicebus-testcontainers.md) for the config format. + +**Cosmos DB emulator note:** Unlike other emulators which use connection strings, the Cosmos DB emulator authenticates via **endpoint + account key** and requires an **SSL certificate** imported into a trust store (e.g., `javax.net.ssl.trustStore` for Java). If SSL setup is too complex, treat Cosmos DB as non-emulatable and recommend Layer 3. + +### Lazy Azure Connections + +If an Azure client is only used inside request handlers or scheduled jobs (no `@PostConstruct` / `IHostedService.StartAsync` / health check probing it), it's lazy. **Skip it** — the app starts fine without it. + +**How to identify:** +- Client is injected but never called during startup +- Client is used only in REST endpoint handlers +- Client is used in background jobs that start after initialization + +### Startup-Required, Non-Emulatable Services + +Some Azure services are required at startup but have no local emulator. + +**Resolution strategies (in priority order):** + +1. **Disable via config** — e.g., `spring.cloud.azure.keyvault.secret.enabled=false` or `KeyVault__Enabled=false` with an `if` guard around registration. +2. **Stub the health check** — Skip that health indicator in the smoke profile. +3. **Accept partial startup** — Non-fatal errors are OK for Layer 2 if the app reaches a healthy state. +4. **Skip Layer 2, recommend Layer 3** — If the app cannot start without a real Azure connection. + +## Authentication Modification Strategies + +For each emulatable Azure dependency, modify how the application authenticates: + +### Config-Driven Applications + +**Examples:** Spring Boot applications with `application.properties` or `application.yml`, Quarkus/Micronaut applications with `application.properties` + +**When to use:** Applications that use a configuration framework to externalize settings. These apps read connection strings from config files at runtime. + +**Strategy:** Modify config files to add explicit emulator connection strings. Create or modify the main config file (NOT environment variables, NOT test-only config files). + +**Which config file to modify:** +- Spring Boot: `src/main/resources/application.properties` or `src/main/resources/application.yml` +- Quarkus: `src/main/resources/application.properties` + +**CRITICAL:** You MUST always modify the config file to add the explicit connection string value. Do NOT rely on environment variables. + +**Example:** + +`src/main/resources/application.properties`: +```properties +azure.storage.blob.connection-string=DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://localhost:10000/devstoreaccount1; +spring.data.mongodb.uri=mongodb://localhost:27017/mydb +``` + +**If the application code uses `@Bean` methods or manual client construction:** You may also need to modify the code to read these config properties if it doesn't already. Add code to accept the connection string property with fallback to the original auth. Then add the connection string value to the config file as shown above. + +### Hardcoded/Plain Applications + +**Examples:** Plain Java CLI apps without config frameworks + +**When to use:** Applications that have NO configuration framework (no Spring Boot, no application.properties). These apps construct clients directly in code with hardcoded values. + +**Strategy:** Modify the source code to hardcode emulator connection strings directly in the client construction code. Since these applications don't have config files to modify, the connection string must be in the source code itself to be committed to git. + +**Why hardcoding is required:** +- No config framework means no config files to modify +- Environment variables aren't committed to git, so they won't be reverted by the restore commit +- The auth commit must contain a reversible change in tracked files + +**Java example:** + +**Before:** +```java +public class BlobServiceClientProvider { + private static BlobServiceClient blobServiceClient; + + public static BlobServiceClient getClient() { + if (blobServiceClient == null) { + String endpoint = System.getenv("AZURE_STORAGE_ENDPOINT"); + blobServiceClient = new BlobServiceClientBuilder() + .endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .buildClient(); + } + return blobServiceClient; + } +} +``` + +**After:** +```java +public class BlobServiceClientProvider { + private static BlobServiceClient blobServiceClient; + + public static BlobServiceClient getClient() { + if (blobServiceClient == null) { + // Hardcoded connection string for smoke testing with Azurite emulator + String smokeTestConnectionString = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://localhost:10000/devstoreaccount1;"; + + if (smokeTestConnectionString != null && !smokeTestConnectionString.isEmpty()) { + blobServiceClient = new BlobServiceClientBuilder() + .connectionString(smokeTestConnectionString) + .buildClient(); + } else { + // Fallback to original Managed Identity auth + String endpoint = System.getenv("AZURE_STORAGE_ENDPOINT"); + blobServiceClient = new BlobServiceClientBuilder() + .endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .buildClient(); + } + } + return blobServiceClient; + } +} +``` + +**CRITICAL:** Only the source code changes are included in the auth commit. No config file changes because there are no config files. + +### Non-Emulatable Services + +**Strategy:** Disable via config or conditional guards: + +**Spring Boot example:** +```yaml +# application-smoke.yml +spring: + cloud: + azure: + keyvault: + secret: + enabled: false +``` + +If the app cannot start without the service, recommend Layer 3 (Azure integration tests). + +## Emulator Connection String Values + +Since `docker-compose.smoke.yml` uses **fixed host port mappings**, each emulator's connection string is a **static constant** — deterministic at generation time. + +| Service | Auth Type | How to Determine the Value | +|---------|-----------|----------------------------| +| Azurite (Blob/Queue/Table) | Connection string | Built from well-known account `devstoreaccount1`, well-known key, and mapped ports (10000/10001/10002). See [Azurite docs](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite#well-known-storage-account-and-key). | +| Service Bus | Connection string | Built from well-known SAS key + `UseDevelopmentEmulator=true`. See [Service Bus emulator docs](https://learn.microsoft.com/en-us/azure/service-bus-messaging/test-locally-with-service-bus-emulator). | +| Event Hubs | Connection string | Same pattern as Service Bus. See [Event Hubs emulator docs](https://learn.microsoft.com/en-us/azure/event-hubs/test-locally-with-event-hub-emulator). | +| Cosmos DB | Endpoint + key | Built from well-known emulator key + mapped port. See [Cosmos emulator docs](https://learn.microsoft.com/en-us/azure/cosmos-db/emulator). Also requires SSL trust store setup. | + +**Important:** The agent must look up the **actual current default credentials** from the linked official docs at generation time. Emulator defaults may change across versions. Do NOT hardcode connection strings from this file. + +## Decision Flow + +``` +For each Azure dependency: +├─ Has local emulator? → Add to docker-compose.smoke.yml → Modify auth to use emulator +├─ Lazy / on-demand? → Skip. Done. +├─ Can disable via config? → Disable in config override or code modification +└─ None of above → Report: "Layer 2 not feasible — use Layer 3" +``` + +## Modification Rules + +When modifying application code or config to use emulators: + +1. **Minimal changes only** — Only modify what's needed to switch auth from Managed Identity to emulator connection strings. Do not refactor, rename, or restructure. +2. **No new dependencies** — Use only packages already in the project. +3. **Reversible** — Changes should be easily revertable to restore original Managed Identity auth. +4. **No unrelated changes** — Never make refactoring, cleanup, or feature changes alongside auth modifications. diff --git a/.github/skills/integration-tests/references/azure-servicebus-testcontainers.md b/.github/skills/integration-tests/references/azure-servicebus-testcontainers.md new file mode 100644 index 000000000..50b596322 --- /dev/null +++ b/.github/skills/integration-tests/references/azure-servicebus-testcontainers.md @@ -0,0 +1,688 @@ +# Azure Service Bus Emulator TestContainers Coding Reference + +## Contents +- 1. MANDATORY - Choose Approach based on Spring/non-Spring, Spring Boot version, TestContainers version +- 2. MANDATORY - Scan all queues/topics/subscriptions before writing code +- 3. DO NOT mock +- 4. Example of Service Bus Emulator config.json +- 5. Spring Cloud Azure Version Compatibility +- 6. Emulator with ServiceBusEmulatorContainer (testcontainers >= 1.20.5) + + Setting up a network + + Starting a SQL Server container as dependency + + Starting a Service Bus Emulator container + + Using Azure Service Bus clients +- 7. Emulator with GenericContainer (testcontainers < 1.20.5) +- 8. Using Spring Cloud Azure with @ServiceConnection (Spring Boot >= 3.1) + + Container setup with @ServiceConnection + + Spring messaging pattern (ServiceBusTemplate / ServiceBusSenderClient) +- 9. Spring Boot 2.x Pattern +- 10. Handle ServiceBusAdministrationClient +- 11. Emulator Readiness and Retry +- 12. Emulator fails to start +- 13. Common Gotchas + +## MANDATORY - Choose Approach based on Spring/non-Spring, Spring Boot version, TestContainers version + +**You MUST check the project's testcontainers and Spring Boot versions BEFORE writing any Service Bus test code.** Using the wrong approach wastes significant time on compilation and runtime failures that are impossible to fix. + +- If project contains usage of `ServiceBusAdministrationClient`, use Service Bus emulator +- If Spring Boot **>= 3.1**, use `@ServiceConnection` for auto-wiring: [Using Spring Cloud Azure with @ServiceConnection](#using-spring-cloud-azure-with-serviceconnection-spring-boot--31) +- If Spring Boot **2.x**, use `@DynamicPropertySource` — `@ServiceConnection` is NOT available: [Spring Boot 2.x pattern](#spring-boot-2x-pattern) +- If testcontainers **>= 1.20.5**, use `ServiceBusEmulatorContainer` from `org.testcontainers:azure`: [Emulator with ServiceBusEmulatorContainer](#emulator-with-servicebusemulatorcontainer-testcontainers--1205) +- If testcontainers **< 1.20.5**, use `GenericContainer` with the emulator Docker image: [Emulator with GenericContainer](#emulator-with-genericcontainer-testcontainers--1205) + +**CRITICAL: `ServiceBusEmulatorContainer` does NOT exist in testcontainers before 1.20.5.** If you see `ClassNotFoundException` or `cannot find symbol: class ServiceBusEmulatorContainer`, the project's testcontainers version is too old. Switch to the GenericContainer approach or upgrade testcontainers. The Maven artifact is `org.testcontainers:azure` (NOT `testcontainers-azure`). + +## MANDATORY - Scan all queues/topics/subscriptions before writing code +The Service Bus emulator cannot create Service Bus queues/topics/subscriptions on the fly, so every resource need to be declared in the config.json. So scan the project to see what queues/topics/subscriptions need to be declared. And then define them in config.json. + +## Do NOT mock +**NEVER MOCK** the `ServiceBusSenderClient`, `ServiceBusTemplate`, `ServiceBusReceiverClient`, `ServiceBusProcessorClient`, `TokenCredential`, `ServiceBusAdministrationClient`, or **ANY bean related to the migrated service.** + +## Example of Service Bus Emulator config.json +Place this file at `src/test/resources/config.json` (or `service-bus-config.json`): + +```json +{ + "UserConfig": { + "Namespaces": [ + { + "Name": "sbemulatorns", + "Queues": [ + { + "Name": "queue.1", + "Properties": { + "DeadLetteringOnMessageExpiration": false, + "DefaultMessageTimeToLive": "PT1H", + "DuplicateDetectionHistoryTimeWindow": "PT20S", + "ForwardDeadLetteredMessagesTo": "", + "ForwardTo": "", + "LockDuration": "PT1M", + "MaxDeliveryCount": 3, + "RequiresDuplicateDetection": false, + "RequiresSession": false + } + } + ], + + "Topics": [ + { + "Name": "topic.1", + "Properties": { + "DefaultMessageTimeToLive": "PT1H", + "DuplicateDetectionHistoryTimeWindow": "PT20S", + "RequiresDuplicateDetection": false + }, + "Subscriptions": [ + { + "Name": "subscription.1", + "Properties": { + "DeadLetteringOnMessageExpiration": false, + "DefaultMessageTimeToLive": "PT1H", + "LockDuration": "PT1M", + "MaxDeliveryCount": 3, + "ForwardDeadLetteredMessagesTo": "", + "ForwardTo": "", + "RequiresSession": false + }, + "Rules": [ + { + "Name": "app-prop-filter-1", + "Properties": { + "FilterType": "Correlation", + "CorrelationFilter": { + "ContentType": "application/text", + "CorrelationId": "id1", + "Label": "subject1", + "MessageId": "msgid1", + "ReplyTo": "someQueue", + "ReplyToSessionId": "sessionId", + "SessionId": "session1", + "To": "xyz" + } + } + } + ] + }, + { + "Name": "subscription.2", + "Properties": { + "DeadLetteringOnMessageExpiration": false, + "DefaultMessageTimeToLive": "PT1H", + "LockDuration": "PT1M", + "MaxDeliveryCount": 3, + "ForwardDeadLetteredMessagesTo": "", + "ForwardTo": "", + "RequiresSession": false + }, + "Rules": [ + { + "Name": "user-prop-filter-1", + "Properties": { + "FilterType": "Correlation", + "CorrelationFilter": { + "Properties": { + "prop1": "value1" + } + } + } + } + ] + }, + { + "Name": "subscription.3", + "Properties": { + "DeadLetteringOnMessageExpiration": false, + "DefaultMessageTimeToLive": "PT1H", + "LockDuration": "PT1M", + "MaxDeliveryCount": 3, + "ForwardDeadLetteredMessagesTo": "", + "ForwardTo": "", + "RequiresSession": false + } + }, + { + "Name": "subscription.4", + "Properties": { + "DeadLetteringOnMessageExpiration": false, + "DefaultMessageTimeToLive": "PT1H", + "LockDuration": "PT1M", + "MaxDeliveryCount": 3, + "ForwardDeadLetteredMessagesTo": "", + "ForwardTo": "", + "RequiresSession": false + }, + "Rules": [ + { + "Name": "sql-filter-1", + "Properties": { + "FilterType": "Sql", + "SqlFilter": { + "SqlExpression": "sys.MessageId = '123456' AND userProp1 = 'value1'" + }, + "Action" : { + "SqlExpression": "SET sys.To = 'Entity'" + } + } + } + ] + } + ] + } + ] + } + ], + "Logging": { + "Type": "File" + } + } +} +``` + +## Spring Cloud Azure Version Compatibility + +Pick the Spring Cloud Azure version compatible with the project's Spring Boot version. See [aka.ms/spring/versions](https://aka.ms/spring/versions) for the compatibility matrix. + +| Spring Boot | Spring Cloud Azure | Notes | +|---|---|---| +| 2.x | 4.x | No `@ServiceConnection`, no `spring-cloud-azure-testcontainers`. Use `@DynamicPropertySource`. | +| 3.1.x - 3.5.x | 5.x | `@ServiceConnection` available | +| 4.0.x | 7.x | `@ServiceConnection` available | + +## Emulator with ServiceBusEmulatorContainer (testcontainers >= 1.20.5) + +**Requires: `org.testcontainers:azure` version >= 1.20.5** + +```xml +<dependency> + <groupId>org.testcontainers</groupId> + <artifactId>azure</artifactId> + <version>1.20.5</version><!-- or newer; class does NOT exist before 1.20.5 --> + <scope>test</scope> +</dependency> +<dependency> + <groupId>org.testcontainers</groupId> + <artifactId>mssqlserver</artifactId> + <scope>test</scope> +</dependency> +``` + +### Setting up a network + +```java +Network network = Network.newNetwork(); +``` + +### Starting a SQL Server container as dependency + +```java +MSSQLServerContainer<?> mssqlServerContainer = new MSSQLServerContainer<>( + "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04" +) + .acceptLicense() + .withPassword("yourStrong(!)Password") + .withCreateContainerCmdModifier(cmd -> { + cmd.getHostConfig().withCapAdd(Capability.SYS_PTRACE); + }) + .withNetwork(network); +``` + +### Starting a Service Bus Emulator container + +```java +ServiceBusEmulatorContainer emulator = new ServiceBusEmulatorContainer( + "mcr.microsoft.com/azure-messaging/servicebus-emulator:1.1.2" +) + .acceptLicense() + .withConfig(MountableFile.forClasspathResource("/service-bus-config.json")) + .withNetwork(network) + .withMsSqlServerContainer(mssqlServerContainer); +``` + +### Using Azure Service Bus clients + +```java +ServiceBusSenderClient senderClient = new ServiceBusClientBuilder() + .connectionString(emulator.getConnectionString()) + .sender() + .queueName("queue.1") + .buildClient(); + +ServiceBusProcessorClient processorClient = new ServiceBusClientBuilder() + .connectionString(emulator.getConnectionString()) + .processor() + .queueName("queue.1") + .processMessage(messageConsumer) + .processError(errorConsumer) + .buildProcessorClient(); +``` + +## Emulator with GenericContainer (testcontainers < 1.20.5) + +**Use this when the project's testcontainers version does not include `ServiceBusEmulatorContainer`.** This approach uses `GenericContainer` directly with the same emulator Docker image. + +```xml +<dependency> + <groupId>org.testcontainers</groupId> + <artifactId>testcontainers</artifactId> + <scope>test</scope> +</dependency> +<dependency> + <groupId>org.testcontainers</groupId> + <artifactId>junit-jupiter</artifactId> + <scope>test</scope> +</dependency> +<dependency> + <groupId>org.testcontainers</groupId> + <artifactId>mssqlserver</artifactId> + <scope>test</scope> +</dependency> +``` + +```java +@Testcontainers +@Tag("Layer1") +class ServiceBusEmulatorL1Test { + + static final Network NETWORK = Network.newNetwork(); + + @Container + static final MSSQLServerContainer<?> SQL_SERVER = new MSSQLServerContainer<>( + "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04") + .acceptLicense() + .withPassword("yourStrong(!)Password") + .withNetwork(NETWORK) + .withNetworkAliases("mssql"); + + @Container + static final GenericContainer<?> SERVICE_BUS = new GenericContainer<>( + "mcr.microsoft.com/azure-messaging/servicebus-emulator:1.1.2") + .withExposedPorts(5672) + .withNetwork(NETWORK) + .withEnv("ACCEPT_EULA", "Y") + .withEnv("MSSQL_SA_PASSWORD", "yourStrong(!)Password") + .withEnv("SQL_SERVER", "mssql") // network alias of the SQL Server container + .withCopyFileToContainer( + MountableFile.forClasspathResource("config.json"), + "/ServiceBus_Emulator/ConfigFiles/config.json") + .dependsOn(SQL_SERVER) + .waitingFor(Wait.forLogMessage(".*Emulator Service is Successfully Up!.*", 1) + .withStartupTimeout(Duration.ofMinutes(3))); + + static String getConnectionString() { + return String.format( + "Endpoint=sb://%s:%d;SharedAccessKeyName=RootManageSharedAccessKey;" + + "SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;", + SERVICE_BUS.getHost(), SERVICE_BUS.getMappedPort(5672)); + } + + private ServiceBusSenderClient senderClient; + private ServiceBusReceiverClient receiverClient; + + @BeforeAll + static void waitForEmulator() { + // Emulator needs extra time after port is ready for entities to initialize + // Use Awaitility — NEVER Thread.sleep() + Awaitility.await() + .atMost(Duration.ofSeconds(120)) + .pollInterval(Duration.ofSeconds(2)) + .until(() -> { + try { + ServiceBusSenderClient probe = new ServiceBusClientBuilder() + .connectionString(getConnectionString()) + .sender().queueName("queue.1").buildClient(); + probe.sendMessage(new ServiceBusMessage("probe")); + probe.close(); + return true; + } catch (Exception e) { + return false; + } + }); + } + + @BeforeEach + void setupClients() { + senderClient = new ServiceBusClientBuilder() + .connectionString(getConnectionString()) + .sender().queueName("queue.1").buildClient(); + receiverClient = new ServiceBusClientBuilder() + .connectionString(getConnectionString()) + .receiver().queueName("queue.1").buildClient(); + } + + @AfterEach + void closeClients() { + if (senderClient != null) senderClient.close(); + if (receiverClient != null) receiverClient.close(); + } +} +``` + +## Using Spring Cloud Azure with @ServiceConnection (Spring Boot >= 3.1) + +**Requires:** Spring Boot >= 3.1, `spring-cloud-azure-testcontainers`, testcontainers >= 1.20.5. + +`@ServiceConnection` is a Spring Boot 3.1+ feature. **Do NOT use this with Spring Boot 2.x — it will not compile.** For Spring Boot 2.x, see the [Spring Boot 2.x pattern](#spring-boot-2x-pattern) section. + +```xml +<properties> + <!-- Match this to your Spring Boot version per the table above --> + <version.spring.cloud.azure>5.25.0</version.spring.cloud.azure> +</properties> + +<dependencyManagement> + <dependencies> + <dependency> + <groupId>com.azure.spring</groupId> + <artifactId>spring-cloud-azure-dependencies</artifactId> + <version>${version.spring.cloud.azure}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> +</dependencyManagement> + +<dependencies> + <!-- Use spring-messaging-azure-servicebus for ServiceBusTemplate/ServiceBusSenderClient --> + <dependency> + <groupId>com.azure.spring</groupId> + <artifactId>spring-messaging-azure-servicebus</artifactId> + </dependency> + <!-- OR use spring-cloud-azure-stream-binder-servicebus for Spring Cloud Stream Supplier/Consumer --> + <!-- + <dependency> + <groupId>com.azure.spring</groupId> + <artifactId>spring-cloud-azure-stream-binder-servicebus</artifactId> + </dependency> + --> + <dependency> + <groupId>com.azure.spring</groupId> + <artifactId>spring-cloud-azure-starter</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-testcontainers</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>junit-jupiter</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.azure.spring</groupId> + <artifactId>spring-cloud-azure-testcontainers</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.microsoft.sqlserver</groupId> + <artifactId>mssql-jdbc</artifactId> + <scope>test</scope> + </dependency> +</dependencies> +``` + +### Container setup with @ServiceConnection + +`@ServiceConnection` tells Spring Boot to auto-configure `AzureServiceBusConnectionDetails` from the running container — no manual connection string wiring needed. The `MSSQLServerContainer` is NOT annotated with `@Container` because `ServiceBusEmulatorContainer.withMsSqlServerContainer()` manages its lifecycle. + +```java +private static final Network NETWORK = Network.newNetwork(); + +private static final MSSQLServerContainer<?> SQLSERVER = new MSSQLServerContainer<>( + "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04") + .acceptLicense() + .withNetwork(NETWORK) + .withNetworkAliases("sqlserver"); + +@Container +@ServiceConnection +private static final ServiceBusEmulatorContainer SERVICE_BUS = new ServiceBusEmulatorContainer( + "mcr.microsoft.com/azure-messaging/servicebus-emulator:latest") + .acceptLicense() + .withCopyFileToContainer(MountableFile.forClasspathResource("config.json"), + "/ServiceBus_Emulator/ConfigFiles/config.json") + .withNetwork(NETWORK) + .withMsSqlServerContainer(SQLSERVER); +``` + +### Spring messaging pattern (ServiceBusTemplate / ServiceBusSenderClient) + +Use when the application uses `ServiceBusSenderClient` or `ServiceBusTemplate` for sending, and `ServiceBusRecordMessageListener` for processing. + +```java +@SpringJUnitConfig +@TestPropertySource(properties = { + "spring.cloud.azure.servicebus.entity-name=queue.1", + "spring.cloud.azure.servicebus.entity-type=queue" +}) +@Testcontainers +@Tag("Layer1") +class ServiceBusMessagingL1Test { + + // ... container setup as above ... + + @Autowired + private ServiceBusSenderClient senderClient; + + @Autowired + private ServiceBusTemplate serviceBusTemplate; + + @Test + void senderClientCanSendAndReceiveMessage() { + // The emulator depends on SQL Server and needs time to initialize messaging entities + waitAtMost(Duration.ofSeconds(120)).pollInterval(Duration.ofSeconds(2)).untilAsserted(() -> { + senderClient.sendMessage(new ServiceBusMessage("Hello World!")); + }); + + waitAtMost(Duration.ofSeconds(30)).untilAsserted(() -> { + assertThat(Config.MESSAGES).contains("Hello World!"); + }); + } + + @Test + void serviceBusTemplateCanSendAndReceiveMessage() { + waitAtMost(Duration.ofSeconds(120)).pollInterval(Duration.ofSeconds(2)).untilAsserted(() -> { + serviceBusTemplate.sendAsync("queue.1", + MessageBuilder.withPayload("Hello from template!").build()) + .block(Duration.ofSeconds(10)); + }); + + waitAtMost(Duration.ofSeconds(30)).untilAsserted(() -> { + assertThat(Config.MESSAGES).contains("Hello from template!"); + }); + } + + @Configuration(proxyBeanMethods = false) + @ImportAutoConfiguration(classes = { + AzureGlobalPropertiesAutoConfiguration.class, + AzureServiceBusAutoConfiguration.class, + AzureServiceBusMessagingAutoConfiguration.class}) + static class Config { + + private static final Set<String> MESSAGES = ConcurrentHashMap.newKeySet(); + + @Bean + ServiceBusRecordMessageListener processMessage() { + return context -> MESSAGES.add(context.getMessage().getBody().toString()); + } + + @Bean + ServiceBusErrorHandler errorHandler() { + return (context) -> { }; + } + } +} +``` + +## Spring Boot 2.x Pattern + +**Spring Boot 2.x does NOT support `@ServiceConnection` or `spring-boot-testcontainers`.** Use `@DynamicPropertySource` to inject the emulator connection string into the Spring context. + +```java +@SpringBootTest +@ActiveProfiles("test") // MANDATORY +@Testcontainers +@Tag("Layer1") +class MessageServiceL1Test { + + static final Network NETWORK = Network.newNetwork(); + + @Container + static final MSSQLServerContainer<?> SQL_SERVER = new MSSQLServerContainer<>( + "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04") + .acceptLicense() + .withPassword("yourStrong(!)Password") + .withNetwork(NETWORK) + .withNetworkAliases("mssql"); + + @Container + static final GenericContainer<?> SERVICE_BUS = new GenericContainer<>( + "mcr.microsoft.com/azure-messaging/servicebus-emulator:1.1.2") + .withExposedPorts(5672) + .withNetwork(NETWORK) + .withEnv("ACCEPT_EULA", "Y") + .withEnv("MSSQL_SA_PASSWORD", "yourStrong(!)Password") + .withEnv("SQL_SERVER", "mssql") + .withCopyFileToContainer( + MountableFile.forClasspathResource("config.json"), + "/ServiceBus_Emulator/ConfigFiles/config.json") + .dependsOn(SQL_SERVER) + .waitingFor(Wait.forLogMessage(".*Emulator Service is Successfully Up!.*", 1) + .withStartupTimeout(Duration.ofMinutes(3))); + + // NO @MockBean — all beans wired from the real emulator + @DynamicPropertySource + static void serviceBusProperties(DynamicPropertyRegistry registry) { + String connectionString = String.format( + "Endpoint=sb://%s:%d;SharedAccessKeyName=RootManageSharedAccessKey;" + + "SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;", + SERVICE_BUS.getHost(), SERVICE_BUS.getMappedPort(5672)); + registry.add("spring.cloud.azure.servicebus.connection-string", () -> connectionString); + registry.add("spring.cloud.azure.servicebus.namespace", () -> "sbemulatorns"); + // Disable managed identity — use the emulator connection string instead + registry.add("spring.cloud.azure.credential.managed-identity-enabled", () -> "false"); + } + + @Autowired + private MessageService messageService; // The app's own service class + + @Test + void sendMessageThroughApplicationService() { + // ALWAYS test through the application's own classes, not the SDK directly + Awaitility.await() + .atMost(Duration.ofSeconds(120)) + .pollInterval(Duration.ofSeconds(2)) + .untilAsserted(() -> { + messageService.sendMessage("test-queue", "Hello from test!"); + }); + } +} +``` + +## Handle ServiceBusAdministrationClient + +**CRITICAL: The Service Bus emulator does NOT support the ServiceBusAdministrationClient REST API.** The emulator only exposes AMQP on port 5672 for messaging operations. The `ServiceBusAdministrationClient` uses HTTPS REST API (port 443) which the emulator does not provide. Any call to `adminClient.getTopic()`, `adminClient.createSubscription()`, etc. will fail with `Connection refused: localhost:443`. + +### When the Application Uses ServiceBusAdministrationClient + +If the application has beans that use `ServiceBusAdministrationClient`, you MUST: +1. Use a test configuration that doesn't include the admin client. +2. **Include ALL dependent beans** - if `TopicProperties mainExchangeTopic` depends on `adminClient`, you must exclude BOTH +3. **Pre-create topics/queues/subscriptions in config.json** instead of relying on admin API calls + +### Complete Test Configuration Example + +When the application has code like this: + +```java +// Production code +@Bean +public ServiceBusAdministrationClient adminClient(AzureServiceBusProperties properties, TokenCredential credential) { + return new ServiceBusAdministrationClientBuilder() + .credential(properties.getFullyQualifiedNamespace(), credential) + .buildClient(); +} + +@Bean +public TopicProperties mainExchangeTopic(ServiceBusAdministrationClient adminClient) { + try { + return adminClient.getTopic(MAIN_EXCHANGE); // ← This FAILS against emulator! + } catch (ResourceNotFoundException e) { + return adminClient.createTopic(MAIN_EXCHANGE); + } +} +``` +**You MUST Exclude Admin Beans with @Profile:** + +```java +// Production code - mark with profile exclusion +@Bean +@Profile("!test") // Excluded in test profile +public ServiceBusAdministrationClient adminClient(AzureServiceBusProperties properties, TokenCredential credential) { + // ... +} + +@Bean +@Profile("!test") // Excluded in test profile +public TopicProperties mainExchangeTopic(ServiceBusAdministrationClient adminClient) { + // ... +} +``` + +**IMPORTANT:** Pre-create the topic in your `service-bus-config.json`: + +```json +{ + "UserConfig": { + "Namespaces": [{ + "Name": "sbemulatorns", + "Topics": [{ + "Name": "mainExchange", + "Subscriptions": [/* pre-create any needed subscriptions */] + }] + }] + } +} +``` + +## Emulator Readiness and Retry + +The Service Bus emulator takes significantly longer to start than Azurite because it depends on SQL Server initializing messaging entities. **Always use Awaitility retry/polling for initial send operations — never `Thread.sleep()`.** + +```java +// Typical total time from container start to first successful send: 60-120 seconds +waitAtMost(Duration.ofSeconds(120)) + .pollInterval(Duration.ofSeconds(2)) + .untilAsserted(() -> { + senderClient.sendMessage(new ServiceBusMessage("test")); + }); +``` + +## Emulator fails to start +If the emulator won't start (Docker not available, timeout, resource limits), **do NOT fall back to mocking.** Instead: +1. Increase the startup timeout (the emulator needs 60-120s) +2. Check Docker resources (emulator + SQL Server need ~4GB RAM) +3. Verify config.json is correctly mounted +4. Check the emulator logs for specific errors + +## Common Gotchas + +| Problem | Cause | Fix | +|---------|-------|-----| +| `ClassNotFoundException: ServiceBusEmulatorContainer` | testcontainers version < 1.20.5 | Upgrade to >= 1.20.5 OR use GenericContainer approach | +| `cannot find symbol: @ServiceConnection` | Spring Boot < 3.1 | Use `@DynamicPropertySource` instead (see Spring Boot 2.x pattern) | +| `UnsatisfiedDependencyException: TokenCredential` | Custom `@Configuration` creates Azure beans without correct emulator properties | Add `@ActiveProfiles("test")` AND provide emulator connection string via `@DynamicPropertySource` so all beans connect to the real emulator | +| `ServiceBusException: Entity not found` | Emulator entities not yet initialized | Use `waitAtMost` retry pattern with Awaitility | +| `Connection refused on port 5672` | SQL Server not ready when emulator starts | Use `dependsOn(SQL_SERVER)` + `waitingFor` log message strategy | +| `config.json not found` | Wrong mount path | Ensure `MountableFile.forClasspathResource("config.json")` matches file in `src/test/resources/` | +| Queue/topic name mismatch | config.json names don't match test properties | Verify `entity-name` matches config.json `Name` field | +| `No qualifying bean of type ServiceBusSenderClient` | Missing auto-configuration imports | Add `@ImportAutoConfiguration` with `AzureGlobalPropertiesAutoConfiguration`, `AzureServiceBusAutoConfiguration`, `AzureServiceBusMessagingAutoConfiguration` | +| `Checkpointer is null` | `auto-complete` not disabled | Set `spring.cloud.stream.servicebus.bindings.<fn>-in-0.consumer.auto-complete=false` | +| `InvalidDestinationException` on context start | Test context loads production JMS `@Configuration` that connects to fake endpoint | Add `@ActiveProfiles("test")` and provide correct emulator connection properties via `@DynamicPropertySource` | +| Tests hang during context startup | `@SpringBootTest` loads full context with real Azure/DB connections | Add `@ActiveProfiles("test")` and provide all emulator properties via `@DynamicPropertySource`, or narrow context with `classes = {...}` | diff --git a/.github/skills/integration-tests/references/azure-storage-testcontainers.md b/.github/skills/integration-tests/references/azure-storage-testcontainers.md new file mode 100644 index 000000000..4449ca75c --- /dev/null +++ b/.github/skills/integration-tests/references/azure-storage-testcontainers.md @@ -0,0 +1,276 @@ +# Azure Blob Storage with Azurite TestContainers Coding Reference + +## Contents +- 1.Azurite-Specific Self-Checks +- 2.Azurite Container Setup + + Azurite well-known credentials +- 3.Azurite URL Format Gotcha +- 4.Spring Boot Config Override for Blob Storage + + ⚠️ CRITICAL: `System.getenv()` vs Spring Properties Mismatch +- 5. Shared Azurite Base Class +- 6. Azure Blob-Specific Test Patterns + + Testing Application Code (Not the SDK) + + Asserting on Behavior, Not Structure + + Error Handling with BlobStorageException + +## 1.Azurite-Specific Self-Checks +Before running tests, verify: +- [ ] If any application code reads config via `System.getenv()`, you've provided values through constructor injection or `@TestConfiguration` beans — NOT through `@DynamicPropertySource` (which only sets Spring properties) +- [ ] If the application parses URLs to extract container names, you've handled the Azurite URL format difference (see section 2) +- [ ] No test uses `DefaultAzureCredentialBuilder` — use `StorageSharedKeyCredential` with Azurite dev credentials +- [ ] No test checks for `blob.core.windows.net` in URLs — Azurite URLs use `localhost` +- [ ] `@ActiveProfiles("test")` is on every `@SpringBootTest` class (if using Spring Boot) +- [ ] `@BeforeEach` cleanup deletes all blob containers to prevent cross-test contamination + +## 2.Azurite Container Setup +```java +new GenericContainer<>("mcr.microsoft.com/azure-storage/azurite:latest") + .withExposedPorts(10000) + .withCommand("azurite-blob", "--blobHost", "0.0.0.0") + .waitingFor(Wait.forListeningPort()); // REQUIRED — prevents race conditions +``` + +### Azurite well-known credentials (safe for local testing only) +- Account name: `devstoreaccount1` +- Account key: `Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==` + +## 3.Azurite URL Format Gotcha +**IMPORTANT — Azurite URL format differs from production Azure Blob Storage:** + +- **Production Azure:** `https://<account>.blob.core.windows.net/<container>/<blob>` +- **Azurite:** `http://<host>:<port>/devstoreaccount1/<container>/<blob>` + +If the application code parses Azure Blob Storage URLs (e.g., extracting container name from the URL path), the Azurite URL will have an extra `/devstoreaccount1/` path segment that production URLs don't have. This causes: +- Container name extracted as `devstoreaccount1` instead of the actual container name +- URL-based detection logic (e.g., checking for `blob.core.windows.net`) failing for Azurite URLs +- Path indices being off-by-one when splitting URLs into segments + +**How to handle this — choose the approach that requires the LEAST production code change:** + +1. **Best approach — Inject the container name and BlobServiceClient separately** instead of having the application parse them from a URL: + ```java + // Add a test-friendly constructor that accepts pre-built client + container name + // Minimal source change: 3-4 lines + S3FileSystemStore(String rootPath, BlobServiceClient client, String containerName) { + this.blobServiceClient = client; + this.containerName = containerName; + this.rootPath = rootPath; + } + ``` + +2. **If the application detects Azure by checking for `blob.core.windows.net`** in the URL (common pattern), provide an override mechanism so tests can force Azure mode: + ```java + // Add a boolean flag or config property to bypass URL detection + S3FileSystemStore(String rootPath, FileSystem fs, BlobServiceClient client, boolean isAzure) { + this.blobServiceClient = client; + this.isAzureMode = isAzure; // skip blob.core.windows.net check + } + ``` +3. **If the application splits the URL path to extract container names**, the path indices will be different for Azurite vs Azure: + - Azure URL path: `/<container>/<blob>` -> `pathParts[1]` = container name + - Azurite URL path: `/devstoreaccount1/<container>/<blob>` -> `pathParts[1]` = `devstoreaccount1`, `pathParts[2]` = container name + + **Never assume Azurite URLs have the same path structure as production Azure URLs.** Instead, pass the container name as a parameter to avoid URL parsing entirely. + +**Self-check:** Before running tests, ask "Does any application code parse URLs to extract container names or detect Azure mode?" If yes, you MUST handle the Azurite URL format difference or 60%+ of tests will fail at runtime. + +## 4.Spring Boot Config Override for Blob Storage + +Production code often uses `DefaultAzureCredentialBuilder` which requires HTTPS and real Azure endpoints. Tests use local Azurite over HTTP with well-known keys. You **MUST** override the production bean configuration so the test context starts successfully. + +**Step 1 — ALWAYS add `@ActiveProfiles("test")` to every `@SpringBootTest` class:** +```java +@SpringBootTest +@ActiveProfiles("test") // MANDATORY — prevents production @Profile("!test") beans from loading +@Testcontainers +class MyServiceL1Test { ... } +``` +Without `@ActiveProfiles("test")`, production configuration classes (DataSource configs, credential builders, startup initializers) will load and fail because they try to connect to real services. This is the **#1 cause of Spring context startup failures** in integration tests. + +**Step 2 — use `@TestConfiguration` with `@Primary` to override production beans:** + +```java +@TestConfiguration +public class TestBlobStorageConfig { + // Override the production BlobServiceClient that uses DefaultAzureCredential + @Bean + @Primary + public BlobServiceClient blobServiceClient( + @Value("${azure.storage.endpoint}") String endpoint) { + // Azurite well-known credentials — safe for local testing only + StorageSharedKeyCredential credential = new StorageSharedKeyCredential( + "devstoreaccount1", + "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="); + return new BlobServiceClientBuilder() + .endpoint(endpoint) + .credential(credential) + .buildClient(); + } +} +``` + +**Step 3 — narrow the Spring context when full context is too heavy:** +If `@SpringBootTest` loads too many unrelated beans (startup initializers, schedulers, external integrations) that fail during context startup, use context slicing: +```java +@SpringBootTest(classes = {MyService.class, TestBlobStorageConfig.class}) +``` +This loads only the beans you need for testing, avoiding failures from unrelated components. + +### ⚠️ CRITICAL: `System.getenv()` vs Spring Properties Mismatch + +**`@DynamicPropertySource` sets Spring properties — it does NOT set environment variables.** If the application's DAO/service reads configuration via `System.getenv("AZURE_STORAGE_ENDPOINT")`, setting `registry.add("AZURE_STORAGE_ENDPOINT", ...)` in `@DynamicPropertySource` will NOT work. The DAO will receive `null` and fail with `NullPointerException` before any test runs. + +**How to detect this:** Before writing any test, `grep -r "System.getenv\|System.getProperty" src/main/` to find all environment variable reads in the application code. If you find any, you MUST use one of the approaches below. + +**Fix — choose the approach that requires the LEAST production code change:** + +1. **Best approach — Add a constructor that accepts the dependencies directly** (minimal safe source change, 3-5 lines): + ```java + // Add to the production DAO class: + AzureBlobDigitalMediaDAO(BlobServiceClient client, String containerName) { + this.blobServiceClient = client; + this.containerName = containerName; + } + ``` + Then in the test, provide the client via `@TestConfiguration` with `@Primary`: + ```java + @TestConfiguration + static class TestConfig { + @Bean @Primary + public AzureBlobDigitalMediaDAO testDao() { + return new AzureBlobDigitalMediaDAO(blobServiceClient, CONTAINER_NAME); + } + } + ``` + +2. **Alternative — Use `@TestConfiguration` `@Primary` bean + `@ConditionalOnMissingBean`** on the production config class so the test bean takes precedence. + +3. **Last resort — Set actual environment variables via `System.setProperty()` paired with changing production code from `System.getenv()` to `System.getProperty()`** (slightly larger source change but avoids constructor changes). + +**Anti-pattern — DO NOT DO THIS:** +```java +// WRONG: @DynamicPropertySource does NOT populate System.getenv() +@DynamicPropertySource +static void props(DynamicPropertyRegistry registry) { + registry.add("AZURE_STORAGE_ENDPOINT", () -> azuriteEndpoint); // ❌ DAO calls System.getenv(), not Spring +} +``` + +**Self-check:** For every `System.getenv()` call in the production code, verify your test provides the value through a mechanism the production code actually reads. `@DynamicPropertySource` only works for code that reads from Spring's `Environment` (e.g., `@Value`, `@ConfigurationProperties`). + +**Key rules:** +- ALWAYS add `@ActiveProfiles("test")` to every `@SpringBootTest` test class — this is the most common mistake. +- NEVER use `DefaultAzureCredentialBuilder` in tests — it will fail on HTTP endpoints and in CI. +- ALWAYS use `StorageSharedKeyCredential` with Azurite's well-known dev credentials for Blob Storage tests. +- Provide test properties via `@DynamicPropertySource` from the TestContainers container (e.g., `azuriteContainer.getHost()` + `azuriteContainer.getMappedPort(10000)`). +- If the full `@SpringBootTest` context fails to start, narrow it with `classes = {...}` rather than trying to mock/stub all failing beans. + +## 5.Shared Azurite Base Class + +When you have 2+ test classes using Azurite, extract the container declaration and client construction into a shared abstract base class: + +```java +// Shared base class — declared once, reused by all test classes +@Testcontainers +abstract class AbstractAzuriteL1Test { + @Container + static final GenericContainer<?> azurite = new GenericContainer<>( + "mcr.microsoft.com/azure-storage/azurite:latest") + .withExposedPorts(10000) + .withCommand("azurite-blob", "--blobHost", "0.0.0.0"); + + protected static BlobServiceClient blobServiceClient; + + @BeforeAll + static void initClient() { + String endpoint = String.format("http://%s:%d/devstoreaccount1", + azurite.getHost(), azurite.getMappedPort(10000)); + blobServiceClient = new BlobServiceClientBuilder() + .connectionString(getAzuriteConnectionString()) + .buildClient(); + } +} + +// Each test class extends the base — no duplicated container setup +@Tag("Layer1") +class EventHandlerL1Test extends AbstractAzuriteL1Test { ... } +class S3ClientUtilL1Test extends AbstractAzuriteL1Test { ... } +``` + +## 6.Azure Blob-Specific Test Patterns + +### Testing Application Code (Not the SDK) + +**Anti-pattern — DO NOT DO THIS:** +```java +// WRONG: Test calls Azure SDK directly instead of the application's CreateBucket class +@Test void testCreateBucketClass() { + // This tests the Azure SDK, NOT the application code + blobServiceClient.createBlobContainer("test-container"); + assertTrue(blobServiceClient.getBlobContainerClient("test-container").exists()); +} +``` + +**Anti-pattern — DO NOT DO THIS either:** +```java +// WRONG: Tests individual Azure Blob operations instead of the application's handler +@Test void testUploadBlob() { + BlobContainerClient container = blobServiceClient.getBlobContainerClient("test"); + container.create(); + container.getBlobClient("file.txt").upload(BinaryData.fromString("data"), true); + String content = container.getBlobClient("file.txt").downloadContent().toString(); + assertEquals("data", content); + // This verifies Azure SDK works — it does NOT test the application's EventHandler +} +``` + +**Correct pattern — invoke the application's own entry points:** +```java +// RIGHT: Test calls the application's own handler method end-to-end +@Test void testHandleRequestProcessesEventsEndToEnd() { + // Arrange — pre-populate Azurite with test event data + uploadTestEvent("container1", "event1.txt", "status:SHIPPED\ntimestamp:1573410202"); + + // Act — invoke the APPLICATION's handler, not the SDK + EventHandler handler = new EventHandler(blobServiceClient); + handler.handleRequest(mockContext); + + // Assert — verify the application produced the expected output + String summary = downloadBlob("summary-container", "summary.txt"); + assertThat(summary).contains("SHIPPED"); +} +``` + +### Asserting on Behavior, Not Structure + +**Every write test must read the data back and verify content.** If you write a blob to Azurite, download it and assert the content matches — do NOT just assert that the container exists (which is always true if you created it in `@BeforeEach`). A test whose only assertion is `assertTrue(container.exists())` or `assertNotNull(result)` is effectively testing nothing. + +### Error Handling with BlobStorageException + +```java +// RIGHT: Test error handling through the application class +@Test void testCreateBucketWithInvalidName() { + RuntimeException ex = assertThrows(RuntimeException.class, + () -> createBucket.createBucketAsync("INVALID-UPPERCASE")); + assertThat(ex.getMessage()).contains("Failed to create bucket"); + assertThat(ex.getCause()).isInstanceOf(BlobStorageException.class); +} +``` + +For each `catch (BlobStorageException e)` block in the migrated code, write a corresponding test: +```java +// If the source code has: +try { + blobClient.upload(data, true); +} catch (BlobStorageException e) { + throw new RuntimeException("Failed to create bucket", e); +} + +// Then you MUST have this test: +@Test void testCreateBucketWrapsStorageException() { + RuntimeException ex = assertThrows(RuntimeException.class, + () -> createBucket.createBucketAsync("INVALID")); + assertThat(ex.getMessage()).contains("Failed to create bucket"); + assertThat(ex.getCause()).isInstanceOf(BlobStorageException.class); +} +``` diff --git a/.github/skills/integration-tests/references/layer1-local-integration.md b/.github/skills/integration-tests/references/layer1-local-integration.md new file mode 100644 index 000000000..2b2d06262 --- /dev/null +++ b/.github/skills/integration-tests/references/layer1-local-integration.md @@ -0,0 +1,358 @@ +# Layer 1: Local Integration Tests + +## Contents +- Prerequisites (Docker & TestContainers available) +- Azure Authentication Strategies for Integration Tests Layer 1 (TokenCredential,Connection Strings, Keys) + + Emulatable Azure Services + + Emulator Connection String Values + + Modification Rules +- Principles + + 1. Core Principles (naming convention, no source code modification to fix TestContainers or Docker compatibility issues) + + 2. MOST IMPORTANT: Test application code, not the SDK + + 3. Make untestable code testable with minimal, safe source changes + + 4. Wire and test the full execution path + + 5. Assert on behavior, not structure + + 6. Only set up what the test uses + + 7. Test edge cases + + 8. Cover downstream consumers + + 9. Only label tests as integration tests if they integrate external systems + + 10. Stay scoped to the migration target + + 11. DO NOT use any test ordering mechanism + + 12. DO NOT use reflection to access or modify private fields,DO NOT widen field visibility + + 13. DO write specific, descriptive assertions + + 14. DO structure every test with clear Arrange-Act-Assert (AAA) sections + + 15. DO add `@BeforeEach` cleanup when tests share a container + + 16. DO verify the test count after `mvn verify` matches expectations + + 17. DO extract shared test infrastructure into a base class or helper when you have 2+ test classes + + 18. DO extract commonly repeated test patterns into helper methods + + 19. DO NOT leave `System.out.println` or debug logging statements in test code + + 20. NEVER use `Thread.sleep()` to wait for containers to start + +## Prerequisites + +- Docker installed and running +- TestContainers library available for the project's language + +## Azure Authentication Strategies for Integration Tests Layer 1 + +Migrated applications typically use **Microsoft Entra ID OAuth** such as **Managed Identity** (`DefaultAzureCredential`) which only works on Azure infrastructure. For local integration testing applications must connect to local emulators. + +### Emulatable Azure Services + +These services have official emulators that can run in Docker containers: + +| Azure Service | Emulator Image | Dependencies | +|---------------|----------------|--------------| +| Blob / Queue / Table Storage | `mcr.microsoft.com/azure-storage/azurite` | None | +| Cosmos DB | `mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator` | None (but requires SSL trust store + endpoint/key auth) | +| SQL Database | `mcr.microsoft.com/mssql/server` | None (wire-compatible with SQL Server) | +| Service Bus | `mcr.microsoft.com/azure-messaging/servicebus-emulator` | Requires MSSQL companion + JSON config | +| Event Hubs | `mcr.microsoft.com/azure-messaging/eventhubs-emulator` | Requires Azurite companion + JSON config | + +> **Note:** Service Bus and Event Hubs emulators require companion containers and a JSON config file. See [azure-servicebus-testcontainers.md](references/azure-servicebus-testcontainers.md) for the config format. + +**Cosmos DB emulator note:** Unlike other emulators which use connection strings, the Cosmos DB emulator authenticates via **endpoint + account key** and requires an **SSL certificate** imported into a trust store (e.g., `javax.net.ssl.trustStore` for Java). If SSL setup is too complex, treat Cosmos DB as non-emulatable and recommend Layer 3. + +### Authentication Modification Strategies (TokenCredential,Connection Strings, Keys) + +For each emulatable Azure dependency, modify how the application authenticates: + +#### Config-Driven Applications + +**Examples:** Spring Boot applications with `application.properties` or `application.yml`, Quarkus/Micronaut applications with `application.properties`. + +**Strategy:** Inject the connection string via test configurations, like property source. + +**CRITICAL:** You MUST always modify the config file to add the explicit connection string value. Do NOT rely on environment variables. + +#### Hardcoded/Plain Applications + +**Examples:** Plain Java CLI apps without config frameworks + +**When to use:** Applications that have NO configuration framework (no Spring Boot, no application.properties). These apps construct clients directly in code with hardcoded values. + +**Strategy:** Modify the source code to extend the client constructor which accepts hardcode emulator connection strings. Since these applications don't have config files to modify, the connection string must be in the source code itself to be committed to git. + +**Java example:** + +**Before:** +```java +public class BlobServiceClientProvider { + private static BlobServiceClient blobServiceClient; + + public static BlobServiceClient getClient() { + if (blobServiceClient == null) { + String endpoint = System.getenv("AZURE_STORAGE_ENDPOINT"); + blobServiceClient = new BlobServiceClientBuilder() + .endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .buildClient(); + } + return blobServiceClient; + } +} +``` + +**After:** +```java +public class BlobServiceClientProvider { + private static BlobServiceClient blobServiceClient; + + public static BlobServiceClient getClient() { + if (blobServiceClient == null) { + String endpoint = System.getenv("AZURE_STORAGE_ENDPOINT"); + blobServiceClient = new BlobServiceClientBuilder() + .endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .buildClient(); + } + return blobServiceClient; + } + + public static BlobServiceClient getClient(String connectionString) { + if (blobServiceClient == null) { + blobServiceClient = new BlobServiceClientBuilder() + .connectionString(testConnectionString) + .buildClient(); + } + return blobServiceClient; + } +} +``` + +### Emulator Connection String Values + +Each emulator's connection string is built from **well-known credentials** that are consistent across all emulator instances. + +| Service | Auth Type | How to Determine the Value | +|---------|-----------|----------------------------| +| Azurite (Blob/Queue/Table) | Connection string | Built from well-known account `devstoreaccount1`, well-known key, and mapped ports (10000/10001/10002). See [Azurite docs](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite#well-known-storage-account-and-key). | +| Service Bus | Connection string | Built from well-known SAS key + `UseDevelopmentEmulator=true`. See [Service Bus emulator docs](https://learn.microsoft.com/en-us/azure/service-bus-messaging/test-locally-with-service-bus-emulator). | +| Event Hubs | Connection string | Same pattern as Service Bus. See [Event Hubs emulator docs](https://learn.microsoft.com/en-us/azure/event-hubs/test-locally-with-event-hub-emulator). | +| Cosmos DB | Endpoint + key | Built from well-known emulator key + mapped port. See [Cosmos emulator docs](https://learn.microsoft.com/en-us/azure/cosmos-db/emulator). Also requires SSL trust store setup. | + +**Important:** The agent must look up the **actual current default credentials** from the linked official docs at generation time. Emulator defaults may change across versions. Do NOT hardcode connection strings from this file. + +### Modification Rules + +When modifying application code or config to use emulators: + +1. **Minimal changes only** — Only modify what's needed to switch auth from Managed Identity to emulator connection strings. Do not refactor, rename, or restructure. +2. **No new dependencies** — Use only packages already in the project. +3. **Reversible** — Changes should be easily revertable to restore original Managed Identity auth. +4. **No unrelated changes** — Never make refactoring, cleanup, or feature changes alongside auth modifications. + +## Principles + +### Core Principles + +1. **DO integration tests** to verify that different components interact correctly, focusing on data exchange and interface connections. +2. **DO write** comprehensive integration tests using containers to simulate all migrated dependencies, **especially Azure services**. +6. **NEVER modify application source code** to fix TestContainers or Docker compatibility issues. +8. **DO use `*L1Test.java`** as the class name suffix for Layer 1 test classes. This matches Maven Surefire's default `*Test.java` pattern + +### MOST IMPORTANT: Test application code, not the SDK + +Always instantiate and invoke the project's own classes/methods. Never call third-party library APIs directly in the test as a substitute for testing the application. If the application has a service class with methods like `handleRequest()`, `processData()`, or `createBucket()`, your tests MUST call those methods. + **Anti-pattern — DO NOT DO THIS:** + ```java + // WRONG: Test calls SDK directly instead of the application's own class + @Test void testServiceMethod() { + // This tests the SDK, NOT the application code + sdkClient.doOperation("test-input"); + assertTrue(sdkClient.getResult("test-input").exists()); + } + ``` + + **Correct pattern — invoke the application's own entry points:** + ```java + // RIGHT: Test calls the application's own handler method end-to-end + @Test void testHandleRequestProcessesDataEndToEnd() { + // Arrange — pre-populate test data + setupTestData("container1", "data1.txt", "status:ACTIVE\ntimestamp:1573410202"); + + // Act — invoke the APPLICATION's handler, not the SDK + MyHandler handler = new MyHandler(sdkClient); + handler.handleRequest(mockContext); + + // Assert — verify the application produced the expected output + String result = readOutput("output-container", "result.txt"); + assertThat(result).contains("ACTIVE"); + } + ``` + **Never bypass the application class by re-implementing its logic with direct SDK calls.** + + > For Azure Blob Storage-specific examples (Azurite anti-patterns, `BlobServiceClient` injection, `EventHandler` testing), see [azure-storage-testcontainers.md](./azure-storage-testcontainers.md). + +### Make untestable code testable with minimal, safe source changes + +If production code cannot be invoked from a test, introduce the smallest possible change (e.g., adding a method, widening visibility, extracting a parameter) to enable it. Never alter existing behavior, signatures, or control flow. Never work around untestable code by re-implementing its logic in the test. + +### Wire and test the full execution path + +Tests must exercise the end-to-end flow from input through business logic to output, not individual layers (controller layer or database layer) in isolation. + +### Assert on behavior, not structure + +Verify correct values, side effects, and state transitions — not just that a result is non-null or non-empty, nor rely on string containment or format checks alone. **Every write test must read the data back and verify content.** A test whose only assertion is `assertTrue(result.exists())` or `assertNotNull(result)` is effectively testing nothing. + +### Only set up what the test uses + +Every configured property, container, or singleton in setUp must be exercised by the test. Remove dead setup. + +### Test error handling at the application level with precise assertions — this is MANDATORY, not optional. + + **Anti-pattern — DO NOT DO THIS:** + ```java + // WRONG: Only testing happy paths + @Test void testOperation() { sdkClient.doOperation("test"); /* only happy path */ } + ``` + + **Correct pattern:** + ```java + // RIGHT: Test error handling through the application class + @Test void testOperationWithInvalidInput() { + RuntimeException ex = assertThrows(RuntimeException.class, + () -> myService.processInput("INVALID-INPUT")); + assertThat(ex.getMessage()).contains("Failed to process"); + assertThat(ex.getCause()).isInstanceOf(SomeSDKException.class); + } + ``` + + **Correct pattern for JSON deserialization error (common with Redis/cache migrations):** + ```java + // RIGHT: Inject corrupted data directly into the store, then test the app's error path + @Test void testGetPersonWithCorruptedJson() { + // Arrange — write invalid JSON directly to Redis in the SAME namespace the app uses + redisCommands.set("personCache:badKey", "{not-valid-json!!}"); + + // Act & Assert — the app's getPerson() should catch JsonProcessingException and wrap it + RuntimeException ex = assertThrows(RuntimeException.class, + () -> cacheManager.getPerson("badKey")); + assertThat(ex.getMessage()).contains("Failed to deserialize"); + assertThat(ex.getCause()).isInstanceOf(JsonProcessingException.class); + } + ``` + **Note:** When testing deserialization errors, write corrupted data to the **same key namespace/prefix** that the application reads from. A common mistake is writing to namespace `stringCache:key` but reading from `personCache:key` — this just produces a cache miss (null), not a deserialization error. + + > For Azure Blob Storage-specific error handling patterns (e.g., `BlobStorageException` wrapping), see [azure-storage-testcontainers.md](./azure-storage-testcontainers.md#5-azure-blob-specific-test-patterns). + + #### Migration-Critical Error Scenarios Checklist + + The following error scenarios are the most commonly missed in migration integration tests. **You MUST check each row and write a test for every scenario that applies to your migration.** Skipping these is the #1 cause of low error handling scores. + + | # | Scenario | When it applies | What to test | Example assertion | + |---|----------|----------------|--------------|-------------------| + | 1 | **SDK exception wrapping** | App has `catch (SDKException e) { throw new ...}` | Trigger the SDK exception through the app's own method and verify the wrapper exception type, message, AND cause chain | `assertThat(ex.getCause()).isInstanceOf(SDKException.class)` | + | 2 | **Resource-not-found via app method** | App reads blobs, DB rows, cache keys that may not exist | Call the app's read method with a non-existent resource; assert on the specific return (null, empty Optional, 404) — not just "no exception" | `assertThat(dao.load(99999, "x")).isNull()` | + | 3 | **Inconsistent state between stores** | App uses 2+ stores (DB + blob, DB + cache) | Write metadata to one store but NOT the other, then call the app's read method — verify it handles the mismatch (exception, null, graceful fallback) | Insert DB row, don't upload blob -> `dao.load()` should throw/return-null | + | 4 | **Invalid/null input through app methods** | App has public methods accepting user-provided strings, IDs, names | Pass null, empty string, and boundary-length values through the app's own method; assert specific exception type or error response | `assertThrows(IllegalArgumentException.class, () -> svc.create(null))` | + | 5 | **Duplicate/conflict operations** | App creates named resources (containers, keys, DB records) | Create a resource, then try to create it again through the app method; verify the specific conflict behavior (exception type, idempotent success, or error code) | `assertThat(ex.getMessage()).contains("already exists")` | + | 6 | **Delete non-existent resource** | App has delete/remove methods | Call delete on a resource that doesn't exist; verify whether it throws, returns false, or is idempotent — **this often differs between AWS SDK and Azure SDK** | `assertThat(svc.delete("nonexistent")).isFalse()` | + | 7 | **Operations after close/shutdown** | App has lifecycle methods (close, shutdown, stopService) | Call close(), then attempt a normal operation; verify it throws the expected exception (NPE, IllegalStateException, etc.) | `svc.close(); assertThrows(IllegalStateException.class, () -> svc.read("key"))` | + | 8 | **Corrupted/invalid data in store** | App deserializes data from external store (JSON from Redis, parsed blob content) | Write corrupted/malformed data directly to the store, then call the app's read method; verify the deserialization error is properly handled | `redis.set("key", "{bad-json}"); assertThrows(RuntimeException.class, () -> mgr.get("key"))` | + + **Self-check:** Count your error test methods. If you have fewer than 3 error tests from the table above, you almost certainly have gaps. Go back and add more. + +### Cover downstream consumers + +If the migrated code produces output consumed by other components (config generators, report builders), test those consumers too. Verify output is consumable by the next component in the pipeline — write then read back through the real consumer API to confirm round-trip correctness. + +### Only label tests as integration tests if they integrate external systems + +Tests with no containers, network, or filesystem dependencies are unit tests, which is not within the IT scope. Do not generate them alongside integration tests. + +### Stay scoped to the migration target + +Only generate tests for code that uses the migrated service. Do not generate unrelated tests for general project utilities. + +### DO NOT use any test ordering mechanism — this is an AUTOMATIC QUALITY DEDUCTION + +This includes JUnit 5 `@Order` / `@TestMethodOrder`, TestNG `dependsOnMethods` / `priority`, and any other framework-specific ordering. Tests MUST be independent and run in any order. Each test must create its own data and clean up after itself. Test ordering indicates shared mutable state — a critical quality issue. Evaluators specifically check for `@Order` and `@TestMethodOrder` annotations and will deduct points for their presence. + + **Anti-pattern — DO NOT DO THIS:** + ```java + // WRONG: @Order creates test interdependence — automatic quality deduction + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class MyL1Test { + @Test @Order(1) void testCreate() { ... } + @Test @Order(2) void testRead() { ... } // implicitly depends on testCreate + } + ``` + + **Correct pattern:** + ```java + // RIGHT: Each test is self-contained with its own setup + class MyL1Test { + @BeforeEach void cleanup() { /* clean all state */ } + @Test void testCreate() { /* creates its own data */ } + @Test void testRead() { /* creates its own data, then reads */ } + } + ``` +### DO NOT use reflection to access or modify private fields, and DO NOT widen field visibility (private->protected/public) in production code for test access. + +Both approaches are fragile and tightly couple tests to implementation details. Reflection breaks on Java 17+ with strong encapsulation. Widening visibility pollutes the production API and can cause compilation errors when test classes are in a different package (protected access requires same package or subclass). Instead: + - For singletons: add a package-private or test-visible constructor/factory method to the production class (minimal safe change). + - For environment variables: use `@DynamicPropertySource`, `System.setProperty()` with matching application code reads, constructor/setter injection, or `@TestConfiguration` beans. + - For configuration files: use `@TestPropertySource`, classpath-based overrides in `src/test/resources/`, or `@DynamicPropertySource`. + - For injecting test dependencies: use constructor injection, setter injection, or `@TestConfiguration` with `@Primary` beans. + - For inspecting internal state: add a package-private getter method or test the observable behavior (outputs, side effects) instead of reading internal fields. + +### DO write specific, descriptive assertions + + ```java + // WRONG — poor failure message: "expected: true but was: false" + assertTrue(containers.contains("my-container")); + assertTrue(ex.getCause() instanceof SomeException); + + // RIGHT — clear failure message showing actual values + assertThat(containers).contains("my-container"); + assertThat(ex.getCause()).isInstanceOf(SomeException.class); + assertThat(result.getName()).isEqualTo("expected-name"); // shows both values on failure + ``` + + Regardless of library, always assert on specific values — not just `assertNotNull(result)` or `assertTrue(success)`. Include `assertInstanceOf()` (JUnit 5.8+) instead of `assertTrue(x instanceof Y)` for better error messages. + +### DO structure every test with clear Arrange-Act-Assert (AAA) sections + separated by blank lines. Each test should verify ONE logical behavior. Do not combine multiple unrelated operations in a single test method. + +### DO add `@BeforeEach` cleanup when tests share a container + +If multiple tests use the same TestContainers instance (e.g., a shared Redis or Azurite container), each test must clean up its state in `@BeforeEach` or `@AfterEach` (e.g., flush Redis, delete all blob containers, truncate database tables). Stale data from one test must never affect another. Without cleanup, test execution order determines results — a critical reliability issue. + +### DO verify the test count after `mvn verify` matches expectations + +Before committing, run `mvn verify` and confirm the number of tests discovered and executed matches the number of test methods you wrote. If the count is lower, some tests are not being discovered — fix the build configuration. + +### DO extract shared test infrastructure into a base class or helper when you have 2+ test classes + +If multiple test classes use the same TestContainers setup (e.g., same Azurite/Redis/PostgreSQL container), extract the container declaration, connection string construction, and `@DynamicPropertySource` into a shared abstract base class (e.g., `AbstractAzuriteL1Test` or `AbstractRedisL1Test`). This eliminates duplication and ensures consistent infrastructure configuration. Each test class that needs the container simply extends the base class. + + > For an Azurite-specific shared base class example (`AbstractAzuriteL1Test`), see [azure-storage-testcontainers.md](./azure-storage-testcontainers.md#4-shared-azurite-base-class). + +### DO extract commonly repeated test patterns into helper methods + +If you find yourself writing the same 3+ lines more than twice (e.g., listing blob names, creating a user and getting the ID, uploading test data), extract it into a descriptive helper method. This improves readability and reduces maintenance burden. + +### DO NOT leave `System.out.println` or debug logging statements in test code + +Remove all diagnostic print statements (`System.out.println`, `System.err.println`, `e.printStackTrace()`) before committing. If you need to inspect state during development, use proper assertions instead. Debug output clutters test logs, makes failures harder to diagnose, and indicates incomplete cleanup. + +### NEVER use `Thread.sleep()` to wait for containers to start + +TestContainers' `.start()` already waits for exposed ports to be ready. If you need additional readiness checks, use `.waitingFor(Wait.forListeningPort())` or `.waitingFor(Wait.forLogMessage(...))` on the container definition. `Thread.sleep()` is a flakiness time bomb — too short on slow CI, too long on fast machines. + +**Anti-pattern — DO NOT DO THIS:** +```java +// WRONG: Arbitrary sleep after container start +container.start(); +Thread.sleep(2000); // flaky — may be too short or too long +``` + +**Correct pattern:** +```java +// RIGHT: Use TestContainers built-in wait strategy +static final GenericContainer<?> myContainer = new GenericContainer<>("image:latest") + .withExposedPorts(PORT) + .waitingFor(Wait.forListeningPort()); // Reliable readiness check +``` diff --git a/.github/skills/integration-tests/references/layer2-runner-script-templates.md b/.github/skills/integration-tests/references/layer2-runner-script-templates.md new file mode 100644 index 000000000..76b69ef0a --- /dev/null +++ b/.github/skills/integration-tests/references/layer2-runner-script-templates.md @@ -0,0 +1,287 @@ +# Layer 2 Runner Script Templates + +## Script Role + +The runner script is a **test runner only**. It starts infrastructure, builds the app, runs smoke tests, and reports results. It does NOT manage git commits or handle test failures — that is the agent's responsibility. + +## When to Use + +- **Agent execution (during Layer 2 generation):** After creating the auth commit (Step 4), the agent executes this script to run smoke tests. If tests fail, the agent analyzes errors, applies fixes, and re-runs the script. +- **User execution (manual re-runs):** Users must checkout the auth commit first, then run the script to verify smoke tests still pass. + +## Placeholders to Replace + +When generating the scripts, replace these placeholders with project-specific values: + +- `<project-specific-build-command>`: The build command for the detected project type + - Maven: `mvn package -DskipTests` + - Gradle: `./gradlew build -x test` + - .NET: `dotnet build` + - npm: `npm run build` + +- `<project-specific-start-command>`: The command to start the application + - Maven (Spring Boot): `mvn spring-boot:run` or `java -jar target/*.jar` + - Gradle (Spring Boot): `./gradlew bootRun` or `java -jar build/libs/*.jar` + - .NET: `dotnet run` or `dotnet MyApp.dll` + - npm: `npm start` + +## Bash Template (run-layer2-tests.sh) + +**NOTE:** This script should be placed in `{modernization-work-folder}/integration-tests/`. The script navigates to the project root to execute commands. + +```bash +#!/bin/bash +set -e + +# --- Auto-generated Layer 2 smoke test runner --- +# Project: {ProjectName} ({Language}, {Framework}) +# Starts infrastructure, builds and runs the app, verifies it stays alive +# and responds to HTTP requests without fatal errors. +# +# Usage: +# bash {modernization-work-folder}/integration-tests/run-layer2-tests.sh +# +# Environment variable overrides (optional): +# APP_PORT - Application port (default: 8080) +# HEALTH_PATH - Health endpoint (default: /) + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" # Navigate to project root +COMPOSE_FILE="$PROJECT_ROOT/src/test/resources/docker-compose.smoke.yml" +APP_LOG="/tmp/app-smoke-$$.log" + +APP_PORT="${APP_PORT:-8080}" +APP_URL="http://localhost:$APP_PORT" +HEALTH_PATH="${HEALTH_PATH:-/health}" # Adjust to detected health endpoint +STARTUP_TIMEOUT=60 +STABILITY_WAIT=5 +CHECKS_PASSED=0 +CHECKS_FAILED=0 +APP_PID="" + +pass() { echo " ✅ $1"; CHECKS_PASSED=$((CHECKS_PASSED + 1)); } +fail() { echo " ❌ $1"; CHECKS_FAILED=$((CHECKS_FAILED + 1)); } + +cleanup() { + [ -n "$APP_PID" ] && kill $APP_PID 2>/dev/null || true + [ -n "$APP_PID" ] && wait $APP_PID 2>/dev/null || true + docker compose -f "$COMPOSE_FILE" down -v 2>/dev/null || true + rm -f "$APP_LOG" +} +trap cleanup EXIT + +cd "$PROJECT_ROOT" + +# --- Step 1: Verify Docker --- +docker info > /dev/null 2>&1 || { echo "ERROR: Docker is not running."; exit 1; } + +# --- Step 2: Start infrastructure --- +echo "Starting infrastructure..." +docker compose -f "$COMPOSE_FILE" up -d --wait + +# --- Step 3: Build --- +echo "Building application..." +<project-specific-build-command> + +# --- Step 4: Start application --- +echo "Starting application..." +<project-specific-start-command> > "$APP_LOG" 2>&1 & +APP_PID=$! + +# --- Step 5: Check — Process alive --- +sleep $STABILITY_WAIT +if kill -0 $APP_PID 2>/dev/null; then + pass "Process is alive (PID $APP_PID)" +else + fail "Process crashed on startup" + tail -20 "$APP_LOG" 2>/dev/null || true + exit 1 +fi + +# --- Step 6: Check — Health probe --- +HEALTH_STATUS="000" +for i in $(seq 1 $STARTUP_TIMEOUT); do + HEALTH_STATUS=$(curl -sf -o /dev/null -w "%{http_code}" "${APP_URL}${HEALTH_PATH}" 2>/dev/null || echo "000") + [ "$HEALTH_STATUS" != "000" ] && break + kill -0 $APP_PID 2>/dev/null || { fail "Process died during health probe"; break; } + sleep 1 +done +[[ "$HEALTH_STATUS" =~ ^[1234] ]] && pass "Health probe (HTTP $HEALTH_STATUS)" \ + || fail "Health probe failed (HTTP $HEALTH_STATUS)" + +# --- Step 7: Check — Clean startup logs --- +if grep -qiE "FATAL|panic|unhandled.exception|OutOfMemory|StackOverflow|segfault" "$APP_LOG" 2>/dev/null; then + fail "Fatal error patterns in startup logs" +else + pass "No fatal errors in startup logs" +fi + +# --- Summary --- +echo "" +echo "========================================" +echo "Results: $CHECKS_PASSED passed, $CHECKS_FAILED failed" +if [ $CHECKS_FAILED -gt 0 ]; then + echo "❌ Layer 2 smoke tests FAILED" + exit 1 +fi +echo "✅ Layer 2 smoke tests PASSED" +echo "========================================" +``` + +## PowerShell Template (run-layer2-tests.ps1) + +**NOTE:** This script should be placed in `{modernization-work-folder}/integration-tests/`. The script navigates to the project root to execute commands. + +```powershell +#Requires -Version 5.1 +$ErrorActionPreference = "Stop" + +# --- Auto-generated Layer 2 smoke test runner --- +# Project: {ProjectName} ({Language}, {Framework}) +# Starts infrastructure, builds and runs the app, verifies it stays alive +# and responds to HTTP requests without fatal errors. +# +# Usage: +# powershell {modernization-work-folder}/integration-tests/run-layer2-tests.ps1 +# +# Environment variable overrides (optional): +# APP_PORT - Application port (default: 8080) +# HEALTH_PATH - Health endpoint (default: /) + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ProjectRoot = Resolve-Path (Join-Path $ScriptDir "..\..") # Navigate to project root +$ComposeFile = Join-Path $ProjectRoot "src\test\resources\docker-compose.smoke.yml" +$AppLog = Join-Path $env:TEMP "app-smoke-$PID.log" + +$AppPort = if ($env:APP_PORT) { $env:APP_PORT } else { 8080 } +$AppUrl = "http://localhost:$AppPort" +$HealthPath = if ($env:HEALTH_PATH) { $env:HEALTH_PATH } else { "/health" } +$StartupTimeout = 60 +$StabilityWait = 5 +$ChecksPassed = 0 +$ChecksFailed = 0 +$AppProcess = $null + +function Pass($message) { + Write-Host " ✅ $message" -ForegroundColor Green + $script:ChecksPassed++ +} + +function Fail($message) { + Write-Host " ❌ $message" -ForegroundColor Red + $script:ChecksFailed++ +} + +function Cleanup { + if ($AppProcess -and !$AppProcess.HasExited) { + Stop-Process -Id $AppProcess.Id -Force -ErrorAction SilentlyContinue + Wait-Process -Id $AppProcess.Id -ErrorAction SilentlyContinue + } + docker compose -f $ComposeFile down -v 2>$null + if (Test-Path $AppLog) { Remove-Item $AppLog -Force } +} + +# Register cleanup +try { + Set-Location $ProjectRoot + + # --- Step 1: Verify Docker --- + docker info >$null 2>&1 + if ($LASTEXITCODE -ne 0) { + Write-Host "ERROR: Docker is not running." -ForegroundColor Red + exit 1 + } + + # --- Step 2: Start infrastructure --- + Write-Host "Starting infrastructure..." + docker compose -f $ComposeFile up -d --wait + + # --- Step 3: Build --- + Write-Host "Building application..." + <project-specific-build-command> + + # --- Step 4: Start application --- + Write-Host "Starting application..." + $AppProcess = Start-Process -FilePath <project-specific-start-command> -RedirectStandardOutput $AppLog -RedirectStandardError $AppLog -PassThru -NoNewWindow + + # --- Step 5: Check — Process alive --- + Start-Sleep -Seconds $StabilityWait + if (!$AppProcess.HasExited) { + Pass "Process is alive (PID $($AppProcess.Id))" + } else { + Fail "Process crashed on startup" + if (Test-Path $AppLog) { Get-Content $AppLog -Tail 20 } + exit 1 + } + + # --- Step 6: Check — Health probe --- + $HealthStatus = "000" + for ($i = 1; $i -le $StartupTimeout; $i++) { + try { + $response = Invoke-WebRequest -Uri "$AppUrl$HealthPath" -UseBasicParsing -TimeoutSec 1 -ErrorAction SilentlyContinue + $HealthStatus = $response.StatusCode + break + } catch { + $HealthStatus = "000" + } + if ($AppProcess.HasExited) { + Fail "Process died during health probe" + break + } + Start-Sleep -Seconds 1 + } + if ($HealthStatus -match "^[1234]") { + Pass "Health probe (HTTP $HealthStatus)" + } else { + Fail "Health probe failed (HTTP $HealthStatus)" + } + + # --- Step 7: Check — Clean startup logs --- + if (Test-Path $AppLog) { + $logContent = Get-Content $AppLog -Raw + if ($logContent -match "(?i)(FATAL|panic|unhandled.?exception|OutOfMemory|StackOverflow|segfault)") { + Fail "Fatal error patterns in startup logs" + } else { + Pass "No fatal errors in startup logs" + } + } + + # --- Summary --- + Write-Host "" + Write-Host "========================================" + Write-Host "Results: $ChecksPassed passed, $ChecksFailed failed" + if ($ChecksFailed -gt 0) { + Write-Host "❌ Layer 2 smoke tests FAILED" -ForegroundColor Red + exit 1 + } + Write-Host "✅ Layer 2 smoke tests PASSED" -ForegroundColor Green + Write-Host "========================================" +} finally { + Cleanup +} +``` + +## Script Behavior + +### What the Script Does + +1. **Verify Docker** — Check if Docker is running +2. **Start infrastructure** — `docker compose up` with all dependencies +3. **Build application** — Run project-specific build command +4. **Start application** — Run in background, log to temp file +5. **Check: Process alive** — Verify process didn't crash (5s stability wait) +6. **Check: Health probe** — HTTP health check (60s timeout, any non-5xx = pass) +7. **Check: Clean logs** — Scan for fatal error patterns (FATAL, panic, OOM, etc.) +8. **Report results** — Print pass/fail summary +9. **Cleanup** — Kill app, docker down, remove temp log + +### Exit Codes + +- `0` — All checks passed +- `1` — One or more checks failed + +### Environment Variables (Optional) + +Users can override defaults: +- `APP_PORT` — Application port (default: 8080) +- `HEALTH_PATH` — Health endpoint path (default: /health) diff --git a/.github/skills/integration-tests/references/layer2-smoke-tests.md b/.github/skills/integration-tests/references/layer2-smoke-tests.md new file mode 100644 index 000000000..f85215ee1 --- /dev/null +++ b/.github/skills/integration-tests/references/layer2-smoke-tests.md @@ -0,0 +1,261 @@ +# Layer 2: Smoke Tests + +**Goal:** "Does the whole application start and stay alive?" + +Verify the complete application boots successfully, reaches a healthy state, and produces no crash-level errors. Layer 2 does **NOT** test individual features, APIs, or business logic — that is Layer 1's responsibility. + +## What Layer 2 Is and Is Not + +| Layer 2 IS | Layer 2 IS NOT | +|------------|----------------| +| Verifying the process starts without crashing | Testing specific API endpoints or features | +| Checking a single health/readiness probe | Hitting every REST route or gRPC method | +| Scanning startup logs for fatal errors | Asserting on response payloads or data | +| Detecting missing configuration or broken DI | Exercising SDK integrations or components | +| Provisioning ALL infrastructure the app needs | Only setting up migrated-component containers | + +## No Test Classes Required + +Layer 2 does **NOT** generate test classes. The runner script (`run-layer2-tests.sh` / `run-layer2-tests.ps1`) **is** the test — it provisions infrastructure, starts the app, runs health checks via `curl` and shell built-ins, and reports pass/fail. No JUnit test code. + +**Layer 2 is independent of Layer 1.** Layer 1 tests only migrated components; Layer 2 must provision ALL application dependencies. + +## Prerequisites + +- Application builds successfully +- Docker installed and running + +## Azure Authentication for Smoke Tests + +Migrated applications typically use **Managed Identity** (`DefaultAzureCredential`) which only works on Azure infrastructure. For local smoke testing, you must modify the application to connect to local emulators instead. + +**See [azure-auth-strategies.md](./azure-auth-strategies.md) for:** +- How to classify Azure dependencies (Emulatable, Lazy, Non-emulatable) +- Emulator images and configuration +- Authentication modification strategies (config-driven vs code-driven apps) +- Emulator connection string values +- Decision flow for handling each dependency type + +**Summary:** For each Azure dependency, determine if it's emulatable (use local emulator), lazy (skip), or startup-required non-emulatable (disable via config or recommend Layer 3). + +## Workflow + +> **CRITICAL — Commit order matters.** Follow Steps 1–8 in exact order. The artifacts commit (Step 3) MUST come before the auth commit (Step 4). Do not combine them. Do not reorder them. + +The workflow produces **a multi-commit sequence** (exactly 3 commits): + +| # | Commit | Contains | +|---|--------|----------| +| 1 | `[layer-2] Add smoke test artifacts` | docker-compose.smoke.yml, runner scripts, AND any source code fixes needed for smoke tests to pass. **All fixes (infrastructure, runner scripts, source code) must be amended to this commit.** | +| 2 | `[smoke-test] Replace Managed Identity with emulator connection strings` | Config file changes (e.g., `application.properties`) with explicit emulator connection strings, and any necessary auth-related code changes. **Auth-related fixes must be amended to this commit.** | +| 3 | `[smoke-test] Restore Managed Identity auth` | Reverts **only commit 2** by SHA — restores original Managed Identity config | + +**CRITICAL — Amend strategy:** +- Fixes to docker-compose.smoke.yml → amend commit 1 +- Fixes to runner scripts → amend commit 1 +- Source code bugs discovered during testing (DI wiring, null refs, etc.) → **amend commit 1** +- Fixes to auth config files → amend commit 2 +- Fixes to auth-related code → amend commit 2 + +This ensures when users checkout commit 2 (auth) to run smoke tests locally, they have ALL fixes: commit 1 contains working artifacts AND all source code fixes, commit 2 contains working auth config. + +The agent executes the smoke test runner script (Step 7) after creating commit 2, and may need to amend commits 1 or 2 during retries. + +**Retry on failure:** If the runner script fails, the agent analyzes the output and attempts a fix: +- **Smoke-artifact failure** (wrong port in compose, bad docker-compose config, bad runner script) → **amend commit 1** with fixes and re-run Step 7 +- **Source-code failure** (broken DI wiring, null reference in initializer, missing config guard, startup crash from migrated code) → **amend commit 1** with fixes and re-run Step 7. Apply the **Handling Test Failures** guidance from the main skill file. +- **Auth-config failure** (wrong connection string in config file, missing config property, auth-related code issue) → **amend commit 2** with fixes and re-run Step 7 + +Max **3 retries** total (across all failure types). If the agent cannot diagnose the root cause or the fix would require architectural changes, stop and report. + +### Step 1: Analyze ALL Application Dependencies + +Scan the **entire** application to identify every external dependency required for startup: + +- Build files: `pom.xml`, `build.gradle`, `*.csproj`, `package.json` +- Config: `application.yml`, `application.properties`, `appsettings.json`, `.env` +- Source code: client initializations, `@Autowired`/`@Inject` services +- Existing Docker/compose files + +**For each Azure dependency, classify it** using the decision flow from [azure-auth-strategies.md](./azure-auth-strategies.md): +- **Emulatable** → Add emulator to docker-compose, will modify auth in Step 4 +- **Lazy** → Skip (doesn't block startup) +- **Non-emulatable** → Disable via config in Step 4, or recommend Layer 3 + +**For non-Azure dependencies:** + +| Category | Example | Action | +|----------|---------|--------| +| Standard databases | PostgreSQL, MySQL, MongoDB, Redis | Add to `docker-compose.smoke.yml` with standard image | +| Azure wire-compatible | Azure DB for PostgreSQL/MySQL, Azure Cache for Redis, Azure SQL | Use open-source image (`postgres:16`, `redis:7`, `mcr.microsoft.com/mssql/server`) | + +**Rules:** Include anything that crashes the app on startup. Skip lazy/on-demand dependencies. Reuse Docker images and ports from Layer 1 where applicable. If an existing `docker-compose.yml` already defines all needed services, prefer reusing it. + +### Step 2: Generate Docker Compose + +Create `docker-compose.smoke.yml` in the test resources directory. The file provisions ALL required dependencies. Every service must have a healthcheck. Include proper ports and volume mounts. + +**File location:** `src/test/resources/docker-compose.smoke.yml` + +### Step 3: Generate Runner Scripts and Commit Artifacts + +Generate `run-layer2-tests.sh` and `run-layer2-tests.ps1` (see Runner Script Template below). + +**File locations:** +- `{modernization-work-folder}/integration-tests/run-layer2-tests.sh` +- `{modernization-work-folder}/integration-tests/run-layer2-tests.ps1` + +Then commit all generated artifacts: + +``` +git add -A +git commit -m "[layer-2] Add smoke test artifacts" +``` + +This commit initially contains only generated files (docker-compose.smoke.yml, runner scripts). No source code changes yet. Files in `.github/` may be excluded if the project's `.gitignore` blocks them — this is acceptable. + +**CRITICAL:** If smoke tests fail during Step 7, amend this commit with ALL fixes: +``` +# After fixing docker-compose.smoke.yml, runner scripts, OR source code +git add -A +git commit --amend --no-edit +``` + +This includes source code bugs discovered during smoke testing. The commit message says "Add smoke test artifacts" but the commit will contain test infrastructure (docker-compose, runner scripts) AND source code fixes needed for tests to pass. This ensures users who checkout the auth commit (Step 4) will have all fixes via this commit in git history. + +### Step 4: Commit Auth Changes + +**CRITICAL:** This step is MANDATORY. You must ALWAYS create an auth commit that modifies config files. + +Modify the application configuration files (NOT environment variables) to use explicit emulator connection strings. See [azure-auth-strategies.md](./azure-auth-strategies.md) for: +- Which config files to modify (`application.properties`, `appsettings.json`, etc.) +- Emulator connection string formats +- Code modification patterns if needed + +Create the auth commit: + +```bash +git add -A +git commit -m "[smoke-test] Replace Managed Identity with emulator connection strings" +``` + +Record the commit SHA for Step 8. + +### Step 5: Verify Config File Changes + +**Do NOT modify runner scripts with environment variables.** The config files from Step 4 contain all necessary connection strings. + +Verify that the auth commit includes: +- All modified config files with explicit connection string values +- Any code changes if the app was hardcoded/plain application +- No environment variable exports or overrides + +The runner scripts will start the application as-is, and the app will read connection strings from the config files you just modified. + +### Step 6: Auto-Detect Application Type + +Analyze the project to determine how it starts and how to verify liveness: + +| Indicator | App Type | Start Command | Liveness Check | +|-----------|----------|---------------|----------------| +| Spring Boot, `@SpringBootApplication` | Java Web/API | `./mvnw spring-boot:run` or `java -jar` | HTTP health probe | +| `@Scheduled`, background jobs | Worker/Background | `./mvnw spring-boot:run` | Process stays alive for N seconds | +| `main()` with no server | CLI/Batch | `java -jar` | Process exits with code 0 | + +### Step 7: Execute Smoke Tests via Runner Script + +After creating the auth commit (Step 4) and detecting the application type (Step 6), execute the smoke test runner script: + +```bash +bash {modernization-work-folder}/integration-tests/run-layer2-tests.sh +# OR on Windows: +powershell {modernization-work-folder}/integration-tests/run-layer2-tests.ps1 +``` + +**The script will:** +1. Verify Docker is running +2. Start infrastructure (`docker compose up`) +3. Build the application +4. Start the application in background +5. Run three health checks: + - **Check 1:** Process is alive after stability wait (5s) + - **Check 2:** Health probe returns non-5xx HTTP response (web/API apps only) + - **Check 3:** No fatal error patterns in startup logs (FATAL, panic, OutOfMemory, etc.) +6. Report pass/fail and exit with appropriate code +7. Clean up (kill app, docker down) + +**If the script exits with code 0:** +- ✅ Tests passed +- Proceed to Step 8 (create restore commit) + +**If the script exits with non-zero:** +- ❌ Tests failed (likely auth-config issues) +- Analyze the script's output to determine root cause +- **Amend the auth commit (Step 5)** with fixes +- Re-run the script (max 3 retries total) + +**Important:** At this point, all source code fixes should already be done (Step 4). Failures here are typically auth configuration issues (wrong connection strings, missing config properties). + +**CRITICAL — Do NOT Create Test Classes:** +- Layer 2 does NOT use JUnit test classes +- The runner script IS the test - it uses shell commands (curl, grep, etc.) +- Do NOT create any `.java` test files for Layer 2 +- If you need to improve smoke testing, modify the runner scripts, not create test classes + +### Step 8: Create Restore Commit + +After smoke tests pass, create the restore commit to restore Managed Identity auth: + +```bash +git revert --no-edit <auth-commit-sha> +git commit --amend -m "[smoke-test] Restore Managed Identity auth" +``` + +This keeps the auth commit in history (visible in `git log`) while restoring the codebase to use Managed Identity. + +**CRITICAL:** All smoke test artifacts (docker-compose.smoke.yml, runner scripts) and source code fixes are in commit 1. Users can checkout the auth commit (commit 2) to run smoke tests locally and will have all necessary fixes via commit 1 in git history. + +## Handling Failures + +**CRITICAL:** All fixes must be amended to either commit 1 (smoke artifacts + source code) or commit 2 (auth config). Never create separate fix commits. + +Testing happens in Step 7 (after both commits 1 and 2 are created). When failures occur: + +| Failure | Likely Cause | Action | +|---------|-------------|--------| +| Infrastructure won't start | Port conflict, Docker issue, bad docker-compose config | **Amend commit 1** (fix docker-compose.smoke.yml) and re-run Step 7 | +| Build fails | Compile error in source code, missing dependencies | **Amend commit 1** (fix source code) and re-run Step 7. Apply Handling Test Failures guidance. | +| Process crashes immediately | Broken DI wiring, null ref, missing config guard, startup crash, OR wrong auth config | **Analyze stack trace** → amend commit 1 (source code bugs) or commit 2 (auth issues) and re-run Step 7 | +| Runner script fails | Wrong app start command, incorrect paths, bad classpath | **Amend commit 1** (fix runner scripts) and re-run Step 7 | +| Health probe times out | Wrong port in config, slow startup | **Amend commit 1** (fix runner script health check) and re-run Step 7 | +| Health probe returns 5xx | Internal error from missing config or code bug | **Analyze** → amend commit 1 (code) or commit 2 (auth) and re-run Step 7 | +| Fatal log patterns | Unhandled exceptions at startup | **Analyze stack trace** → amend commit 1 (source code) or commit 2 (auth config) if root cause is identifiable; otherwise report | +| Fatal log patterns | Unhandled exceptions at startup | **Analyze stack trace → fix** if root cause is identifiable; otherwise report | + +**Key principles:** +- Layer 2 fixes **both** its own generated artifacts **and** source-code issues it discovers. The goal is a passing smoke test, not just a report. +- Use the **Handling Test Failures** guidance from the main skill file to decide what to fix and how. +- Keep source-code fixes **minimal and targeted** — fix the specific startup blocker (e.g., null guard, missing config binding, broken DI registration). Do not refactor or change architecture. +- Max **3 retries** total. If the root cause is unclear, the fix would require architectural changes, or the app genuinely needs a real Azure service with no workaround, stop and report. + +## Standardized Runner Scripts + +Generate `run-layer2-tests.sh` and `run-layer2-tests.ps1` in `{modernization-work-folder}/integration-tests/`. These are test runners that start infrastructure, build the app, run smoke tests, and report results. + +**See [layer2-runner-script-templates.md](./layer2-runner-script-templates.md) for:** +- Complete bash and PowerShell script templates +- Placeholder replacement guide +- Script behavior and exit codes +- Environment variable overrides + +Users run: +- Unix: `bash {modernization-work-folder}/integration-tests/run-layer2-tests.sh` +- Windows: `powershell {modernization-work-folder}/integration-tests/run-layer2-tests.ps1` + +## Pass Criteria + +- All infrastructure containers reach healthy state +- Application builds and starts without crashing +- Health probe returns non-5xx (web/API apps) +- No fatal-level errors in startup logs +- Clean shutdown of app and infrastructure diff --git a/.github/skills/integration-tests/references/layer3-azure-integration.md b/.github/skills/integration-tests/references/layer3-azure-integration.md new file mode 100644 index 000000000..df30130ef --- /dev/null +++ b/.github/skills/integration-tests/references/layer3-azure-integration.md @@ -0,0 +1,194 @@ +# Layer 3: Azure Integration Tests + +**Goal:** "Does it work in real cloud environment?" + +Deploy to Azure staging environment and test against real Azure services. + +## Test Isolation + +- **DO use `L3Test` as the class name suffix** for all Layer 3 test classes (e.g., `AzureSqlL3Test`, `BlobStorageL3Test`). The `*Test` suffix matches Maven Surefire's default discovery pattern — no build plugin changes needed. +- **DO annotate every test class with a `Layer3` tag/category** so runner scripts filter precisely and never trigger Layer 1, 2, or 4 tests. See the Test Isolation Convention in the main skill file for the exact annotation per language/framework. +- The runner script **MUST filter by the `Layer3` tag** (e.g., `mvn verify -Dgroups=Layer3`, `dotnet test --filter Category=Layer3`, `pytest -m layer3`) + +## Prerequisites + +- Azure subscription with staging environment +- Azure CLI installed and authenticated +- Infrastructure-as-Code templates (Bicep/ARM/Terraform) + +## Workflow + +### 1. Identify Azure Services + +Map application dependencies to Azure services: + +| Local Dependency | Azure Service | Configuration Needed | +|-----------------|---------------|---------------------| +| SQL Server | Azure SQL Database | Connection string, firewall | +| PostgreSQL | Azure Database for PostgreSQL | Connection string, SSL | +| Redis | Azure Cache for Redis | Connection string, access key | +| File storage | Azure Blob Storage | Connection string, container | +| Message queue | Azure Service Bus | Connection string, queue | +| Key vault | Azure Key Vault | Managed identity, access policy | +| Logging | Application Insights | Instrumentation key | + +### 2. Deploy to Staging + +#### Using Azure CLI + +```bash +# Set variables +RESOURCE_GROUP="rg-app-staging" +LOCATION="eastus" +APP_NAME="app-integration-test-$(date +%s)" + +# Create resource group +az group create --name $RESOURCE_GROUP --location $LOCATION + +# Deploy infrastructure +az deployment group create \ + --resource-group $RESOURCE_GROUP \ + --template-file infra/main.bicep \ + --parameters environment=staging + +# Deploy application +az webapp deploy \ + --resource-group $RESOURCE_GROUP \ + --name $APP_NAME \ + --src-path ./publish.zip +``` + +#### Using GitHub Actions + +```yaml +- name: Deploy to Staging + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ env.APP_NAME }} + slot-name: staging + package: ./publish.zip +``` + +### 3. Configure Azure Services + +```bash +# Get connection strings from deployed resources +SQL_CONN=$(az sql db show-connection-string \ + --server $SQL_SERVER \ + --name $DB_NAME \ + --client ado.net) + +REDIS_CONN=$(az redis list-keys \ + --resource-group $RESOURCE_GROUP \ + --name $REDIS_NAME \ + --query primaryKey -o tsv) + +STORAGE_CONN=$(az storage account show-connection-string \ + --resource-group $RESOURCE_GROUP \ + --name $STORAGE_NAME \ + --query connectionString -o tsv) + +# Update app settings +az webapp config appsettings set \ + --resource-group $RESOURCE_GROUP \ + --name $APP_NAME \ + --settings \ + "ConnectionStrings__Default=$SQL_CONN" \ + "Redis__ConnectionString=$REDIS_CONN" \ + "Storage__ConnectionString=$STORAGE_CONN" +``` + +### 4. Run Integration Tests Against Staging + +```bash +# Set test target to staging URL +export TEST_BASE_URL="https://$APP_NAME.azurewebsites.net" + +# Run Layer 3 integration tests only (filter by Layer3 tag) +dotnet test --filter Category=Layer3 +``` + +Test scenario areas for Azure (all tagged with `Layer3`): + +| Scenario Area | Tests | +|----------|-------| +| Database | CRUD operations, transactions, stored procedures | +| Storage | Blob upload/download, container operations | +| Cache | Get/set, expiration, distributed locks | +| Messaging | Send/receive, dead letter, retry | +| Identity | Authentication, authorization, managed identity | + +### 5. Validate Azure-Specific Features + +```csharp +[Trait("Category", "Layer3")] +public class AzureSqlL3Test +{ + [Fact] + public async Task CanConnectToAzureSql() + { + await using var conn = new SqlConnection(_connectionString); + await conn.OpenAsync(); + conn.State.Should().Be(ConnectionState.Open); + } + + [Fact] + public async Task TransactionWorksAcrossMultipleTables() + { + // Test Azure SQL transaction behavior + } +} + +[Trait("Category", "Layer3")] +public class AzureBlobL3Test +{ + [Fact] + public async Task CanUploadAndDownloadBlob() + { + var container = _blobClient.GetBlobContainerClient("test"); + await container.CreateIfNotExistsAsync(); + + var blob = container.GetBlobClient("test.txt"); + await blob.UploadAsync(new BinaryData("test content")); + + var downloaded = await blob.DownloadContentAsync(); + downloaded.Value.Content.ToString().Should().Be("test content"); + } +} +``` + +### 6. Collect Metrics and Logs + +```bash +# Get Application Insights logs +az monitor app-insights query \ + --app $APP_INSIGHTS_NAME \ + --analytics-query "traces | where timestamp > ago(1h) | order by timestamp desc | take 100" + +# Check for errors +az monitor app-insights query \ + --app $APP_INSIGHTS_NAME \ + --analytics-query "exceptions | where timestamp > ago(1h)" + +# Get performance metrics +az monitor metrics list \ + --resource $APP_RESOURCE_ID \ + --metric "Requests,AverageResponseTime,Http5xx" +``` + +### 7. Cleanup + +```bash +# Delete staging resources +az group delete --name $RESOURCE_GROUP --yes --no-wait +``` + +## Pass Criteria + +- Application deploys successfully to Azure +- All Azure service connections work +- Integration tests pass against real services +- No 5xx errors in Application Insights +- Performance is within acceptable thresholds +- Logs show no critical errors +- Runner scripts generated per the Standardized Runner Scripts convention in the main skill file diff --git a/.github/skills/integration-tests/references/layer4-behavioral-comparison.md b/.github/skills/integration-tests/references/layer4-behavioral-comparison.md new file mode 100644 index 000000000..0eceb1c71 --- /dev/null +++ b/.github/skills/integration-tests/references/layer4-behavioral-comparison.md @@ -0,0 +1,242 @@ +# Layer 4: Behavioral Comparison + +**Goal:** "Does it match the original?" + +Run old and new versions side-by-side and compare outputs for identical inputs. + +## Test Isolation + +- **DO use `L4Test` as the class name suffix** for all Layer 4 behavioral comparison test classes (e.g., `OrderApiL4Test`, `UserServiceL4Test`). The `*Test` suffix matches Maven Surefire's default discovery pattern — no build plugin changes needed. +- **DO annotate every test class with a `Layer4` tag/category** so runner scripts filter precisely and never trigger Layer 1, 2, or 3 tests. See the Test Isolation Convention in the main skill file for the exact annotation per language/framework. +- The runner script **MUST filter by the `Layer4` tag** (e.g., `mvn verify -Dgroups=Layer4`, `dotnet test --filter Category=Layer4`, `pytest -m layer4`) + +## Prerequisites + +- Access to both original and migrated application code +- Ability to run both versions simultaneously +- Test data/scenarios from production or comprehensive test suite + +## Workflow + +### 1. Set Up Side-by-Side Environment + +``` +┌─────────────────┐ ┌─────────────────┐ +│ Original App │ │ Migrated App │ +│ (Port 8080) │ │ (Port 8081) │ +└────────┬────────┘ └────────┬────────┘ + │ │ + └───────────┬───────────┘ + │ + ┌──────┴──────┐ + │ Comparator │ + │ Tests │ + └─────────────┘ +``` + +#### Docker Compose Setup + +```yaml +version: '3.8' +services: + original-app: + build: + context: ./original + ports: + - "8080:80" + environment: + - ConnectionStrings__Default=${DB_CONNECTION} + + migrated-app: + build: + context: ./migrated + ports: + - "8081:80" + environment: + - ConnectionStrings__Default=${DB_CONNECTION} + + # Shared database for consistent state + database: + image: mcr.microsoft.com/mssql/server:2022-latest + environment: + - ACCEPT_EULA=Y + - SA_PASSWORD=YourStrong!Passw0rd +``` + +### 2. Define Comparison Test Cases + +Identify all testable behaviors: + +| Category | Test Inputs | Comparison Points | +|----------|-------------|-------------------| +| API responses | Same HTTP requests | Status code, response body, headers | +| Data operations | Same CRUD operations | Database state, return values | +| Business logic | Same input parameters | Calculation results, decisions | +| Error handling | Invalid inputs | Error codes, messages | +| Edge cases | Boundary values | Behavior consistency | + +### 3. Create Comparison Test Framework + +```csharp +public class BehaviorComparisonTests +{ + private readonly HttpClient _originalClient; + private readonly HttpClient _migratedClient; + + public BehaviorComparisonTests() + { + _originalClient = new HttpClient { BaseAddress = new Uri("http://localhost:8080") }; + _migratedClient = new HttpClient { BaseAddress = new Uri("http://localhost:8081") }; + } + + [Theory] + [MemberData(nameof(GetTestCases))] + public async Task ResponsesMatch(TestCase testCase) + { + // Execute same request against both + var originalResponse = await ExecuteRequest(_originalClient, testCase); + var migratedResponse = await ExecuteRequest(_migratedClient, testCase); + + // Compare responses + var comparison = CompareResponses(originalResponse, migratedResponse); + + comparison.IsMatch.Should().BeTrue( + $"Mismatch in {testCase.Name}:\n{comparison.Differences}"); + } + + private ComparisonResult CompareResponses(Response original, Response migrated) + { + var differences = new List<string>(); + + // Compare status codes + if (original.StatusCode != migrated.StatusCode) + differences.Add($"Status: {original.StatusCode} vs {migrated.StatusCode}"); + + // Compare response bodies (with normalization) + var normalizedOriginal = NormalizeResponse(original.Body); + var normalizedMigrated = NormalizeResponse(migrated.Body); + + if (!JsonEquals(normalizedOriginal, normalizedMigrated)) + differences.Add($"Body differs:\nOriginal: {normalizedOriginal}\nMigrated: {normalizedMigrated}"); + + return new ComparisonResult + { + IsMatch = differences.Count == 0, + Differences = string.Join("\n", differences) + }; + } + + private string NormalizeResponse(string json) + { + // Remove fields that are expected to differ + var obj = JsonSerializer.Deserialize<JsonElement>(json); + return RemoveIgnoredFields(obj, new[] { "timestamp", "requestId", "version" }); + } +} +``` + +### 4. Handle Expected Differences + +Some differences are expected and should be ignored: + +| Field Type | Example | Handling | +|-----------|---------|----------| +| Timestamps | `createdAt`, `updatedAt` | Ignore or compare format only | +| IDs | `requestId`, `correlationId` | Ignore | +| Version info | `apiVersion`, `buildNumber` | Ignore | +| Order | Array element order | Sort before compare | +| Precision | Float/decimal precision | Round to acceptable precision | + +```csharp +public class ResponseNormalizer +{ + private readonly HashSet<string> _ignoredFields = new() + { + "timestamp", "createdAt", "updatedAt", + "requestId", "correlationId", "traceId", + "version", "buildNumber" + }; + + public JsonElement Normalize(JsonElement element) + { + // Remove ignored fields + // Sort arrays + // Normalize number precision + // etc. + } +} +``` + +### 5. Generate Comparison Report + +```markdown +# Behavioral Comparison Report + +## Summary +- Total test cases: 150 +- Matching: 147 (98%) +- Differences: 3 (2%) + +## Differences Found + +### Case: GET /api/orders/123 +| Field | Original | Migrated | +|-------|----------|----------| +| `items[0].price` | 19.99 | 19.990000 | + +**Analysis:** Floating point precision difference, acceptable. + +### Case: POST /api/users (duplicate email) +| Aspect | Original | Migrated | +|--------|----------|----------| +| Status | 400 | 409 | +| Message | "Email exists" | "Duplicate email" | + +**Analysis:** Different but semantically equivalent error handling. + +## Recommendations +1. Accept precision differences as expected +2. Review error message changes with stakeholders +3. All critical business logic matches ✓ +``` + +### 6. Run Comparison Suite + +```bash +# Start both applications +docker-compose up -d + +# Wait for both to be healthy +./wait-for-healthy.sh http://localhost:8080/health +./wait-for-healthy.sh http://localhost:8081/health + +# Run Layer 4 comparison tests only (filter by Layer4 tag) +dotnet test --filter Category=Layer4 + +# Generate report +dotnet test --logger "html;LogFileName=comparison-report.html" + +# Cleanup +docker-compose down +``` + +## Handling Database State + +For stateful comparisons, ensure both applications start with identical data: + +```bash +# Reset database before each test +docker-compose exec database /opt/mssql-tools/bin/sqlcmd \ + -S localhost -U sa -P 'YourStrong!Passw0rd' \ + -i /scripts/reset-test-data.sql +``` + +## Pass Criteria + +- All API responses match (after normalization) +- Database state changes are identical +- Business logic produces same results +- Error handling is semantically equivalent +- Performance is comparable (within 20% variance) +- No regressions in functionality +- Runner scripts generated per the Standardized Runner Scripts convention in the main skill file diff --git a/.github/skills/playbook-create/SKILL.md b/.github/skills/playbook-create/SKILL.md new file mode 100644 index 000000000..43f664b38 --- /dev/null +++ b/.github/skills/playbook-create/SKILL.md @@ -0,0 +1,87 @@ +--- +name: playbook-create +description: Generate or update modernization playbook from document sources. Use this skill when the user wants to create a playbook, sync playbook from a document or GitHub issue, extract migration policies from architecture docs, or update existing playbook files with new decisions. +--- + +# Playbook Create + +Analyze source documents and generate a modernization playbook — three markdown files that capture an organization's modernization strategy, approved migration targets, and enforceable policies (standards + guardrails). + +## User Input + +- **output-path** (Required): The folder to save the playbook files. +- **source-file-path** (Optional): Path to the source file or directory containing the document content + +## Output Structure + +``` +${output-path}/ +├── charter.md # Scope, modernization strategy (6R), and principles +├── targets.md # Approved target technologies, library mappings, and target artifacts +└── policies.md # Standards + guardrails: naming, security, compliance, prohibited/required tech, validation gates +``` + +## Principles + +- **Source Fidelity**: The playbook is loaded and enforced by automated agents at runtime — a fabricated policy causes wrong migration decisions. Only include content explicitly present in the source document or user prompt. If a category isn't mentioned, omit that section entirely rather than adding placeholders. +- **Incremental Merge**: When output files already exist, merge at the **section level** — update sections with new or changed content, preserve unchanged sections verbatim. If the source explicitly removes or contradicts an existing entry, update that entry. Never drop existing content simply because the source is silent on it. +- **Direct Policy Output**: State policies as-is. Do not include rationale, explanations, or implementation guidance — those belong elsewhere (skills). + +## Classification Principles + +Each file serves a distinct purpose and is consumed at different stages of the modernization workflow: + +- **charter.md** — Playbook metadata (name, version), scope (covered applications, languages, constraints), modernization strategy (6R decision table with override conditions), and guiding principles. Loaded during assessment and plan creation to determine what to modernize and what strategy to apply. +- **targets.md** — Approved framework versions, compute/data/integration services, source-to-target library mappings, and target artifacts (container base images). Loaded during assessment (to define target services to assess against) and plan creation (to determine what tasks to generate). +- **policies.md** — Naming & metadata standards, security requirements, compliance requirements, guardrails (prohibited technologies/patterns, required elements, region constraints), validation & quality gates, and coding style guidelines. Loaded during assessment, plan creation, and execution to enforce standards and guardrails. + +## Workflow + +### Step 1: Read and Analyze Source + +1. If ${source-file-path} is provided, read the content (may be a GitHub issue export, markdown file, or a directory of files — if a directory, read all files recursively) +2. Check if output files already exist in ${output-path} — read them for merge comparison +3. Classify each decision from the source (and/or the user prompt) into one of the three output files using the Classification Guide above + +If no source file is provided, work with the user prompt and any existing playbook files only. + +### Step 2: Generate Playbook Files + +For each file, use the corresponding template as the structural reference, then fill in content extracted from the source. +Only include sections/subsections that have meaningful, source-backed content. Do not emit empty headings, empty tables, or placeholder-only sections. + +#### charter.md + +Use the template [charter-template](charter-template.md) as a section catalog: +- Metadata, Scope, Modernization Strategy (6R Guidelines), Principles + +#### targets.md + +Use the template [targets-template](targets-template.md) as a section catalog: +- Target Frameworks, Target Compute Services, Target Data Services, Target Integration Services, Target Libraries, Target Artifacts + +#### policies.md + +Use the template [policies-template](policies-template.md) as a section catalog: +- Naming & Metadata Standards, Security Requirements, Compliance Requirements, Guardrails (Hard Boundaries), Validation & Quality Gates, Coding Style Guidelines + +For each file: if it already exists, merge new content; if not, create it fresh. + +### Step 3: Validate + +Verify the output before finishing: +- [ ] All three files exist in ${output-path} +- [ ] Each file includes only sections with meaningful content from the source +- [ ] No empty headings, empty tables, or placeholder-only sections remain +- [ ] Every decision in the source document is reflected in at least one output file +- [ ] No content was invented beyond what the source provides + +### Step 4: Present Summary + +Report to the user: +- Number of target technologies defined +- Number of library migration mappings captured +- Number of prohibited technologies/patterns +- Number of required elements +- Number of validation/quality gates +- Sections omitted due to missing source content — flag these as gaps for architect review diff --git a/.github/skills/playbook-create/charter-template.md b/.github/skills/playbook-create/charter-template.md new file mode 100644 index 000000000..646e8a30c --- /dev/null +++ b/.github/skills/playbook-create/charter-template.md @@ -0,0 +1,30 @@ +# Charter + +## Metadata + +| Field | Value | +|-------|-------| +| Playbook Name | | +| Version | | +| Changelog | | + +## Scope + +### Covered Applications and Languages + +### Application Types + +**Included:** + +**Excluded:** + +### Custom Libraries + +### Constraints + +## Modernization Strategy (6R Guidelines) + +| Application Type | Default Strategy | Override Conditions | +|------------------|-----------------|---------------------| + +## Principles diff --git a/.github/skills/playbook-create/policies-template.md b/.github/skills/playbook-create/policies-template.md new file mode 100644 index 000000000..04e844e48 --- /dev/null +++ b/.github/skills/playbook-create/policies-template.md @@ -0,0 +1,72 @@ +# Policies + +## Naming & Metadata Standards + +### Resource Naming Patterns + +| Resource Type | Pattern | Example | +|--------------|---------|---------| + +### Tagging Requirements + +| Tag | Required | Description | +|-----|----------|-------------| + +## Security Requirements + +### Authentication & Authorization + +### Secrets Management + +### Network Security + +### Encryption + +## Compliance Requirements + +### Applicable Frameworks + +| Framework | Key Constraints | +|-----------|----------------| + +### Data Classification + +## Guardrails (Hard Boundaries) + +### Prohibited Technologies + +| Technology | Reason | Approved Alternative | +|-----------|--------|---------------------| + +### Prohibited Patterns + +| Pattern | Reason | Approved Alternative | +|---------|--------|---------------------| + +### Required Elements + +Every modernized application must include: + +#### Cloud Resources + +#### Monitoring + +#### CI/CD + +#### Testing + +### Approved Regions / Residency Constraints + +## Validation & Quality Gates + +### Required Scanners/Tools + +### Pipeline Gates + +### Confidence Thresholds + +## Coding Style Guidelines + +### Coding Standards + +### Frontend Style Guidelines diff --git a/.github/skills/playbook-create/targets-template.md b/.github/skills/playbook-create/targets-template.md new file mode 100644 index 000000000..05334f689 --- /dev/null +++ b/.github/skills/playbook-create/targets-template.md @@ -0,0 +1,31 @@ +# Targets + +## Target Frameworks + +| Language | Target Version | Notes | +|----------|---------------|-------| + +## Target Compute Services + +| Platform | Use When | +|----------|----------| + +## Target Data Services + +| Service | Use When | +|---------|----------| + +## Target Integration Services + +| Service | Use When | +|---------|----------| + +## Target Libraries + +| Source | Target | Notes | +|--------|--------|-------| + +## Target Artifacts + +| Artifact | Location | Notes | +|----------|----------|-------| diff --git a/.github/skills/rearchitect/SKILL.md b/.github/skills/rearchitect/SKILL.md new file mode 100644 index 000000000..7a94508ec --- /dev/null +++ b/.github/skills/rearchitect/SKILL.md @@ -0,0 +1,126 @@ +--- +name: rearchitect +description: Scan project for Apache Struts and WinForms usage, report findings with modern alternatives +--- + +# Rearchitect — Legacy Framework Detection + +Scan the current project to detect outdated or unmaintained frameworks/technology stacks, report findings, and suggest modern alternatives. Save results via the `write_assessment_result` tool. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Execution Steps + +### Step 1: Determine Project Type + +Identify the project's technology stack by looking for marker files: + +| Marker File | Project Type | +|-------------|-------------| +| `pom.xml`, `build.gradle`, `build.gradle.kts` | Java/JVM | +| `*.csproj`, `*.sln`, `*.slnx` | .NET | +| `web.xml` | Java Web (Servlet) | + +### Step 2: Run Detection + +**Only** check the two targets listed below. Do **not** scan for or report any other frameworks, libraries, or dependencies beyond these two targets. + +--- + +#### Required Targets + +##### 1. Apache Struts + +**Configuration file detection:** +- `pom.xml` / `build.gradle` / `build.gradle.kts`: search for `org.apache.struts`, `struts2-core`, `struts-core`, `struts-taglib` +- `web.xml`: search for `org.apache.struts`, `StrutsPrepareAndExecuteFilter`, `ActionServlet` + +**Source code detection:** +- Java files: search for `import org.apache.struts`, `import com.opensymphony.xwork2` +- JSP files: search for `<%@ taglib.*struts`, `<s:` (Struts 2 tags) + +**Alternatives:** Spring Boot + Spring MVC, or Quarkus / Micronaut + +**Fixed explanation (use verbatim when detected):** +> Apache Struts has reached end-of-life and no longer receives security patches or bug fixes. It has a history of critical remote code execution vulnerabilities (e.g., CVE-2017-5638, CVE-2023-50164) that made it one of the most exploited frameworks in the Java ecosystem. Continued use exposes the application to known, unpatched attack vectors. Migration to a modern, actively maintained framework such as Spring Boot is strongly recommended to ensure ongoing security support and access to current Java platform features. + +##### 2. WinForms (Windows Forms) + +**Configuration file detection:** +- `.csproj`: search for `<UseWindowsForms>true</UseWindowsForms>`, `System.Windows.Forms`, `<OutputType>WinExe</OutputType>` (combined with WindowsForms references) + +**Source code detection:** +- C# files: search for `using System.Windows.Forms`, `: Form`, `: UserControl` (in System.Windows.Forms context) +- Presence of `.Designer.cs` files + +**Alternatives:** WPF, MAUI, Avalonia UI, or Blazor Desktop + +**Fixed explanation (use verbatim when detected):** +> Windows Forms (WinForms) is a legacy UI framework tied exclusively to Windows and .NET Framework. While it still receives minimal maintenance in .NET 8+, it lacks modern UI capabilities such as responsive layouts, high-DPI scaling, hardware-accelerated rendering, and cross-platform support. Its designer-centric, event-driven programming model makes it difficult to adopt modern patterns like MVVM or data binding. Migrating to WPF is recommended for richer user experiences, better maintainability, and modern UI patterns. + +--- + +### Step 3: Save Output + +Call the `write_assessment_result` tool with the following parameters: +- `resultJson`: the detection results as a JSON string +- `assessmentDir`: the value of the `assessment_dir` variable + +The JSON must strictly follow this format: + +```json +{ + "outdatedFrameworks": [ + { + "name": "Apache Struts 2", + "old": "struts2", + "new": "spring-boot", + "status": "end-of-life", + "detectedVersion": "2.5.30", + "migrationComplexity": "high", + "detectedIn": { + "configFiles": ["path/to/pom.xml"], + "sourceFiles": ["path/to/Action.java", "path/to/Login.jsp"] + }, + "alternatives": [ + "Spring Boot + Spring MVC", + "Quarkus", + "Micronaut" + ], + "explanation": "Apache Struts has reached end-of-life and no longer receives security patches or bug fixes. It has a history of critical remote code execution vulnerabilities (e.g., CVE-2017-5638, CVE-2023-50164) that made it one of the most exploited frameworks in the Java ecosystem. Continued use exposes the application to known, unpatched attack vectors. Migration to a modern, actively maintained framework such as Spring Boot is strongly recommended to ensure ongoing security support and access to current Java platform features." + } + ] +} +``` + +**JSON field descriptions:** +- `name`: Full framework name (with version distinction, e.g. "Apache Struts 1" vs "Apache Struts 2") +- `old`: Short identifier of the legacy framework (e.g. `struts2`, `winforms`) +- `new`: Short identifier of the recommended primary alternative (e.g. `spring-boot`, `maui`, `blazor`) +- `status`: `"end-of-life"` | `"deprecated"` | `"unmaintained"` | `"security-vulnerability"` | `"critical-bug"` | `"runtime-incompatible"` +- `detectedVersion`: Version string detected from config files, or `null` if not determinable +- `migrationComplexity`: `"high"` | `"medium"` | `"low"` +- `detectedIn.configFiles`: List of config file paths where references were detected +- `detectedIn.sourceFiles`: List of source file paths where references were detected +- `alternatives`: List of all recommended alternative frameworks +- `explanation`: Fixed explanation text for why this framework needs to be upgraded — use the exact text specified in each target's "Fixed explanation" section above + +If no outdated frameworks are detected, pass `{"outdatedFrameworks": []}` to the tool. + +**The JSON passed to the tool must contain ONLY the JSON object described above. No other text or formatting.** + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No build files found**: Output: `> ERROR: No recognized build files found at {workspace-path}. Verify the path is correct.` +- **Insufficient info**: Generate a best-effort report from available data. Set `detectedVersion` to `null` for dependencies where the version cannot be determined. + +## Success Criteria + +- All detection targets are checked against both configuration files and source code +- No frameworks or dependencies beyond Apache Struts and WinForms are reported +- JSON is valid and follows the specified schema exactly +- Only high-confidence findings are reported — no guesses or uncertain cases +- Result saved via `write_assessment_result` tool diff --git a/.github/skills/reconcile-tasks-with-plan/SKILL.md b/.github/skills/reconcile-tasks-with-plan/SKILL.md new file mode 100644 index 000000000..c63c67210 --- /dev/null +++ b/.github/skills/reconcile-tasks-with-plan/SKILL.md @@ -0,0 +1,46 @@ +--- +name: reconcile-tasks-with-plan +description: Update tasks.json to match the current plan.md content without modifying plan.md +--- + +# Reconcile tasks.json with plan.md + +This skill synchronizes tasks.json with plan.md when the plan has been manually updated. +It reads the current plan.md and tasks.json, detects differences, and rewrites tasks.json +to reflect the plan. **Do NOT modify plan.md** — it is the source of truth for task intent. + +## User Input + +- modernization-work-folder (Mandatory): The folder containing plan.md and .metadata/tasks.json +- language (Mandatory): The programming language of the project (java or dotnet) + +## Workflow + +1. **Read current state**: Read the following files from `${modernization-work-folder}`: + - `plan.md` — the authoritative modernization plan (source of truth for task intent) + - `.metadata/tasks.json` — the current structured task list (source of truth for execution state) + +2. **Detect inconsistencies**: Compare plan.md against the tasks defined in .metadata/tasks.json. Look for: + - Tasks described in plan.md that are missing from tasks.json + - Tasks in tasks.json that are no longer mentioned in plan.md + - Changes in task descriptions, requirements, scope, or ordering between the two files + +3. **Update tasks.json**: If inconsistencies are found, rewrite .metadata/tasks.json to match plan.md: + - Refer to the json schema tasks-schema.json for the correct task structure + - Add new tasks that appear in plan.md but are missing from tasks.json + - Remove tasks that are no longer described in plan.md + - Update descriptions, requirements, or ordering to match plan.md + - **Preserve task IDs**: For tasks that clearly map to existing entries, keep the same task ID + - **Preserve execution state**: Do NOT reset tasks that already have a `status` of "success", "failed", or "skipped". Keep their `status`, `taskSummary`, and `successCriteriaStatus` unchanged + - **Preserve metadata**: Keep the `metadata` block unchanged (same `planName`, `createdAt`, etc.) + - Follow the same task breakdown rules and schema conventions as `create-modernization-plan` + - Consult `java-upgrade-guideline.md` or `dotnet-upgrade-guideline.md` as applicable for upgrade tasks + +4. **Skip if consistent**: If no meaningful inconsistencies are found between plan.md and tasks.json, do not write any files. Simply respond that no changes were needed. + +## Important Notes + +- **Never modify plan.md** — it is the user's manually edited source of truth +- Only modify tasks that are genuinely affected by changes in plan.md +- Each task must remain independently testable +- Do not change task types unless the plan.md clearly indicates a different type diff --git a/.github/skills/repository-dependency-graph/SKILL.md b/.github/skills/repository-dependency-graph/SKILL.md new file mode 100644 index 000000000..76b1e1dd4 --- /dev/null +++ b/.github/skills/repository-dependency-graph/SKILL.md @@ -0,0 +1,250 @@ +--- +name: repository-dependency-graph +description: Analyze the service topology of a multi-repository application. Given an application name and repository paths, identifies each independently deployable service, infers each service's role and language, detects inter-service dependencies, and produces a topology graph (Markdown). +--- + +# Repository Dependency Graph + +<!-- ff:ai_analysis:start --> + +Analyze the service topology of the application identified by the `name` parameter. For each +repository in `entries`, identify the independently deployable services it contains, infer their +roles and languages, and detect inter-service dependencies. Produce a topology graph in Markdown +format and save it to `{report-dir}/application-topology-graph.md`. + +## Input Parameters + +- `name` (required): The short, human-readable display name for the application. Used as the + report heading and in the service table. +- `entries` (required, list): One or more repository entries belonging to this application. Each + entry is an object with: + - `repoName` (required): The canonical display name for the repository (e.g. `order-service`). + Used in the topology graph, service table, and as the basis for slug generation. Takes + precedence over the directory name for all naming and dependency-matching purposes. + - `path` (required): The local filesystem path to the repository root. + + At least one entry must have an accessible `path`. +- `report-dir` (required): The directory where the output file is written. The directory is + created and managed by the CLI runner; the skill must not modify its path or structure. + +**Output filename**: `{report-dir}/application-topology-graph.md` + +## Execution Steps + +### Step 1: Validate Inputs + +1. Verify `name` is non-empty. If empty, abort with: + `> ERROR: The 'name' parameter is required and must not be empty.` +2. For each entry in `entries`, verify both `repoName` and `path` are present and non-empty. If + either is missing, abort with: + `> ERROR: Each entry in 'entries' must have both 'repoName' and 'path' fields.` +3. For each entry in `entries`, check whether `path` is accessible (exists and is readable). + - Collect accessible entries into a working set. + - Collect inaccessible entries into an `inaccessible` list for reporting. +4. If the working set is empty (all paths are inaccessible), abort with: + `> ERROR: Topology analysis skipped for '{name}': none of the provided repository paths could be accessed.` +5. If `report-dir` does not exist or is not writable, abort with: + `> ERROR: Output directory '{report-dir}' does not exist or is not writable.` + +### Step 2: Per-Repository Service Identification + +For each accessible entry in `entries`, identify independently deployable services using `entry.path` +as the filesystem root. Use `entry.repoName` as the canonical repository name — it replaces +directory-name inference for display labels, slug generation, and cross-repository dependency +matching. + +**Build file detection** (determines language, framework, and service candidates): + +| Build file | Language | Framework hints | +|------------|----------|-----------------| +| `pom.xml` | java | Check `<parent>` for `spring-boot-starter-parent` → Spring Boot; `quarkus-bom` → Quarkus; `micronaut-parent` → Micronaut | +| `build.gradle` / `build.gradle.kts` | java | Check `plugins {}` for `org.springframework.boot`, `io.quarkus`, `io.micronaut.application` | +| `*.csproj` | dotnet | Check `<TargetFramework>` and packages for `Microsoft.AspNetCore.*` → ASP.NET Core; `Microsoft.Azure.Functions.Worker` → Azure Functions | +| `*.sln` / `*.slnx` | dotnet | Multi-project solution; recurse into sub-projects | +| `package.json` (with `"start"` script or `"main"` field) | javascript/typescript | Check `"dependencies"` for `express`, `fastify`, `koa`, `@nestjs/core`, `next`, `react`, `vue`, `@angular/core` | +| `tsconfig.json` (without `package.json`) | typescript | Infer TypeScript library | + +**Service identity** (one candidate per independently deployable unit): + +- For single-service repos: use `entry.repoName` as the service name. +- For monorepos: use `entry.repoName` as the repository label; detect multiple deployable units by looking for: + - Multiple `Dockerfile` files at different subdirectory levels (each names a service) + - Multiple `*.csproj` files with `<OutputType>Exe</OutputType>` or `<OutputType>exe</OutputType>` + - Multiple `pom.xml` files in subdirectories (each with its own `<artifactId>`) + - Multiple `package.json` files with a `"start"` or `"main"` script at subdirectory level + - Each detected unit becomes a separate Service entry; `subPath` is set to its relative path within the repo. + +**ServiceRole inference rules** (apply in order; first match wins): + +| Role | Evidence | +|------|----------| +| `ApiGateway` | Name or directory contains `gateway`, `proxy`, `edge`, `ingress`; OR Spring Cloud Gateway / Netflix Zuul dependency detected | +| `Frontend` | Framework is React, Angular, Vue, Blazor, Next.js, Nuxt; OR name contains `ui`, `web`, `frontend`, `portal`, `dashboard` | +| `Worker` | No inbound HTTP port exposed in Dockerfile; OR name contains `worker`, `consumer`, `processor`, `job`, `scheduler`, `daemon`; OR Spring Batch / Azure WebJobs / Hangfire dependency detected | +| `DataService` | Name contains `db`, `data`, `repository`, `store`, `cache`; OR heavy ORM usage (Spring Data JPA, EF Core DbContext is >50% of dependencies) | +| `SharedLibrary` | No `Dockerfile` and no executable entry point; name contains `lib`, `shared`, `common`, `sdk`, `client` | +| `WebApi` | HTTP framework detected (Spring MVC, ASP.NET Core controllers, Express, NestJS, FastAPI) and none of the above matched | +| `Unknown` | None of the above rules matched | + +**Service ID**: Lowercase slug of service name (replace spaces, dots, underscores with hyphens; remove non-alphanumeric except hyphens). Must be unique within the application. + +### Step 3: Cross-Repository Dependency Detection + +For each service, scan the following configuration and build files for references to other service names/identifiers discovered in Step 2: + +**Files to scan**: +- `application.properties`, `application.yml`, `application.yaml` (Spring Boot) +- `appsettings.json`, `appsettings.*.json` (ASP.NET Core) +- `*.env`, `.env`, `.env.*` +- `docker-compose.yml`, `docker-compose.yaml`, `docker-compose.*.yml` +- Helm chart `values.yaml`, `values.*.yaml` +- Kubernetes manifests (`*.yaml` in `k8s/`, `kubernetes/`, `deploy/`, `manifests/` directories) +- `pom.xml` (Maven dependencies — detect another service's `artifactId` as a dependency) +- `*.csproj` (NuGet `<PackageReference>` — detect another service's project/package name) +- `package.json` (`dependencies` / `devDependencies` — detect another service's package name) + +**What to look for**: + +| DependencyType | Evidence | +|----------------|----------| +| `HttpCall` | Property value matching a pattern like `http(s)://{service-name}`, `{service-name}.default.svc`, `{service-name}:PORT`, or an environment variable named `{SERVICE_NAME}_URL` / `{SERVICE_NAME}_HOST` / `{SERVICE_NAME}_BASE_URL` | +| `MessageQueue` | Property key or value containing a topic/queue name that also appears in another service's config (e.g., `spring.kafka.topic`, `rabbitmq.queue`, `azure.servicebus.topic`) | +| `SharedLibrary` | Build file dependency whose artifact/package name matches another service's slug or name (common for `SharedLibrary`-role services) | +| `DirectReference` | `depends_on:` in docker-compose; Kubernetes service reference; direct project reference in `.sln` / `*.csproj` | + +For each detected dependency, record: +- `targetServiceId` (the other service's slug) +- `dependencyType` (from the table above) +- `evidence` (the config file path and key/value that triggered the match, e.g., `appsettings.json: ServiceUrls:OrderService = http://order-service`) + +Only record dependencies where **both** the source service and the target service are within the analyzed set. Do not record dependencies on external services (databases, cloud services, etc.) — those are covered by the `dependency-map` skill. + +### Step 4: Cycle Detection + +Perform a depth-first search (DFS) on the directed dependency graph. + +- Maintain a visited set and a recursion stack. +- When a back edge is detected (a node already in the recursion stack is encountered again), record the cycle as a warning string: + `"Circular dependency detected: {ServiceA} → {ServiceB} → ... → {ServiceA}"` +- Continue DFS after recording the cycle (do not abort). +- Collect all cycle warning strings into `cycleWarnings`. + +### Step 5: Duplicate Service Detection + +For each pair of services, check: +1. Are their slugified names identical? (e.g., `order-service` and `order-service`) +2. Do their names differ only by separator or case after normalization? (e.g., `orderservice` == `order_service` == `OrderService`) +3. Do their primary entry-point artifact names match? (e.g., same Maven `<artifactId>`, same .NET assembly name) + +If any condition is true, add to that service's `warnings` list: +`"WARNING: Potential duplicate of '{other-service-name}' (from {other-repo-name} at {other-repo-path}). Verify these are not the same service."` + +### Step 6: Generate Mermaid Diagram + +Build a `flowchart TD` diagram. + +**Node format**: `{ServiceId}["{ServiceName}\n({Role})"]` +- Example: `orderSvc["order-service\n(WebApi)"]` + +**Edge format** (normal dependency): +`{SourceId} -->|"{DependencyType}"| {TargetId}` +- Example: `apiGateway -->|"HttpCall"| orderSvc` + +**Cycle edge format**: +`{SourceId} -.->|"⚠ cycle"| {TargetId}` + +**Node label rules**: +- Use plain text only; avoid `@`, `#`, `$`, `%`, `&`, `<`, `>`, `"` inside node labels +- Replace double quotes in names with single quotes before embedding in labels +- All node IDs must be unique across the diagram + +**Scale limit (40-node rule)**: +- If total service count ≤ 40: show all services individually. +- If total service count > 40: collapse per-repository into aggregate nodes: + - `{repoSlug}Grp["{repoName}\n({N} services)"]` where `{repoSlug}` is the slug of `entry.repoName` + - Show only cross-repository edges between aggregate nodes. + - Add a note at the top of the diagram section: `> Note: {N} services exceed the 40-node display limit. Services are grouped by repository.` + +### Step 7: Render Output + +Produce the final output content: + +**Markdown format** : + +``` +# Topology Graph: {name} + +Analyzed {N} service(s) across {M} repositor(y/ies) for application "{name}" on {YYYY-MM-DD HH:MM UTC}. + +## Services + +```mermaid +{mermaid diagram content} +``` + +## Service Details + +| Service | Role | Language | Source Repository | Warnings | +|---------|------|----------|------------------|----------| +| {service-name} | {Role} | {language} | {repoName} | {warnings or —} | +... + +## Warnings + +- {cycle warning 1} +- {cycle warning 2} +- {duplicate warning} +- Inaccessible repository: {repoName} ({path}) (skipped) +``` +(Omit `## Warnings` section entirely when no warnings exist.) + +### Step 8: Save Output + +1. Compute the output filename: + - Full path: `{report-dir}/application-topology-graph.md` +2. Write the rendered content to the output file (create or overwrite). +3. Log: `Topology graph for '{name}' saved to {output-path}` + +## Scaling Rules + +- Maximum 40 Mermaid nodes for GitHub rendering compatibility and diagram legibility. +- When service count > 40: collapse to per-repository aggregate nodes (Step 6 scale limit rule). +- Performance expectation: analysis of 3–10 repositories should complete in under 5 minutes on a + standard developer workstation. +- For very large monorepos (>20 sub-projects), limit per-repo service detection to a maximum of + 10 services; add a note in the Warnings section: `Note: Repository '{repo}' contains more than + 10 detected services; only the first 10 are shown.` + +## Mermaid Syntax Rules + +- Use `flowchart TD` (top-down layout). +- Avoid special characters in node labels: `@`, `#`, `$`, `%`, `&`, `<`, `>`. +- Always quote arrow labels with double quotes: `-->|"label"|`. +- Use `-.->` (dotted arrow) for cycle edges with label `"⚠ cycle"`. +- All node IDs must be unique across the entire diagram. +- Do not use `subgraph` — flat node layout only (services are already grouped logically by role + via node labels). + +## Error Handling + +| Condition | Behavior | +|-----------|----------| +| All `entries` inaccessible | Abort with error message (Step 1). No output file written. | +| Subset of paths inaccessible | Continue with accessible subset. Add each inaccessible entry as `Inaccessible repository: {repoName} ({path}) (skipped)` in Warnings section. | +| Missing `repoName` or `path` field | Abort with error message (Step 1). No output file written. | +| No build files found in any repository | Best-effort: list each repo as a service with `role: Unknown` and `language: unknown`. Add note in Warnings: `Note: No recognized build files were found. Service roles could not be inferred.` | +| Unsupported project type | Set `language: unknown` and `role: Unknown` for that service. Do not fail. | +| Service name collision (duplicate IDs after slugification) | Append the `repoName` as a suffix: `{slug}-{repo-name-slug}`. | +| Output file write error | Log error: `Failed to write topology graph for '{name}' to {report-dir}/application-topology-graph.md: {error}`. Do not abort the parent process. | + +## Success Criteria + +- Output file `{report-dir}/application-topology-graph.md` is created and non-empty. +- File contains at least one service node in the Mermaid diagram. +- All inaccessible repository paths are listed in the Warnings section (none silently ignored). +- The Mermaid diagram contains no syntax errors (valid `flowchart TD` syntax). +- The Service Details table has one row per detected service. +- The Warnings section is present only when at least one warning exists. +- No unhandled exceptions propagate to the assessment pipeline. + +<!-- ff:ai_analysis:end --> diff --git a/.github/skills/security-assessment-merge/SKILL.md b/.github/skills/security-assessment-merge/SKILL.md new file mode 100644 index 000000000..da58db577 --- /dev/null +++ b/.github/skills/security-assessment-merge/SKILL.md @@ -0,0 +1,318 @@ +--- +name: security-assessment-merge +description: Merge CVE and CWE security assessment results into a unified security report and update report.json +--- + +# Security Assessment: Merge and Report + +## Role + +You are a **security assessment aggregator**. Your task is to read all CVE and CWE result files produced by earlier security skills, merge them into a unified security assessment report, and inject the findings into `report.json`. + +> **Important:** You are a data aggregator, NOT an analyzer. Do NOT re-scan the codebase. Your sole responsibility is to read, normalize, merge, and write the security findings that were already produced by the CVE and CWE assessment skills. + +## Working Directory + +All security assessment input and output files are located under: + +``` +.github/modernize/assessment/engines/security/ +``` + +All file paths in this skill are relative to this directory unless otherwise noted. + +## Objective + +1. Read all security assessment result files from the `.github/modernize/assessment/engines/security/` directory +2. Normalize CVE and CWE findings into a unified format +3. Generate `security-assessment.json` (machine-readable merged report) in the same directory +4. Generate `security-assessment.md` (human-readable markdown report) in the same directory +5. Inject a `"security"` array into the existing `report.json` + +## Instructions + +### Step 1: Read CVE Results + +Read the CVE result file at `.github/modernize/assessment/engines/security/cve-assessment-result.json`. + +This file is a **flat JSON array** where each element has: +```json +{ + "id": "CVE-2024-xxxx", + "name": "Summary", + "status": "FOUND", + "category": "CVE", + "severity": "critical|high|medium|low", + "storyPoint": 1, + "evidence": { + "files": ["pom.xml:42"], + "explanation": "Markdown description..." + } +} +``` + +Only include entries where `status` is `"FOUND"`. + +**Filter by minimum CVE severity:** The minimum severity threshold is provided in the assessment prompt instructions. Only include CVE findings whose severity meets or exceeds the specified threshold. The severity order from lowest to highest is: `low` < `medium` < `high` < `critical`. Exclude findings with unknown or missing severity. If no threshold was specified in the prompt, default to `high`. + +If the file does not exist or is empty, treat CVE findings as an empty list. + +### Step 2: Read CWE Results + +Read all CWE result files matching `.github/modernize/assessment/engines/security/result-cwe-*.json`. + +Each CWE file uses a **wrapper format**: +```json +{ + "input_name": "CWE - Category Name", + "status": "success", + "result": { + "values": [ + { + "id": "CWE-79", + "name": "Cross-site Scripting", + "status": "FOUND", + "category": "Injection Attacks", + "severity": "optional", + "storyPoint": 8, + "description": "The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.", + "evidence": { + "files": ["src/Controller.java"], + "explanation": "Description..." + } + } + ] + } +} +``` + +Navigate to `result.values` in each file and extract entries where `status` is `"FOUND"`. + +If no CWE files exist, treat CWE findings as an empty list. + +### Step 3: Build the Unified Security Findings Array + +Transform all FOUND CVE and CWE items into the unified format: + +```json +{ + "id": "CVE-2024-xxxx or CWE-79", + "title": "Human-readable title", + "category": "CVE or CWE category (e.g., Injection Attacks)", + "severity": "mandatory|optional|potential", + "description": "Detailed description", + "evidence": { + "files": ["path/to/file.java"], + "explanation": "Why this was flagged" + }, + "storyPoint": 1 +} +``` + +For **CVE findings**: Map `name` → `title`, use `explanation` as both `description` and `evidence.explanation`. **Map the raw CVE severity to assessment severity levels:** +- `critical` or `high` → `mandatory` +- `medium` → `optional` +- `low` or unknown → `potential` + +For **CWE findings**: Map `name` → `title`, map `severity` → `severity` (already in assessment format), map `storyPoint` → `storyPoint`, map `description` → `description`, use `explanation` as `evidence.explanation`. + +### Step 4: Calculate Summary Statistics + +Count: +- `totalFindings`: Total number of FOUND CVE + CWE items +- `cveCount`: Number of CVE findings +- `cweCount`: Number of CWE findings +- `bySeverity`: Count of findings grouped by severity (`mandatory`, `optional`, `potential`) +- `byCategory`: Count of findings grouped by category (`CVE`, `Injection Attacks`, etc.) +- `totalRulesAssessed`: Total number of CWE checklist items across all `.github/modernize/assessment/engines/security/result-cwe-*.json` files (both FOUND and NOT_FOUND) +- `rulesPassed`: `totalRulesAssessed - cweCount` + +### Step 5: Write security-assessment.json + +Write the full merged report to `.github/modernize/assessment/engines/security/security-assessment.json`: + +```json +{ + "GeneratedAt": "2026-04-09T12:00:00.0000000Z", + "ProjectPath": ".", + "Summary": { + "TotalFindings": 5, + "CveCount": 2, + "CweCount": 3, + "BySeverity": { "mandatory": 3, "optional": 1, "potential": 1 }, + "ByCategory": { "CVE": 2, "Injection Attacks": 2, "Code Quality": 1 }, + "TotalRulesAssessed": 59, + "RulesPassed": 56 + }, + "CveFindings": [ + { + "Id": "CVE-2024-xxxx", + "Name": "Vulnerability Title", + "Category": "CVE", + "Severity": "mandatory", + "StoryPoint": 1, + "Description": "...", + "Files": ["pom.xml:42"], + "Explanation": "..." + } + ], + "CweFindings": [ + { + "Id": "CWE-79", + "Name": "Cross-site Scripting", + "Category": "Injection Attacks", + "Severity": "optional", + "StoryPoint": 8, + "Description": "...", + "Files": ["src/Controller.java"], + "Explanation": "..." + } + ] +} +``` + +### Step 6: Write security-assessment.md + +Write a human-readable markdown report to `.github/modernize/assessment/engines/security/security-assessment.md`: + +```markdown +# Security Assessment Report + +**Generated:** <timestamp> + +## Summary + +| Metric | Count | +|--------|-------| +| Total Findings | N | +| CVE Vulnerabilities | N | +| CWE Vulnerabilities | N | +| Total Rules Assessed | N | +| Rules Passed | N | + +### By Severity + +| Severity | Count | +|----------|-------| +| mandatory | N | +| optional | N | +| potential | N | + +## CVE Findings (Dependency Vulnerabilities) + +### CVE-2024-xxxx: Title +- **Severity:** mandatory +- **Story Points:** 1 +- **Files:** pom.xml:42 + +<explanation> + +## CWE Findings (Code-Level Vulnerabilities) + +### CWE-79: Cross-site Scripting +- **Category:** Injection Attacks +- **Severity:** optional +- **Story Points:** 8 +- **Files:** src/Controller.java + +<explanation> +``` + +If there are no findings at all, write: +```markdown +## No security vulnerabilities found. + +The assessment did not detect any CVE or CWE vulnerabilities in the codebase. +``` + +### Step 7: Merge into report.json + +The `report.json` file lives in a versioned report directory: + +``` +.github/modernize/assessment/reports/report-{reportId}/report.json +``` + +where `{reportId}` is a `yyyyMMddHHmmss` timestamp (e.g., `20260410120000`). This directory is created by the main assessment skill. + +**Step 7a: Locate report.json** + +Find the latest versioned report directory by listing directories matching the `report-*` pattern and sorting in descending order (newest first): + +```bash +REPORTS_DIR=".github/modernize/assessment/reports" +REPORT_DIR=$(ls -d "$REPORTS_DIR"/report-* 2>/dev/null | sort -r | head -n 1) + +if [ -n "$REPORT_DIR" ] && [ -f "$REPORT_DIR/report.json" ]; then + echo "Found report.json at: $REPORT_DIR/report.json" +else + echo "Warning: No versioned report directory found under $REPORTS_DIR" +fi +``` + +**Step 7b: Merge security findings into report.json** + +**Use `jq` for safe JSON manipulation** — do NOT manually rewrite report.json. + +Write the unified findings array to a temporary file, then merge: + +```bash +SECURITY_DIR=".github/modernize/assessment/engines/security" + +# Write the unified findings array +cat > "$SECURITY_DIR/unified-findings.json" << 'SECURITY_EOF' +[ + ... unified findings array from Step 3 ... +] +SECURITY_EOF + +# Merge into report.json using jq +if [ -n "$REPORT_DIR" ] && [ -f "$REPORT_DIR/report.json" ] && command -v jq &> /dev/null; then + jq --argjson sec "$(cat "$SECURITY_DIR/unified-findings.json")" '. + {"security": $sec}' "$REPORT_DIR/report.json" > "$REPORT_DIR/report.json.tmp" && mv "$REPORT_DIR/report.json.tmp" "$REPORT_DIR/report.json" +elif [ -n "$REPORT_DIR" ] && [ -f "$REPORT_DIR/report.json" ]; then + # Fallback without jq: use python + python3 -c " +import json +report_path = '$REPORT_DIR/report.json' +with open(report_path, 'r') as f: report = json.load(f) +with open('$SECURITY_DIR/unified-findings.json', 'r') as f: security = json.load(f) +report['security'] = security +with open(report_path, 'w') as f: json.dump(report, f, indent=2) +" 2>/dev/null || echo "Warning: Could not merge security into report.json (jq and python3 unavailable)" +else + echo "Warning: report.json not found — skipping merge. The standalone security-assessment.json is still valid." +fi + +# Clean up temp file +rm -f "$SECURITY_DIR/unified-findings.json" +``` + +**Step 7c: Handle missing report.json** + +If no `report-*` directory or `report.json` exists (e.g., AppCAT was not run or failed), create a minimal stub in a new versioned directory: + +```bash +if [ -z "$REPORT_DIR" ] || [ ! -f "$REPORT_DIR/report.json" ]; then + REPORT_ID=$(date -u +"%Y%m%d%H%M%S") + REPORT_DIR="$REPORTS_DIR/report-$REPORT_ID" + mkdir -p "$REPORT_DIR" + cat > "$REPORT_DIR/report.json" << STUB_EOF +{ + "metadata": { + "id": "$REPORT_ID", + "generated_at": "$(date -u +"%Y-%m-%dT%H:%M:%S.0000000Z")", + "note": "Security-only report (AppCAT was not run or failed)" + }, + "security": $(cat "$SECURITY_DIR/unified-findings.json" 2>/dev/null || echo "[]") +} +STUB_EOF + echo "Created stub report at: $REPORT_DIR/report.json" +fi +``` + +## Error Handling + +- If no security result files exist at all, write empty reports (`security-assessment.json` with zero findings, `security-assessment.md` with "No vulnerabilities found") +- If a CWE result file is malformed, skip it and continue with the rest +- If the `report.json` merge fails, log a warning but do NOT fail the overall task — the standalone `security-assessment.json` is still valid +- Always produce all three output files (`security-assessment.json`, `security-assessment.md`, and the merged `report.json`) diff --git a/.github/skills/validate-playbook-compliance/SKILL.md b/.github/skills/validate-playbook-compliance/SKILL.md new file mode 100644 index 000000000..19ae310ef --- /dev/null +++ b/.github/skills/validate-playbook-compliance/SKILL.md @@ -0,0 +1,31 @@ +--- +name: validate-playbook-compliance +description: Validate playbook compliance by mapping playbook rules to plan tasks +--- + +# Validate Playbook Compliance + +Map each playbook rule to the tasks in the modernization plan and produce a compliance summary. + +## User Input + +- tasks-json-path (Mandatory): Path to the tasks.json file +- compliance-output-path (Mandatory): Path to write the compliance markdown summary + +## Workflow + +1. Read the tasks from ${tasks-json-path} +2. Read the playbook files provided as attachments +3. For each playbook rule, determine which task (if any) addresses it +4. Write a markdown summary to ${compliance-output-path} with the following format: + +## Playbook Compliance + +| Playbook | Rule | Status | Task | +|----------|------|--------|------| +| targets.md | brief rule summary | ✅ COVERED | 001 | +| policies.md | another rule | ❌ NOT COVERED | - | + +**COVERED: X/Y · NOT COVERED: Z/Y** + +Include all rules from all playbook files. Only write the markdown file, do not modify any other files. diff --git a/.github/skills/validate-playbook-evidence/SKILL.md b/.github/skills/validate-playbook-evidence/SKILL.md new file mode 100644 index 000000000..ae4d51192 --- /dev/null +++ b/.github/skills/validate-playbook-evidence/SKILL.md @@ -0,0 +1,32 @@ +--- +name: validate-playbook-evidence +description: Analyze code changes and produce playbook compliance evidence from git diff +--- + +# Validate Playbook Evidence + +Analyze the git diff and produce playbook compliance evidence showing which rules were implemented. + +## User Input + +- baseline-commit-sha (Mandatory): The baseline commit SHA to diff from +- playbook-file-list (Mandatory): Comma-separated list of playbook file names +- evidence-output-path (Mandatory): Path to write the evidence markdown summary + +## Workflow + +1. Analyze the git diff from baseline commit ${baseline-commit-sha} to HEAD +2. The playbook files are: ${playbook-file-list} +3. Write a markdown summary to ${evidence-output-path} with the following format: + +## Playbook Code Evidence (from diff) + +### [policies.md] +**Rule: brief rule summary** +```diff ++ filepath:line added code +- filepath:line removed code +``` + +Focus on the 2-5 most impactful rules. Each diff line starts with '+' or '-' and includes file:line prefix. +Only write the markdown file, do not modify any other files. From b5c404e48a32f21474e120e51768cb6d432d9729 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 08:19:18 +0000 Subject: [PATCH 2/4] Initial plan From ce772aa938f62f9f9b6104b79fd2793ca74db905 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 08:21:40 +0000 Subject: [PATCH 3/4] feat: add AppCAT assessment report for application cloud readiness Agent-Logs-Url: https://github.com/qianwens/PhotoAlbum-Java/sessions/9ef27310-2ec5-4dfc-854c-082da2f9df87 Co-authored-by: qianwens <37290631+qianwens@users.noreply.github.com> --- .../reports/report-20260520082027/report.json | 1020 +++++++++++++++++ 1 file changed, 1020 insertions(+) create mode 100644 .github/modernize/assessment/reports/report-20260520082027/report.json diff --git a/.github/modernize/assessment/reports/report-20260520082027/report.json b/.github/modernize/assessment/reports/report-20260520082027/report.json new file mode 100644 index 000000000..d561e41de --- /dev/null +++ b/.github/modernize/assessment/reports/report-20260520082027/report.json @@ -0,0 +1,1020 @@ +{ + "version": "1.0.0", + "producer": "Java AppCAT CLI", + "metadata": { + "analysisStartTime": "2026-05-20T08:20:27.341717461Z", + "analysisEndTime": "2026-05-20T08:21:11.43246598Z", + "status": "Complete", + "privacyMode": "Protected", + "privacyModeHelpUrl": "https://aka.ms/appcat-privacy-mode", + "targetIds": [ + "azure-container-apps", + "azure-aks", + "azure-appservice" + ], + "targetDisplayNames": [ + "Azure Container Apps", + "Azure Kubernetes Service", + "Azure App Service" + ], + "capabilities": [], + "os": [] + }, + "summary": { + "totalProjects": 1, + "totalIssues": 9, + "totalIncidents": 27, + "totalEffort": 172, + "charts": { + "severity": { + "mandatory": 11, + "optional": 2, + "potential": 14, + "information": 0 + }, + "category": { + "database-migration": 6, + "framework-upgrade": 10, + "jakarta-migration": 1, + "java-version-upgrade": 3, + "local-credential": 3, + "spring-migration": 4 + } + } + }, + "projects": [ + { + "path": ".", + "issues": 9, + "storyPoints": 172, + "properties": { + "appName": "photo-album", + "jdkVersion": "1.8", + "frameworks": [ + "Spring Boot", + "Spring" + ], + "languages": [ + "Java" + ], + "tools": [ + "Maven" + ] + }, + "incidents": [ + { + "ruleId": "azure-java-version-01000", + "incidentId": "857aab55-c0bd-421a-bf45-be197345e684", + "location": "pom.xml", + "locationKind": "File", + "line": 24, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-java-version-02000", + "incidentId": "b5465bed-b056-4c98-8008-e0c33cbc4165", + "location": "pom.xml", + "locationKind": "File", + "line": 25, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "optional" + }, + "azure-appservice": { + "effort": 8, + "severity": "optional" + }, + "azure-container-apps": { + "effort": 8, + "severity": "optional" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-java-version-02000", + "incidentId": "3b2742d5-c480-4e17-8900-970c0b14e528", + "location": "pom.xml", + "locationKind": "File", + "line": 26, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "optional" + }, + "azure-appservice": { + "effort": 8, + "severity": "optional" + }, + "azure-container-apps": { + "effort": 8, + "severity": "optional" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-port-01000", + "incidentId": "d4d0c961-fed7-48b0-a840-d21785045e35", + "location": "src/main/resources/application-docker.properties", + "locationKind": "File", + "line": 24, + "column": 0, + "targets": { + "azure-aks": { + "effort": 1, + "severity": "potential" + }, + "azure-appservice": { + "effort": 1, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 1, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-port-01000", + "incidentId": "67777219-049f-42f7-ad45-5697827438dd", + "location": "src/main/resources/application.properties", + "locationKind": "File", + "line": 2, + "column": 0, + "targets": { + "azure-aks": { + "effort": 1, + "severity": "potential" + }, + "azure-appservice": { + "effort": 1, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 1, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-restricted-config-01000", + "incidentId": "7e1ebb17-e48c-4736-8cdf-7a688cd53465", + "location": "src/main/resources/application-docker.properties", + "locationKind": "File", + "line": 24, + "column": 0, + "targets": { + "azure-container-apps": { + "effort": 2, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-restricted-config-01000", + "incidentId": "67cf7064-d318-48ea-85b6-569d887a3642", + "location": "src/main/resources/application.properties", + "locationKind": "File", + "line": 2, + "column": 0, + "targets": { + "azure-container-apps": { + "effort": 2, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "2d5ea715-1361-4d66-8247-5934a6d069d5", + "location": "pom.xml", + "locationKind": "File", + "line": 34, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "b1435381-0107-4fbe-8d6c-abd3e09da564", + "location": "pom.xml", + "locationKind": "File", + "line": 78, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "24135035-25fa-4af1-9b01-9150bb5782a9", + "location": "pom.xml", + "locationKind": "File", + "line": 46, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "6bdcfee2-8597-447c-b106-dcaba29a5990", + "location": "pom.xml", + "locationKind": "File", + "line": 72, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "1ebf5043-cc28-4b15-9394-a57e556b1d77", + "location": "pom.xml", + "locationKind": "File", + "line": 40, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "e9c0c0c8-9071-45bc-8ced-58ba04a4101d", + "location": "pom.xml", + "locationKind": "File", + "line": 92, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "f6eea7d2-5ef4-4462-aa9d-f1f52fe27fa2", + "location": "pom.xml", + "locationKind": "File", + "line": 59, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "38a3aa6a-4b69-4fb1-861e-5f86adb91620", + "location": "pom.xml", + "locationKind": "File", + "line": 52, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "204b9858-ebcf-4ed3-bcea-c19b98998b39", + "location": "docker-compose.yml", + "locationKind": "File", + "line": 32, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "5422f8c9-2589-41e1-a88e-67f54fd13efc", + "location": "src/main/resources/application-docker.properties", + "locationKind": "File", + "line": 2, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "66950164-9ae0-4807-bc7f-b3323b69b05b", + "location": "src/main/resources/application.properties", + "locationKind": "File", + "line": 10, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "152dae18-71b3-455b-8e5b-f8918c3637d8", + "location": "src/main/resources/application-docker.properties", + "locationKind": "File", + "line": 5, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "aed4fc08-0cfe-44e0-9fb4-1c3ac963a9f5", + "location": "src/main/resources/application.properties", + "locationKind": "File", + "line": 13, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-password-01000", + "incidentId": "87f2aa19-3bf1-4095-8c8d-30c7a87a6d2e", + "location": "src/test/resources/application-test.properties", + "locationKind": "File", + "line": 5, + "column": 0, + "targets": { + "azure-aks": { + "effort": 3, + "severity": "potential" + }, + "azure-appservice": { + "effort": 3, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 3, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-password-01000", + "incidentId": "d89fc75c-3e09-46c3-9415-575f23931e4a", + "location": "src/main/resources/application-docker.properties", + "locationKind": "File", + "line": 4, + "column": 0, + "targets": { + "azure-aks": { + "effort": 3, + "severity": "potential" + }, + "azure-appservice": { + "effort": 3, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 3, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-password-01000", + "incidentId": "cf964b5a-ab23-44be-84e0-427641a63939", + "location": "src/main/resources/application.properties", + "locationKind": "File", + "line": 12, + "column": 0, + "targets": { + "azure-aks": { + "effort": 3, + "severity": "potential" + }, + "azure-appservice": { + "effort": 3, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 3, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-framework-version-01000", + "incidentId": "ff52f4d2-8946-4240-93fa-9d592be0107c", + "location": "pom.xml", + "locationKind": "File", + "line": 34, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-framework-version-01000", + "incidentId": "af92c962-d2dd-4c03-8389-567107f02979", + "location": "pom.xml", + "locationKind": "File", + "line": 78, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-framework-version-01000", + "incidentId": "bf5043a1-ea10-47fa-aaa1-46ceada82566", + "location": "pom.xml", + "locationKind": "File", + "line": 46, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "jakarta-database-00002", + "incidentId": "4e8a05ff-f6e3-4844-b2de-9bef313b2d87", + "location": "pom.xml", + "locationKind": "File", + "line": 46, + "column": 0, + "targets": { + "azure-aks": { + "effort": 5, + "severity": "potential" + }, + "azure-appservice": { + "effort": 5, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 5, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=cloud-readiness" + ] + } + ] + } + ], + "rules": { + "azure-database-microsoft-oracle-07000": { + "id": "azure-database-microsoft-oracle-07000", + "description": "Oracle database found. To migrate a Java application that uses an Oracle database to Azure, you can follow these recommendations:\n\n * **Migrate to Azure Database for PostgreSQL**: Azure recommends migrating Oracle databases to Azure Database for PostgreSQL Flexible Server as it provides better cost-effectiveness and performance. Create a managed PostgreSQL Flexible Server database in Azure and choose the appropriate pricing tier based on your application's requirements.\n\n * **Use migration tools**: Utilize the Azure Database Migration Service (DMS) or third-party tools to migrate your Oracle database schema and data to PostgreSQL. Consider using ora2pg or similar tools to convert Oracle-specific SQL to PostgreSQL-compatible SQL.\n\n * **Update database drivers and connection strings**: Replace Oracle JDBC drivers with PostgreSQL drivers in your Java application. Update connection strings from Oracle format (jdbc:oracle:thin:) to PostgreSQL format (jdbc:postgresql:).\n\n * **Review and convert Oracle-specific code**: Identify and convert Oracle-specific SQL functions, stored procedures, and PL/SQL code to PostgreSQL equivalents. Pay attention to data types, syntax differences, and built-in functions.\n\n * Enable **monitoring and diagnostics**: Utilize Azure Monitor to gain insights into the performance and health of your Java application and the underlying PostgreSQL database. Set up metrics, alerts, and log analytics to proactively identify and resolve issues.\n\n * Implement **security** measures: Apply security best practices to protect your Java application and the PostgreSQL database. This includes implementing authentication and authorization mechanisms with passwordless connections and leveraging Microsoft Defender for Cloud for threat detection and vulnerability assessments.\n\n * **Backup** your data: Azure Database for PostgreSQL provides automated backups by default. You can configure the retention period for backups based on your requirements. You can also enable geo-redundant backups, if needed, to enhance data durability and availability.", + "title": "Oracle database found", + "severity": "potential", + "effort": 8, + "links": [ + { + "url": "https://learn.microsoft.com/azure/postgresql", + "title": "Azure Database for PostgreSQL documentation" + }, + { + "url": "https://learn.microsoft.com/azure/postgresql/migrate/how-to-migrate-oracle-ora2pg", + "title": "Oracle to PostgreSQL migration guide" + }, + { + "url": "https://learn.microsoft.com/azure/dms", + "title": "Azure Database Migration Service documentation" + }, + { + "url": "https://learn.microsoft.com/azure/azure-monitor", + "title": "Azure Monitor documentation" + }, + { + "url": "https://learn.microsoft.com/azure/defender-for-cloud", + "title": "Microsoft Defender for Cloud" + } + ], + "labels": [ + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "source", + "domain=cloud-readiness", + "category=database-migration", + "database", + "oracle", + "os=windows", + "os=linux" + ] + }, + "azure-java-version-01000": { + "id": "azure-java-version-01000", + "description": "The application is using a Java version that has reached the end of support. It is strongly recommended to plan and execute a migration strategy to upgrade your application to a supported Java version.\nSupported Java versions receive long-term support (LTS) from the Java community, including bug fixes and updates. Migrating to a supported version provides you with a stable and well-maintained platform for your application.", + "title": "Java Version Has Reached the End of Support", + "severity": "mandatory", + "effort": 8, + "labels": [ + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "source", + "domain=java-upgrade", + "category=java-version-upgrade", + "version", + "os=windows", + "os=linux" + ] + }, + "azure-java-version-02000": { + "id": "azure-java-version-02000", + "description": "The application is not using the latest LTS Java version. It is recommended to consider upgrading to the latest LTS version to take advantage of the newest language features, performance improvements, and extended support timelines.\nUpgrading to the latest LTS version ensures your application benefits from the most recent security enhancements and a longer support lifecycle.", + "title": "Java Version is not the latest LTS", + "severity": "optional", + "effort": 8, + "labels": [ + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "source", + "domain=java-upgrade", + "category=java-version-upgrade", + "version", + "os=windows", + "os=linux" + ] + }, + "azure-password-01000": { + "id": "azure-password-01000", + "description": "Using clear passwords in property files is a security risk, as they can be easily compromised if the files are accessed by unauthorized individuals. To enhance the security of your application, it is recommended to employ secure credential management practices.\n\n * **Azure Key Vault**: Utilize Azure Key Vault to securely store and manage your application's passwords and other sensitive credentials. Azure Key Vault provides a centralized and highly secure location for storing secrets, keys, and certificates.\n\n * **Passwordless connections**: You can provide an additional layer of security and convenience for accessing resources in Azure by eliminating the need for passwords. This way you can reduce the risk of password-related vulnerabilities, such as weak passwords or password theft.", + "title": "Password found in configuration file", + "severity": "potential", + "effort": 3, + "links": [ + { + "url": "https://learn.microsoft.com/azure/key-vault", + "title": "Azure Key Vault documentation" + }, + { + "url": "https://learn.microsoft.com/azure/developer/intro/passwordless-overview", + "title": "Passwordless connections for Azure services" + }, + { + "url": "https://learn.microsoft.com/azure/developer/java/migration/migrate-spring-boot-to-azure-container-apps#inventory-configuration-sources-and-secrets", + "title": "Password found in configuration file" + }, + { + "url": "https://docs.microsoft.com/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-key-vault", + "title": "Read a secret from Azure Key Vault in a Spring Boot application" + }, + { + "url": "https://search.maven.org/artifact/com.azure.spring/azure-spring-boot-starter-keyvault-secrets", + "title": "Azure Spring Boot Starter for Azure Key Vault Secrets" + } + ], + "labels": [ + "source", + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "domain=cloud-readiness", + "category=local-credential", + "password", + "security", + "os=windows", + "os=linux" + ] + }, + "jakarta-database-00002": { + "id": "jakarta-database-00002", + "description": "The application depends on **Jakarta Persistence (JPA)** APIs (`jakarta.persistence.*` or legacy `javax.persistence.*`), which are used for object-relational mapping (ORM) and database interaction in Jakarta EE or Java EE applications.\n\nWhen migrating to Azure:\n- Ensure that the database connection, JPA provider (e.g., Hibernate, EclipseLink), and dialect are compatible with your target Azure database service.\n- Recommended database services include **Azure Database for PostgreSQL**, **Azure Database for MySQL**, or **Azure SQL Database**.\n- For containerized deployments, these JPA-based applications can run on **Azure Kubernetes Service (AKS)** or **Azure App Service for Linux/Windows**.\n- If using **Spring Data JPA**, verify that connection pool settings and environment variables are properly configured for the cloud environment.\n- Consider leveraging **Azure Key Vault** for secure storage of database credentials and connection strings.", + "title": "Detects usage of Jakarta Persistence (JPA) APIs", + "severity": "potential", + "effort": 5, + "links": [ + { + "url": "https://jakarta.ee/specifications/persistence/", + "title": "Jakarta Persistence Specification" + }, + { + "url": "https://learn.microsoft.com/en-us/azure/architecture/guide/technology-choices/data-stores-getting-started#common-database-scenarios", + "title": "Prepare to choose a data store in Azure" + } + ], + "labels": [ + "source=java", + "source=java-ee", + "target=azure-aks", + "target=azure-container-apps", + "target=azure-appservice", + "domain=cloud-readiness", + "category=jakarta-migration", + "os=windows", + "os=linux" + ] + }, + "spring-boot-to-azure-port-01000": { + "id": "spring-boot-to-azure-port-01000", + "description": "The application is setting the server port. To migrate a Java application that sets the server port to Azure Container Apps:\n\n * **Azure Container Apps allows you to expose port according to your Azure Container Apps resource configuration. For instance, a Spring Boot application listens to port of 8080 by default, but it can be set with server.port or environment variable SERVER_PORT as you need.", + "title": "Server port configuration found", + "severity": "potential", + "effort": 1, + "links": [ + { + "url": "https://learn.microsoft.com/azure/developer/java/migration/migrate-spring-boot-to-azure-container-apps#identify-any-clients-relying-on-a-non-standard-port", + "title": "Identify any clients relying on a non-standard port" + } + ], + "labels": [ + "source=springboot", + "target=azure-aks", + "target=azure-appservice", + "target=azure-container-apps", + "domain=cloud-readiness", + "category=spring-migration", + "port", + "server port", + "os=windows", + "os=linux" + ] + }, + "spring-boot-to-azure-restricted-config-01000": { + "id": "spring-boot-to-azure-restricted-config-01000", + "description": "The application uses restricted configurations for Azure Container Apps.\n These properties can be automatically injected into your application environment by Azure Container Apps to access managed Config Server and managed Eureka Server.\n Please remove them from your application, including configuration files, config server files, command line parameters, Java system attributes, and environment variables.\n\n If configured in **configuration files**: they will be ignored and overrided by Azure Container Apps.\n \n If configured in **Config Server files**, **command line parameters**, **Java system attribute**, **environment variable**: they need to be removed or you might experience conflicts and unexpected behavior.", + "title": "Restricted configurations found", + "severity": "potential", + "effort": 2, + "links": [ + { + "url": "https://learn.microsoft.com/azure/developer/java/migration/migrate-spring-cloud-to-azure-container-apps#remove-restricted-configurations", + "title": "Migrate Spring Boot applications to Azure Container Apps - Remove restricted configurations" + }, + { + "url": "https://learn.microsoft.com/azure/container-apps/java-config-server?tabs=azure-cli", + "title": "Connect to a managed Config Server for Spring in Azure Container Apps" + }, + { + "url": "https://learn.microsoft.com/azure/container-apps/java-eureka-server?tabs=azure-cli", + "title": "Connect to a managed Eureka Server for Spring in Azure Container Apps" + } + ], + "labels": [ + "target=azure-container-apps", + "source=springboot", + "domain=cloud-readiness", + "category=spring-migration", + "os=windows", + "os=linux" + ] + }, + "spring-boot-to-azure-spring-boot-version-01000": { + "id": "spring-boot-to-azure-spring-boot-version-01000", + "description": "The application is using a Spring Boot version that has reached its End of OSS Support.\nWith the officially supported new versions from Spring, you can get the best experience. Here are some steps you can take to update your application to the latest version of Spring Boot:\n\n* Choose a **supported Spring Boot version**: Check out Spring Boot Support Versions and determine the most suitable supported Spring Boot version.\n\n* **Update Spring Boot version**: Update the Spring Boot version of your application. There are automated tools like Rewrite to help you with the migration.\n\n* **Address code compatibility**: Review your application's codebase for any potential compatibility issues with the target Spring Boot version. Update deprecated APIs or features, address any language or library changes, and ensure that your code follows best practices and standards.\n\n* **Test thoroughly**: Execute a comprehensive testing process to verify the compatibility and functionality of your application with the new Spring Boot version. Perform unit tests, integration tests, and system tests to validate that all components and dependencies work as expected.", + "title": "Spring Boot Version Has Reached the End of OSS Support", + "severity": "mandatory", + "effort": 8, + "links": [ + { + "url": "https://learn.microsoft.com/azure/developer/java/migration/migrate-spring-boot-to-azure-container-apps", + "title": "Migrate Spring Boot applications to Azure Container Apps" + }, + { + "url": "https://learn.microsoft.com/azure/container-apps/java-microservice-get-started?tabs=azure-cli", + "title": "Launch your first Java microservice application with managed Java components in Azure Container Apps" + }, + { + "url": "https://spring.io/projects/spring-boot/#support", + "title": "Spring Boot Supported Versions" + }, + { + "url": "https://github.com/spring-projects/spring-boot/wiki/Supported-Versions", + "title": "Spring Boot Support Policy" + } + ], + "labels": [ + "source=springboot", + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "domain=java-upgrade", + "category=framework-upgrade", + "version", + "os=windows", + "os=linux" + ] + }, + "spring-framework-version-01000": { + "id": "spring-framework-version-01000", + "description": "Your application is using a Spring Framework version that has reached its End of OSS Support.\nUpgrading to a supported version ensures better performance, security, and compatibility with modern tools.\n 1. Pick a Supported Version: Review the Spring Framework support policy and choose an actively supported version.\n 2. Update Your Project: Change the Spring Framework version in your pom.xml or build.gradle.\n 3. Fix Compatibility Issues: Update deprecated code, replace removed features, and ensure dependencies are compatible with the new Spring Framework version.\n 4. Thoroughly Test: Run unit, integration, and end-to-end tests to make sure everything still works after the upgrade.", + "title": "Spring Framework Version Has Reached the End of OSS Support", + "severity": "mandatory", + "effort": 8, + "links": [ + { + "url": "https://spring.io/projects/spring-framework#support", + "title": "Spring Framework Supported Versions" + }, + { + "url": "https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions", + "title": "Spring Framework Support Policy" + } + ], + "labels": [ + "source=spring", + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "domain=java-upgrade", + "category=framework-upgrade", + "version", + "os=windows", + "os=linux" + ] + } + } +} \ No newline at end of file From 99f20ea302ff1ae5bc84f771ab9a74350948ae1a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 08:22:08 +0000 Subject: [PATCH 4/4] chore: cleanup context files and skill definitions post-assessment Agent-Logs-Url: https://github.com/qianwens/PhotoAlbum-Java/sessions/9ef27310-2ec5-4dfc-854c-082da2f9df87 Co-authored-by: qianwens <37290631+qianwens@users.noreply.github.com> --- .github/modernize/appcat/.gitignore | 2 + .github/modernize/appcat/appcat.log | 330 ++ .../modernize/appcat/assessment-config.yaml | 69 + .github/modernize/appcat/result/analysis.log | 3074 +++++++++++++++++ .github/modernize/appcat/result/shim.log | 0 .github/modernize/ccacontext/.ccaskills | 64 - .github/modernize/ccacontext/cleanup.sh | 45 - .github/skills/api-service-contracts/SKILL.md | 210 -- .github/skills/architecture-diagram/SKILL.md | 190 - .github/skills/assessment/SKILL.md | 173 - .github/skills/business-workflows/SKILL.md | 199 -- .../skills/configuration-inventory/SKILL.md | 205 -- .../create-dotnet-upgrade-plan/SKILL.md | 143 - .../dotnet-upgrade-guideline.md | 43 - .../tasks-schema.json | 349 -- .../upgrade-plan-template.md | 42 - .../skills/create-java-upgrade-plan/SKILL.md | 58 - .../java-upgrade-guideline.md | 44 - .../tasks-schema.json | 349 -- .../upgrade-plan-template.md | 51 - .../skills/create-modernization-plan/SKILL.md | 129 - .../dotnet-upgrade-guideline.md | 43 - .../infra-plan-template.md | 48 - .../java-upgrade-guideline.md | 44 - .../plan-template.md | 70 - .../questionnaire.md | 19 - .../security-plan-template.md | 26 - .../supported-patterns-dotnet.md | 50 - .../supported-patterns-java.md | 88 - .../tasks-schema.json | 349 -- .../skills/cve-known-vulnerabilities/SKILL.md | 201 -- .github/skills/cwe-code-quality/SKILL.md | 153 - .../cwe-concurrency-synchronization/SKILL.md | 113 - .../skills/cwe-credentials-secrets/SKILL.md | 109 - .../skills/cwe-file-path-security/SKILL.md | 109 - .github/skills/cwe-injection-attacks/SKILL.md | 137 - .github/skills/cwe-memory-safety/SKILL.md | 149 - .github/skills/data-architecture/SKILL.md | 227 -- .github/skills/dependency-map/SKILL.md | 180 - .../skills/execute-java-upgrade-task/SKILL.md | 376 -- .../execute-modernization-task/SKILL.md | 49 - .github/skills/execute-upgrade-task/SKILL.md | 23 - .github/skills/fact-application-name/SKILL.md | 112 - .github/skills/fact-application-port/SKILL.md | 96 - .github/skills/fact-application-type/SKILL.md | 133 - .../skills/fact-architecture-pattern/SKILL.md | 218 -- .github/skills/fact-base-image/SKILL.md | 102 - .../fact-communication-protocols/SKILL.md | 118 - .../fact-compliance-requirements/SKILL.md | 131 - .github/skills/fact-container-engine/SKILL.md | 108 - .../skills/fact-container-version/SKILL.md | 99 - .../skills/fact-data-classification/SKILL.md | 151 - .../fact-embedded-language-usage/SKILL.md | 277 -- .../fact-environment-variables/SKILL.md | 105 - .../fact-external-dependencies/SKILL.md | 124 - .../skills/fact-external-services/SKILL.md | 93 - .../fact-hardware-requirements/SKILL.md | 115 - .github/skills/fact-health-checks/SKILL.md | 110 - .github/skills/fact-image-layers/SKILL.md | 102 - .github/skills/fact-image-size/SKILL.md | 121 - .../fact-language-dependencies/SKILL.md | 104 - .../fact-licensing-information/SKILL.md | 119 - .../skills/fact-multi-stage-build/SKILL.md | 92 - .github/skills/fact-network-settings/SKILL.md | 90 - .github/skills/fact-operating-system/SKILL.md | 126 - .../skills/fact-orchestration-tool/SKILL.md | 96 - .github/skills/fact-profile-settings/SKILL.md | 332 -- .github/skills/fact-resource-limits/SKILL.md | 103 - .../skills/fact-runtime-environment/SKILL.md | 107 - .../fact-security-implementation/SKILL.md | 142 - .../skills/fact-service-definition/SKILL.md | 108 - .../skills/fact-servlet-container/SKILL.md | 310 -- .../fact-startup-instrumentation/SKILL.md | 371 -- .github/skills/fact-system-packages/SKILL.md | 99 - .../skills/fact-testing-framework/SKILL.md | 139 - .../skills/fact-version-information/SKILL.md | 109 - .github/skills/fact-volume-mounts/SKILL.md | 96 - .github/skills/fact-xml-configs/SKILL.md | 298 -- .github/skills/integration-tests/SKILL.md | 324 -- .../references/azure-auth-strategies.md | 189 - .../azure-servicebus-testcontainers.md | 688 ---- .../azure-storage-testcontainers.md | 276 -- .../references/layer1-local-integration.md | 358 -- .../layer2-runner-script-templates.md | 287 -- .../references/layer2-smoke-tests.md | 261 -- .../references/layer3-azure-integration.md | 194 -- .../layer4-behavioral-comparison.md | 242 -- .github/skills/playbook-create/SKILL.md | 87 - .../playbook-create/charter-template.md | 30 - .../playbook-create/policies-template.md | 72 - .../playbook-create/targets-template.md | 31 - .github/skills/rearchitect/SKILL.md | 126 - .../skills/reconcile-tasks-with-plan/SKILL.md | 46 - .../repository-dependency-graph/SKILL.md | 250 -- .../skills/security-assessment-merge/SKILL.md | 318 -- .../validate-playbook-compliance/SKILL.md | 31 - .../validate-playbook-evidence/SKILL.md | 32 - 97 files changed, 3475 insertions(+), 13855 deletions(-) create mode 100644 .github/modernize/appcat/.gitignore create mode 100644 .github/modernize/appcat/appcat.log create mode 100644 .github/modernize/appcat/assessment-config.yaml create mode 100644 .github/modernize/appcat/result/analysis.log create mode 100644 .github/modernize/appcat/result/shim.log delete mode 100644 .github/modernize/ccacontext/.ccaskills delete mode 100644 .github/modernize/ccacontext/cleanup.sh delete mode 100644 .github/skills/api-service-contracts/SKILL.md delete mode 100644 .github/skills/architecture-diagram/SKILL.md delete mode 100644 .github/skills/assessment/SKILL.md delete mode 100644 .github/skills/business-workflows/SKILL.md delete mode 100644 .github/skills/configuration-inventory/SKILL.md delete mode 100644 .github/skills/create-dotnet-upgrade-plan/SKILL.md delete mode 100644 .github/skills/create-dotnet-upgrade-plan/dotnet-upgrade-guideline.md delete mode 100644 .github/skills/create-dotnet-upgrade-plan/tasks-schema.json delete mode 100644 .github/skills/create-dotnet-upgrade-plan/upgrade-plan-template.md delete mode 100644 .github/skills/create-java-upgrade-plan/SKILL.md delete mode 100644 .github/skills/create-java-upgrade-plan/java-upgrade-guideline.md delete mode 100644 .github/skills/create-java-upgrade-plan/tasks-schema.json delete mode 100644 .github/skills/create-java-upgrade-plan/upgrade-plan-template.md delete mode 100644 .github/skills/create-modernization-plan/SKILL.md delete mode 100644 .github/skills/create-modernization-plan/dotnet-upgrade-guideline.md delete mode 100644 .github/skills/create-modernization-plan/infra-plan-template.md delete mode 100644 .github/skills/create-modernization-plan/java-upgrade-guideline.md delete mode 100644 .github/skills/create-modernization-plan/plan-template.md delete mode 100644 .github/skills/create-modernization-plan/questionnaire.md delete mode 100644 .github/skills/create-modernization-plan/security-plan-template.md delete mode 100644 .github/skills/create-modernization-plan/supported-patterns-dotnet.md delete mode 100644 .github/skills/create-modernization-plan/supported-patterns-java.md delete mode 100644 .github/skills/create-modernization-plan/tasks-schema.json delete mode 100644 .github/skills/cve-known-vulnerabilities/SKILL.md delete mode 100644 .github/skills/cwe-code-quality/SKILL.md delete mode 100644 .github/skills/cwe-concurrency-synchronization/SKILL.md delete mode 100644 .github/skills/cwe-credentials-secrets/SKILL.md delete mode 100644 .github/skills/cwe-file-path-security/SKILL.md delete mode 100644 .github/skills/cwe-injection-attacks/SKILL.md delete mode 100644 .github/skills/cwe-memory-safety/SKILL.md delete mode 100644 .github/skills/data-architecture/SKILL.md delete mode 100644 .github/skills/dependency-map/SKILL.md delete mode 100644 .github/skills/execute-java-upgrade-task/SKILL.md delete mode 100644 .github/skills/execute-modernization-task/SKILL.md delete mode 100644 .github/skills/execute-upgrade-task/SKILL.md delete mode 100644 .github/skills/fact-application-name/SKILL.md delete mode 100644 .github/skills/fact-application-port/SKILL.md delete mode 100644 .github/skills/fact-application-type/SKILL.md delete mode 100644 .github/skills/fact-architecture-pattern/SKILL.md delete mode 100644 .github/skills/fact-base-image/SKILL.md delete mode 100644 .github/skills/fact-communication-protocols/SKILL.md delete mode 100644 .github/skills/fact-compliance-requirements/SKILL.md delete mode 100644 .github/skills/fact-container-engine/SKILL.md delete mode 100644 .github/skills/fact-container-version/SKILL.md delete mode 100644 .github/skills/fact-data-classification/SKILL.md delete mode 100644 .github/skills/fact-embedded-language-usage/SKILL.md delete mode 100644 .github/skills/fact-environment-variables/SKILL.md delete mode 100644 .github/skills/fact-external-dependencies/SKILL.md delete mode 100644 .github/skills/fact-external-services/SKILL.md delete mode 100644 .github/skills/fact-hardware-requirements/SKILL.md delete mode 100644 .github/skills/fact-health-checks/SKILL.md delete mode 100644 .github/skills/fact-image-layers/SKILL.md delete mode 100644 .github/skills/fact-image-size/SKILL.md delete mode 100644 .github/skills/fact-language-dependencies/SKILL.md delete mode 100644 .github/skills/fact-licensing-information/SKILL.md delete mode 100644 .github/skills/fact-multi-stage-build/SKILL.md delete mode 100644 .github/skills/fact-network-settings/SKILL.md delete mode 100644 .github/skills/fact-operating-system/SKILL.md delete mode 100644 .github/skills/fact-orchestration-tool/SKILL.md delete mode 100644 .github/skills/fact-profile-settings/SKILL.md delete mode 100644 .github/skills/fact-resource-limits/SKILL.md delete mode 100644 .github/skills/fact-runtime-environment/SKILL.md delete mode 100644 .github/skills/fact-security-implementation/SKILL.md delete mode 100644 .github/skills/fact-service-definition/SKILL.md delete mode 100644 .github/skills/fact-servlet-container/SKILL.md delete mode 100644 .github/skills/fact-startup-instrumentation/SKILL.md delete mode 100644 .github/skills/fact-system-packages/SKILL.md delete mode 100644 .github/skills/fact-testing-framework/SKILL.md delete mode 100644 .github/skills/fact-version-information/SKILL.md delete mode 100644 .github/skills/fact-volume-mounts/SKILL.md delete mode 100644 .github/skills/fact-xml-configs/SKILL.md delete mode 100644 .github/skills/integration-tests/SKILL.md delete mode 100644 .github/skills/integration-tests/references/azure-auth-strategies.md delete mode 100644 .github/skills/integration-tests/references/azure-servicebus-testcontainers.md delete mode 100644 .github/skills/integration-tests/references/azure-storage-testcontainers.md delete mode 100644 .github/skills/integration-tests/references/layer1-local-integration.md delete mode 100644 .github/skills/integration-tests/references/layer2-runner-script-templates.md delete mode 100644 .github/skills/integration-tests/references/layer2-smoke-tests.md delete mode 100644 .github/skills/integration-tests/references/layer3-azure-integration.md delete mode 100644 .github/skills/integration-tests/references/layer4-behavioral-comparison.md delete mode 100644 .github/skills/playbook-create/SKILL.md delete mode 100644 .github/skills/playbook-create/charter-template.md delete mode 100644 .github/skills/playbook-create/policies-template.md delete mode 100644 .github/skills/playbook-create/targets-template.md delete mode 100644 .github/skills/rearchitect/SKILL.md delete mode 100644 .github/skills/reconcile-tasks-with-plan/SKILL.md delete mode 100644 .github/skills/repository-dependency-graph/SKILL.md delete mode 100644 .github/skills/security-assessment-merge/SKILL.md delete mode 100644 .github/skills/validate-playbook-compliance/SKILL.md delete mode 100644 .github/skills/validate-playbook-evidence/SKILL.md diff --git a/.github/modernize/appcat/.gitignore b/.github/modernize/appcat/.gitignore new file mode 100644 index 000000000..235a3a8c2 --- /dev/null +++ b/.github/modernize/appcat/.gitignore @@ -0,0 +1,2 @@ + +* diff --git a/.github/modernize/appcat/appcat.log b/.github/modernize/appcat/appcat.log new file mode 100644 index 000000000..f92383105 --- /dev/null +++ b/.github/modernize/appcat/appcat.log @@ -0,0 +1,330 @@ +time="2026-05-20T08:20:27Z" level=info msg="running analysis for input: /home/runner/work/PhotoAlbum-Java/PhotoAlbum-Java" +time="2026-05-20T08:20:27Z" level=info msg="creating provider config" +time="2026-05-20T08:20:27Z" level=info msg="setting provider from provider config" provider=java +time="2026-05-20T08:20:27Z" level=info msg="setting provider from provider config" provider=builtin +time="2026-05-20T08:20:27Z" level=info msg="collecting application properties" +time="2026-05-20T08:20:27Z" level=info msg="loading rules for analysis" rules=/home/runner/.appcat/rulesets +time="2026-05-20T08:20:28Z" level=info msg="starting provider" provider=java +time="2026-05-20T08:20:32Z" level=info msg="starting provider" provider=builtin +time="2026-05-20T08:20:32Z" level=info msg="evaluating rules for violations. see analysis.log for more info" +time="2026-05-20T08:20:33Z" level=info msg="[1/309] processed rule" ruleID=azure-aws-config-region-02000 +time="2026-05-20T08:20:33Z" level=info msg="[2/309] processed rule" ruleID=azure-aws-config-credential-01000 +time="2026-05-20T08:20:33Z" level=info msg="[3/309] processed rule" ruleID=hardcoded-ip-address +time="2026-05-20T08:20:34Z" level=info msg="[4/309] processed rule" ruleID=azure-aws-config-sqs-04004 +time="2026-05-20T08:20:34Z" level=info msg="[5/309] processed rule" ruleID=azure-cache-redis-01000 +time="2026-05-20T08:20:34Z" level=info msg="[6/309] processed rule" ruleID=azure-database-config-mongodb-02000 +time="2026-05-20T08:20:34Z" level=info msg="[7/309] processed rule" ruleID=azure-file-system-02000 +time="2026-05-20T08:20:34Z" level=info msg="[8/309] processed rule" ruleID=azure-file-system-03000 +time="2026-05-20T08:20:36Z" level=info msg="[9/309] processed rule" ruleID=azure-java-version-01000 +time="2026-05-20T08:20:36Z" level=info msg="progressive report updated" +time="2026-05-20T08:20:36Z" level=info msg="[10/309] processed rule" ruleID=azure-java-version-02000 +time="2026-05-20T08:20:36Z" level=info msg="[11/309] processed rule" ruleID=azure-keystore-certificates-01000 +time="2026-05-20T08:20:37Z" level=info msg="progressive report updated" +time="2026-05-20T08:20:53Z" level=info msg="[12/309] processed rule" ruleID=azure-aws-config-s3-03001 +time="2026-05-20T08:20:53Z" level=info msg="[13/309] processed rule" ruleID=azure-aws-config-sqs-04000 +time="2026-05-20T08:20:53Z" level=info msg="[14/309] processed rule" ruleID=aws-lambda-to-azure-functions-01000 +time="2026-05-20T08:20:53Z" level=info msg="[15/309] processed rule" ruleID=azure-aws-config-sqs-04002 +time="2026-05-20T08:20:53Z" level=info msg="[16/309] processed rule" ruleID=azure-message-queue-config-kafka-01000 +time="2026-05-20T08:20:53Z" level=info msg="[17/309] processed rule" ruleID=azure-message-queue-config-rabbitmq-01000 +time="2026-05-20T08:20:53Z" level=info msg="[18/309] processed rule" ruleID=azure-message-queue-spring-jms-rabbitmq-01000 +time="2026-05-20T08:20:53Z" level=info msg="[19/309] processed rule" ruleID=azure-message-queue-config-artemis-01000 +time="2026-05-20T08:20:53Z" level=info msg="[20/309] processed rule" ruleID=azure-message-queue-amqp-02000 +time="2026-05-20T08:20:53Z" level=info msg="[21/309] processed rule" ruleID=azure-message-queue-ibm-jms-01000 +time="2026-05-20T08:20:53Z" level=info msg="[22/309] processed rule" ruleID=amazon-sns-to-azure-servicebus-01000 +time="2026-05-20T08:20:53Z" level=info msg="[23/309] processed rule" ruleID=azure-message-queue-activemq-01000 +time="2026-05-20T08:20:56Z" level=info msg="[24/309] processed rule" ruleID=azure-aws-config-sqs-04003 +time="2026-05-20T08:20:56Z" level=info msg="[25/309] processed rule" ruleID=amazon-kinesis-to-azure-eventhubs-01000 +time="2026-05-20T08:20:56Z" level=info msg="[26/309] processed rule" ruleID=apache-pulsar-to-azure-eventhubs-01000 +time="2026-05-20T08:20:56Z" level=info msg="[27/309] processed rule" ruleID=azure-aws-config-sqs-04001 +time="2026-05-20T08:20:57Z" level=info msg="[28/309] processed rule" ruleID=azure-aws-config-secret-manager-05000 +time="2026-05-20T08:20:57Z" level=info msg="[29/309] processed rule" ruleID=tibco-ems-jms-to-azure-servicebus-jms-01000 +time="2026-05-20T08:20:57Z" level=info msg="[30/309] processed rule" ruleID=spring-boot-to-azure-config-server-01000 +time="2026-05-20T08:20:57Z" level=info msg="[31/309] processed rule" ruleID=spring-boot-to-azure-eureka-01000 +time="2026-05-20T08:20:57Z" level=info msg="[32/309] processed rule" ruleID=azure-keystore-certificates-02000 +time="2026-05-20T08:20:57Z" level=info msg="[33/309] processed rule" ruleID=azure-message-queue-rabbitmq-01000 +time="2026-05-20T08:20:57Z" level=info msg="[34/309] processed rule" ruleID=spring-boot-to-azure-port-01000 +time="2026-05-20T08:20:57Z" level=info msg="[35/309] processed rule" ruleID=spring-boot-to-azure-restricted-config-01000 +time="2026-05-20T08:20:57Z" level=info msg="[36/309] processed rule" ruleID=quartz-scheduler-to-azure-functions-01000 +time="2026-05-20T08:20:57Z" level=info msg="[37/309] processed rule" ruleID=spring-batch-to-azure-durable-functions-01000 +time="2026-05-20T08:20:57Z" level=info msg="[38/309] processed rule" ruleID=spring-boot-to-azure-spring-boot-version-01000 +time="2026-05-20T08:20:57Z" level=info msg="[39/309] processed rule" ruleID=spring-boot-to-azure-spring-boot-version-02000 +time="2026-05-20T08:20:57Z" level=info msg="[40/309] processed rule" ruleID=spring-boot-to-azure-spring-cloud-version-01000 +time="2026-05-20T08:20:57Z" level=info msg="[41/309] processed rule" ruleID=spring-boot-to-azure-spring-cloud-version-02000 +time="2026-05-20T08:20:57Z" level=info msg="[42/309] processed rule" ruleID=azure-message-queue-java-ee-rabbitmq-amqp-01000 +time="2026-05-20T08:20:57Z" level=info msg="[43/309] processed rule" ruleID=solace-pubsubplus-to-azure-servicebus-01000 +time="2026-05-20T08:20:57Z" level=info msg="[44/309] processed rule" ruleID=azure-aws-config-s3-03000 +time="2026-05-20T08:20:58Z" level=info msg="[45/309] processed rule" ruleID=azure-aws-config-s3-03002 +time="2026-05-20T08:20:58Z" level=info msg="[46/309] processed rule" ruleID=azure-system-config-01000 +time="2026-05-20T08:20:58Z" level=info msg="[47/309] processed rule" ruleID=azure-tas-binding-01000 +time="2026-05-20T08:20:58Z" level=info msg="progressive report updated" +time="2026-05-20T08:20:58Z" level=info msg="[48/309] processed rule" ruleID=spring-boot-to-azure-eureka-02000 +time="2026-05-20T08:20:58Z" level=info msg="[49/309] processed rule" ruleID=database-reliability-01000 +time="2026-05-20T08:20:58Z" level=info msg="[50/309] processed rule" ruleID=azure-database-microsoft-cassandra-04000 +time="2026-05-20T08:20:58Z" level=info msg="[51/309] processed rule" ruleID=spring-boot-to-azure-eureka-03000 +time="2026-05-20T08:20:58Z" level=info msg="[52/309] processed rule" ruleID=azure-database-microsoft-mongodb-05000 +time="2026-05-20T08:20:58Z" level=info msg="[53/309] processed rule" ruleID=azure-database-microsoft-sql-03000 +time="2026-05-20T08:20:58Z" level=info msg="[54/309] processed rule" ruleID=azure-database-microsoft-mariadb-06000 +time="2026-05-20T08:20:58Z" level=info msg="[55/309] processed rule" ruleID=ibm-db2-to-azure-postgresql-01000 +time="2026-05-20T08:20:58Z" level=info msg="[56/309] processed rule" ruleID=firebird-to-azure-postgresql-01000 +time="2026-05-20T08:20:58Z" level=info msg="[57/309] processed rule" ruleID=sqlite-to-azure-postgresql-01000 +time="2026-05-20T08:20:58Z" level=info msg="[58/309] processed rule" ruleID=apm-00001 +time="2026-05-20T08:20:58Z" level=info msg="[59/309] processed rule" ruleID=apm-00002 +time="2026-05-20T08:20:58Z" level=info msg="[60/309] processed rule" ruleID=azure-database-microsoft-oracle-07000 +time="2026-05-20T08:20:58Z" level=info msg="[61/309] processed rule" ruleID=auth-01000 +time="2026-05-20T08:20:58Z" level=info msg="[62/309] processed rule" ruleID=auth-00000 +time="2026-05-20T08:20:58Z" level=info msg="[63/309] processed rule" ruleID=auth-02000 +time="2026-05-20T08:20:58Z" level=info msg="[64/309] processed rule" ruleID=auth-03000 +time="2026-05-20T08:20:58Z" level=info msg="[65/309] processed rule" ruleID=auth-04000 +time="2026-05-20T08:20:58Z" level=info msg="[66/309] processed rule" ruleID=spring-boot-to-azure-openfeign-01000 +time="2026-05-20T08:20:58Z" level=info msg="[67/309] processed rule" ruleID=openliberty-database-00002 +time="2026-05-20T08:20:58Z" level=info msg="[68/309] processed rule" ruleID=spring-boot-to-azure-key-vault-01000 +time="2026-05-20T08:20:58Z" level=info msg="[69/309] processed rule" ruleID=openliberty-database-00005 +time="2026-05-20T08:20:59Z" level=info msg="[70/309] processed rule" ruleID=azure-database-mysql-01000 +time="2026-05-20T08:20:59Z" level=info msg="[71/309] processed rule" ruleID=azure-database-postgresql-02000 +time="2026-05-20T08:20:59Z" level=info msg="progressive report updated" +time="2026-05-20T08:21:00Z" level=info msg="[72/309] processed rule" ruleID=openliberty-database-00004 +time="2026-05-20T08:21:00Z" level=info msg="[73/309] processed rule" ruleID=openliberty-database-00007 +time="2026-05-20T08:21:00Z" level=info msg="[74/309] processed rule" ruleID=openliberty-database-00006 +time="2026-05-20T08:21:00Z" level=info msg="[75/309] processed rule" ruleID=openliberty-filesystem-00003 +time="2026-05-20T08:21:00Z" level=info msg="[76/309] processed rule" ruleID=apm-00003 +time="2026-05-20T08:21:00Z" level=info msg="[77/309] processed rule" ruleID=openliberty-filesystem-00004 +time="2026-05-20T08:21:01Z" level=info msg="[78/309] processed rule" ruleID=openliberty-jms-00002 +time="2026-05-20T08:21:01Z" level=info msg="[79/309] processed rule" ruleID=openliberty-jms-00003 +time="2026-05-20T08:21:01Z" level=info msg="[80/309] processed rule" ruleID=openliberty-database-00001 +time="2026-05-20T08:21:01Z" level=info msg="[81/309] processed rule" ruleID=openliberty-jms-00006 +time="2026-05-20T08:21:01Z" level=info msg="[82/309] processed rule" ruleID=openliberty-jms-00005 +time="2026-05-20T08:21:01Z" level=info msg="[83/309] processed rule" ruleID=azure-password-01000 +time="2026-05-20T08:21:01Z" level=info msg="[84/309] processed rule" ruleID=openliberty-database-00003 +time="2026-05-20T08:21:01Z" level=info msg="[85/309] processed rule" ruleID=spring-framework-version-01000 +time="2026-05-20T08:21:01Z" level=info msg="[86/309] processed rule" ruleID=spring-framework-version-02000 +time="2026-05-20T08:21:01Z" level=info msg="[87/309] processed rule" ruleID=jakarta-ee-version-01000 +time="2026-05-20T08:21:02Z" level=info msg="[88/309] processed rule" ruleID=openliberty-filesystem-00001 +time="2026-05-20T08:21:02Z" level=info msg="[89/309] processed rule" ruleID=google-firestore-to-azure-cosmosdb-01000 +time="2026-05-20T08:21:02Z" level=info msg="[90/309] processed rule" ruleID=google-cloud-bigtable-to-azure-cosmosdb-01000 +time="2026-05-20T08:21:02Z" level=info msg="[91/309] processed rule" ruleID=google-pubsub-to-azure-service-bus-01000 +time="2026-05-20T08:21:02Z" level=info msg="progressive report updated" +time="2026-05-20T08:21:02Z" level=info msg="[92/309] processed rule" ruleID=java-ldap-to-msft-entra-id-01000 +time="2026-05-20T08:21:02Z" level=info msg="[93/309] processed rule" ruleID=google-cloud-storage-to-azure-blob-storage-01000 +time="2026-05-20T08:21:02Z" level=info msg="[94/309] processed rule" ruleID=google-cloud-functions-to-azure-functions-01000 +time="2026-05-20T08:21:02Z" level=info msg="[95/309] processed rule" ruleID=google-cloud-spanner-to-azure-postgresql-01000 +time="2026-05-20T08:21:02Z" level=info msg="[96/309] processed rule" ruleID=sybase-ase-to-azure-database-01000 +time="2026-05-20T08:21:02Z" level=info msg="[97/309] processed rule" ruleID=embedded-cache-01000 +time="2026-05-20T08:21:02Z" level=info msg="[98/309] processed rule" ruleID=embedded-cache-02000 +time="2026-05-20T08:21:02Z" level=info msg="[99/309] processed rule" ruleID=embedded-cache-03000 +time="2026-05-20T08:21:02Z" level=info msg="[100/309] processed rule" ruleID=embedded-cache-04000 +time="2026-05-20T08:21:02Z" level=info msg="[101/309] processed rule" ruleID=embedded-cache-05000 +time="2026-05-20T08:21:02Z" level=info msg="[102/309] processed rule" ruleID=embedded-cache-06000 +time="2026-05-20T08:21:02Z" level=info msg="[103/309] processed rule" ruleID=embedded-cache-07000 +time="2026-05-20T08:21:02Z" level=info msg="[104/309] processed rule" ruleID=openliberty-database-00009 +time="2026-05-20T08:21:02Z" level=info msg="[105/309] processed rule" ruleID=embedded-cache-08000 +time="2026-05-20T08:21:02Z" level=info msg="[106/309] processed rule" ruleID=embedded-cache-09000 +time="2026-05-20T08:21:02Z" level=info msg="[107/309] processed rule" ruleID=embedded-cache-10000 +time="2026-05-20T08:21:02Z" level=info msg="[108/309] processed rule" ruleID=embedded-cache-11000 +time="2026-05-20T08:21:02Z" level=info msg="[109/309] processed rule" ruleID=embedded-cache-12000 +time="2026-05-20T08:21:02Z" level=info msg="[110/309] processed rule" ruleID=embedded-cache-13000 +time="2026-05-20T08:21:02Z" level=info msg="[111/309] processed rule" ruleID=embedded-cache-14000 +time="2026-05-20T08:21:02Z" level=info msg="[112/309] processed rule" ruleID=embedded-cache-16000 +time="2026-05-20T08:21:02Z" level=info msg="[113/309] processed rule" ruleID=openliberty-jms-00001 +time="2026-05-20T08:21:02Z" level=info msg="[114/309] processed rule" ruleID=embedded-cache-15000 +time="2026-05-20T08:21:02Z" level=info msg="[115/309] processed rule" ruleID=java-rmi-00000 +time="2026-05-20T08:21:02Z" level=info msg="[116/309] processed rule" ruleID=java-rmi-00001 +time="2026-05-20T08:21:02Z" level=info msg="[117/309] processed rule" ruleID=java-corba-00000 +time="2026-05-20T08:21:02Z" level=info msg="[118/309] processed rule" ruleID=java-rpc-00000 +time="2026-05-20T08:21:02Z" level=info msg="[119/309] processed rule" ruleID=openliberty-database-00008 +time="2026-05-20T08:21:03Z" level=info msg="[120/309] processed rule" ruleID=openliberty-logging-00001 +time="2026-05-20T08:21:03Z" level=info msg="[121/309] processed rule" ruleID=local-storage-00002 +time="2026-05-20T08:21:03Z" level=info msg="[122/309] processed rule" ruleID=local-storage-00003 +time="2026-05-20T08:21:03Z" level=info msg="[123/309] processed rule" ruleID=openliberty-filesystem-00002 +time="2026-05-20T08:21:03Z" level=info msg="[124/309] processed rule" ruleID=local-storage-00001 +time="2026-05-20T08:21:03Z" level=info msg="[125/309] processed rule" ruleID=openliberty-logging-00002 +time="2026-05-20T08:21:03Z" level=info msg="[126/309] processed rule" ruleID=jni-native-code-00000 +time="2026-05-20T08:21:03Z" level=info msg="[127/309] processed rule" ruleID=google-gcr-to-azure-acr-01000 +time="2026-05-20T08:21:03Z" level=info msg="[128/309] processed rule" ruleID=jca-00000 +time="2026-05-20T08:21:04Z" level=info msg="[129/309] processed rule" ruleID=local-storage-00006 +time="2026-05-20T08:21:04Z" level=info msg="[130/309] processed rule" ruleID=local-storage-00005 +time="2026-05-20T08:21:04Z" level=info msg="[131/309] processed rule" ruleID=jni-native-code-00001 +time="2026-05-20T08:21:04Z" level=info msg="[132/309] processed rule" ruleID=logging-0001 +time="2026-05-20T08:21:04Z" level=info msg="[133/309] processed rule" ruleID=logging-0003 +time="2026-05-20T08:21:04Z" level=info msg="[134/309] processed rule" ruleID=logging-0004 +time="2026-05-20T08:21:04Z" level=info msg="[135/309] processed rule" ruleID=logging-0005 +time="2026-05-20T08:21:04Z" level=info msg="[136/309] processed rule" ruleID=logging-0000 +time="2026-05-20T08:21:04Z" level=info msg="[137/309] processed rule" ruleID=local-storage-00004 +time="2026-05-20T08:21:04Z" level=info msg="[138/309] processed rule" ruleID=openliberty-jms-00004 +time="2026-05-20T08:21:04Z" level=info msg="[139/309] processed rule" ruleID=socket-communication-00001 +time="2026-05-20T08:21:04Z" level=info msg="[140/309] processed rule" ruleID=session-00001 +time="2026-05-20T08:21:04Z" level=info msg="[141/309] processed rule" ruleID=web-11000 +time="2026-05-20T08:21:04Z" level=info msg="[142/309] processed rule" ruleID=web-10000 +time="2026-05-20T08:21:04Z" level=info msg="[143/309] processed rule" ruleID=socket-communication-00000 +time="2026-05-20T08:21:04Z" level=info msg="[144/309] processed rule" ruleID=localhost-http-00001 +time="2026-05-20T08:21:04Z" level=info msg="[145/309] processed rule" ruleID=localhost-jdbc-00002 +time="2026-05-20T08:21:04Z" level=info msg="[146/309] processed rule" ruleID=localhost-ws-00003 +time="2026-05-20T08:21:04Z" level=info msg="[147/309] processed rule" ruleID=hardcoded-urls-00001 +time="2026-05-20T08:21:04Z" level=info msg="[148/309] processed rule" ruleID=hardcoded-urls-00002 +time="2026-05-20T08:21:05Z" level=info msg="[149/309] processed rule" ruleID=windows-registry-00000 +time="2026-05-20T08:21:05Z" level=info msg="[150/309] processed rule" ruleID=unsecure-network-protocol-00000 +time="2026-05-20T08:21:05Z" level=info msg="[151/309] processed rule" ruleID=localhost-00004 +time="2026-05-20T08:21:06Z" level=info msg="[152/309] processed rule" ruleID=logging-0002 +time="2026-05-20T08:21:06Z" level=info msg="[153/309] processed rule" ruleID=ant-build-tool-00001 +time="2026-05-20T08:21:06Z" level=info msg="[154/309] processed rule" ruleID=webform-auth-00000 +time="2026-05-20T08:21:06Z" level=info msg="[155/309] processed rule" ruleID=jakarta-auth-00001 +time="2026-05-20T08:21:06Z" level=info msg="[156/309] processed rule" ruleID=jakarta-database-00001 +time="2026-05-20T08:21:06Z" level=info msg="[157/309] processed rule" ruleID=jakarta-database-00002 +time="2026-05-20T08:21:06Z" level=info msg="[158/309] processed rule" ruleID=jakarta-database-00003 +time="2026-05-20T08:21:06Z" level=info msg="[159/309] processed rule" ruleID=jakarta-service-00001 +time="2026-05-20T08:21:06Z" level=info msg="[160/309] processed rule" ruleID=jakarta-service-00002 +time="2026-05-20T08:21:06Z" level=info msg="[161/309] processed rule" ruleID=external-config-00000 +time="2026-05-20T08:21:06Z" level=info msg="progressive report updated" +time="2026-05-20T08:21:06Z" level=info msg="[162/309] processed rule" ruleID=dockerfile-00000 +time="2026-05-20T08:21:06Z" level=info msg="[163/309] processed rule" ruleID=dockerfile-00010 +time="2026-05-20T08:21:06Z" level=info msg="[164/309] processed rule" ruleID=dockerfile-00020 +time="2026-05-20T08:21:06Z" level=info msg="[165/309] processed rule" ruleID=dockerfile-00030 +time="2026-05-20T08:21:06Z" level=info msg="[166/309] processed rule" ruleID=mail-00000 +time="2026-05-20T08:21:06Z" level=info msg="[167/309] processed rule" ruleID=clustering-00000 +time="2026-05-20T08:21:06Z" level=info msg="[168/309] processed rule" ruleID=cra-weak-crypto-md5-01000 +time="2026-05-20T08:21:06Z" level=info msg="[169/309] processed rule" ruleID=cra-weak-crypto-sha1-02000 +time="2026-05-20T08:21:06Z" level=info msg="[170/309] processed rule" ruleID=cra-weak-crypto-des-03000 +time="2026-05-20T08:21:06Z" level=info msg="[171/309] processed rule" ruleID=cra-weak-crypto-rc4-04000 +time="2026-05-20T08:21:06Z" level=info msg="[172/309] processed rule" ruleID=cra-weak-crypto-ecb-05000 +time="2026-05-20T08:21:06Z" level=info msg="[173/309] processed rule" ruleID=cra-weak-crypto-password-hash-07000 +time="2026-05-20T08:21:06Z" level=info msg="[174/309] processed rule" ruleID=cra-weak-crypto-blowfish-06000 +time="2026-05-20T08:21:07Z" level=info msg="[175/309] processed rule" ruleID=cra-hardcoded-credential-password-01000 +time="2026-05-20T08:21:07Z" level=info msg="[176/309] processed rule" ruleID=cra-hardcoded-credential-apikey-02000 +time="2026-05-20T08:21:07Z" level=info msg="[177/309] processed rule" ruleID=cra-insecure-tls-hostname-verify-04000 +time="2026-05-20T08:21:07Z" level=info msg="[178/309] processed rule" ruleID=cra-insecure-tls-protocol-01000 +time="2026-05-20T08:21:07Z" level=info msg="[179/309] processed rule" ruleID=cra-insecure-random-math-02000 +time="2026-05-20T08:21:07Z" level=info msg="[180/309] processed rule" ruleID=cra-insecure-tls-trust-all-03000 +time="2026-05-20T08:21:07Z" level=info msg="[181/309] processed rule" ruleID=cra-insecure-random-01000 +time="2026-05-20T08:21:07Z" level=info msg="[182/309] processed rule" ruleID=cra-hardcoded-credential-crypto-key-05000 +time="2026-05-20T08:21:07Z" level=info msg="[183/309] processed rule" ruleID=cra-insecure-random-threadlocal-03000 +time="2026-05-20T08:21:07Z" level=info msg="[184/309] processed rule" ruleID=java-10-deprecate-javafx-00000 +time="2026-05-20T08:21:07Z" level=info msg="[185/309] processed rule" ruleID=java-10-deprecate-dom-00000 +time="2026-05-20T08:21:07Z" level=info msg="[186/309] processed rule" ruleID=java-10-deprecate-security-00000 +time="2026-05-20T08:21:07Z" level=info msg="[187/309] processed rule" ruleID=java-10-deprecate-security-00001 +time="2026-05-20T08:21:07Z" level=info msg="[188/309] processed rule" ruleID=java-10-deprecate-runtime-00000 +time="2026-05-20T08:21:07Z" level=info msg="[189/309] processed rule" ruleID=java-10-deprecate-security-00002 +time="2026-05-20T08:21:07Z" level=info msg="[190/309] processed rule" ruleID=azure-java-sdk-legacy-migration-01000 +time="2026-05-20T08:21:07Z" level=info msg="[191/309] processed rule" ruleID=java-10-deprecate-security-00003 +time="2026-05-20T08:21:07Z" level=info msg="[192/309] processed rule" ruleID=java-10-deprecate-security-00004 +time="2026-05-20T08:21:07Z" level=info msg="[193/309] processed rule" ruleID=java-11-deprecate-awt-00000 +time="2026-05-20T08:21:07Z" level=info msg="[194/309] processed rule" ruleID=java-11-deprecate-javaee-00001 +time="2026-05-20T08:21:07Z" level=info msg="[195/309] processed rule" ruleID=java-11-deprecate-property-00000 +time="2026-05-20T08:21:07Z" level=info msg="[196/309] processed rule" ruleID=java-11-deprecate-property-00001 +time="2026-05-20T08:21:07Z" level=info msg="[197/309] processed rule" ruleID=java-11-deprecate-javaee-00000 +time="2026-05-20T08:21:07Z" level=info msg="[198/309] processed rule" ruleID=java-11-deprecate-pack-00000 +time="2026-05-20T08:21:08Z" level=info msg="[199/309] processed rule" ruleID=cra-insecure-tls-cipher-suite-05000 +time="2026-05-20T08:21:08Z" level=info msg="[200/309] processed rule" ruleID=java-11-deprecate-security-00000 +time="2026-05-20T08:21:08Z" level=info msg="[201/309] processed rule" ruleID=java-11-deprecate-security-00001 +time="2026-05-20T08:21:08Z" level=info msg="[202/309] processed rule" ruleID=java-11-deprecate-stream-00000 +time="2026-05-20T08:21:08Z" level=info msg="[203/309] processed rule" ruleID=cra-hardcoded-credential-config-03000 +time="2026-05-20T08:21:08Z" level=info msg="[204/309] processed rule" ruleID=java-11-deprecate-peer-00000 +time="2026-05-20T08:21:08Z" level=info msg="[205/309] processed rule" ruleID=java-11-deprecate-corba-00000 +time="2026-05-20T08:21:08Z" level=info msg="[206/309] processed rule" ruleID=cra-hardcoded-credential-default-pwd-04000 +time="2026-05-20T08:21:08Z" level=info msg="[207/309] processed rule" ruleID=java-11-deprecate-unsafe-00000 +time="2026-05-20T08:21:08Z" level=info msg="[208/309] processed rule" ruleID=java-11-deprecate-unsafe-00001 +time="2026-05-20T08:21:08Z" level=info msg="[209/309] processed rule" ruleID=java-removals-00010 +time="2026-05-20T08:21:08Z" level=info msg="[210/309] processed rule" ruleID=java-9-deprecate-javafx-00000 +time="2026-05-20T08:21:08Z" level=info msg="[211/309] processed rule" ruleID=java-9-deprecate-property-00000 +time="2026-05-20T08:21:08Z" level=info msg="[212/309] processed rule" ruleID=java-9-deprecate-property-00001 +time="2026-05-20T08:21:08Z" level=info msg="[213/309] processed rule" ruleID=java-11-deprecate-thread-00000 +time="2026-05-20T08:21:08Z" level=info msg="[214/309] processed rule" ruleID=java-removals-00000 +time="2026-05-20T08:21:08Z" level=info msg="[215/309] processed rule" ruleID=java-9-deprecate-dom-00000 +time="2026-05-20T08:21:08Z" level=info msg="[216/309] processed rule" ruleID=java-9-deprecate-log-00000 +time="2026-05-20T08:21:08Z" level=info msg="[217/309] processed rule" ruleID=java-9-deprecate-security-00000 +time="2026-05-20T08:21:08Z" level=info msg="[218/309] processed rule" ruleID=java-9-deprecate-peer-00000 +time="2026-05-20T08:21:08Z" level=info msg="[219/309] processed rule" ruleID=java-9-deprecate-security-00001 +time="2026-05-20T08:21:08Z" level=info msg="[220/309] processed rule" ruleID=java-9-deprecate-reflect-00000 +time="2026-05-20T08:21:08Z" level=info msg="[221/309] processed rule" ruleID=java-9-deprecate-url-00000 +time="2026-05-20T08:21:08Z" level=info msg="[222/309] processed rule" ruleID=java-9-deprecate-reflect-00010 +time="2026-05-20T08:21:08Z" level=info msg="[223/309] processed rule" ruleID=java-9-deprecate-security-00002 +time="2026-05-20T08:21:08Z" level=info msg="[224/309] processed rule" ruleID=java-9-deprecate-unsafe-00000 +time="2026-05-20T08:21:08Z" level=info msg="[225/309] processed rule" ruleID=java-9-deprecate-unsafe-00001 +time="2026-05-20T08:21:09Z" level=info msg="[226/309] processed rule" ruleID=java-12-deprecate-security-00000 +time="2026-05-20T08:21:09Z" level=info msg="[227/309] processed rule" ruleID=java-9-deprecate-pack-00000 +time="2026-05-20T08:21:09Z" level=info msg="[228/309] processed rule" ruleID=java-14-deprecate-property-00000 +time="2026-05-20T08:21:09Z" level=info msg="[229/309] processed rule" ruleID=java-9-deprecate-tracing-00000 +time="2026-05-20T08:21:09Z" level=info msg="[230/309] processed rule" ruleID=java-13-deprecate-security-00000 +time="2026-05-20T08:21:09Z" level=info msg="[231/309] processed rule" ruleID=java-9-deprecate-agent-00000 +time="2026-05-20T08:21:09Z" level=info msg="[232/309] processed rule" ruleID=eclipse-00002 +time="2026-05-20T08:21:09Z" level=info msg="[233/309] processed rule" ruleID=java-12-deprecate-finalize-00000 +time="2026-05-20T08:21:09Z" level=info msg="[234/309] processed rule" ruleID=java-14-deprecate-pack-00000 +time="2026-05-20T08:21:09Z" level=info msg="[235/309] processed rule" ruleID=java-15-deprecate-ssl-00001 +time="2026-05-20T08:21:09Z" level=info msg="[236/309] processed rule" ruleID=java-14-deprecate-property-00001 +time="2026-05-20T08:21:09Z" level=info msg="[237/309] processed rule" ruleID=java-14-deprecate-security-00000 +time="2026-05-20T08:21:09Z" level=info msg="[238/309] processed rule" ruleID=java-13-deprecate-runtime-00000 +time="2026-05-20T08:21:09Z" level=info msg="[239/309] processed rule" ruleID=java-15-deprecate-property-00000 +time="2026-05-20T08:21:09Z" level=info msg="[240/309] processed rule" ruleID=java-15-deprecate-signer-00000 +time="2026-05-20T08:21:09Z" level=info msg="[241/309] processed rule" ruleID=java-15-deprecate-ssl-00000 +time="2026-05-20T08:21:09Z" level=info msg="[242/309] processed rule" ruleID=java-12-deprecate-finalize-00001 +time="2026-05-20T08:21:09Z" level=info msg="[243/309] processed rule" ruleID=java-17-deprecate-security-manager-00000 +time="2026-05-20T08:21:09Z" level=info msg="[244/309] processed rule" ruleID=java-17-deprecate-security-manager-00010 +time="2026-05-20T08:21:09Z" level=info msg="[245/309] processed rule" ruleID=java-17-deprecate-security-manager-00030 +time="2026-05-20T08:21:09Z" level=info msg="[246/309] processed rule" ruleID=java-17-deprecate-security-manager-00040 +time="2026-05-20T08:21:09Z" level=info msg="[247/309] processed rule" ruleID=java-17-deprecate-security-manager-00050 +time="2026-05-20T08:21:10Z" level=info msg="[248/309] processed rule" ruleID=java-17-deprecate-security-manager-00060 +time="2026-05-20T08:21:10Z" level=info msg="[249/309] processed rule" ruleID=lombok-incompatibility-00001 +time="2026-05-20T08:21:10Z" level=info msg="[250/309] processed rule" ruleID=java-17-deprecate-security-manager-00020 +time="2026-05-20T08:21:10Z" level=info msg="[251/309] processed rule" ruleID=java-17-deprecate-security-manager-00070 +time="2026-05-20T08:21:10Z" level=info msg="[252/309] processed rule" ruleID=java-17-deprecate-applet-00000 +time="2026-05-20T08:21:10Z" level=info msg="[253/309] processed rule" ruleID=java-17-deprecate-unsafe-00000 +time="2026-05-20T08:21:10Z" level=info msg="[254/309] processed rule" ruleID=java-18-deprecate-property-00000 +time="2026-05-20T08:21:10Z" level=info msg="[255/309] processed rule" ruleID=removed-packages-00000 +time="2026-05-20T08:21:10Z" level=info msg="[256/309] processed rule" ruleID=cra-insecure-tls-config-02000 +time="2026-05-20T08:21:10Z" level=info msg="[257/309] processed rule" ruleID=java-18-deprecate-socket-00000 +time="2026-05-20T08:21:10Z" level=info msg="[258/309] processed rule" ruleID=java-16-deprecate-security-00000 +time="2026-05-20T08:21:10Z" level=info msg="[259/309] processed rule" ruleID=java-18-deprecate-runtime-00000 +time="2026-05-20T08:21:10Z" level=info msg="[260/309] processed rule" ruleID=java-14-deprecate-thread-00000 +time="2026-05-20T08:21:10Z" level=info msg="[261/309] processed rule" ruleID=java-18-deprecate-security-00000 +time="2026-05-20T08:21:10Z" level=info msg="[262/309] processed rule" ruleID=removed-packages-00010 +time="2026-05-20T08:21:10Z" level=info msg="[263/309] processed rule" ruleID=java-19-deprecate-param-spec-00001 +time="2026-05-20T08:21:10Z" level=info msg="[264/309] processed rule" ruleID=java-18-deprecate-thread-00000 +time="2026-05-20T08:21:10Z" level=info msg="[265/309] processed rule" ruleID=java-17-deprecate-socket-00000 +time="2026-05-20T08:21:10Z" level=info msg="[266/309] processed rule" ruleID=java-16-deprecate-thread-group-00000 +time="2026-05-20T08:21:10Z" level=info msg="[267/309] processed rule" ruleID=java-19-deprecate-locale-00000 +time="2026-05-20T08:21:10Z" level=info msg="[268/309] processed rule" ruleID=java-19-deprecate-param-spec-00000 +time="2026-05-20T08:21:10Z" level=info msg="[269/309] processed rule" ruleID=java-19-deprecate-thread-00001 +time="2026-05-20T08:21:10Z" level=info msg="[270/309] processed rule" ruleID=java-18-deprecate-finalize-00000 +time="2026-05-20T08:21:10Z" level=info msg="[271/309] processed rule" ruleID=java-20-deprecate-net-00000 +time="2026-05-20T08:21:10Z" level=info msg="[272/309] processed rule" ruleID=java-20-deprecate-thread-00001 +time="2026-05-20T08:21:10Z" level=info msg="[273/309] processed rule" ruleID=java-20-deprecate-thread-00002 +time="2026-05-20T08:21:10Z" level=info msg="[274/309] processed rule" ruleID=java-19-deprecate-thread-00002 +time="2026-05-20T08:21:10Z" level=info msg="[275/309] processed rule" ruleID=java-18-deprecate-unsafe-00000 +time="2026-05-20T08:21:10Z" level=info msg="[276/309] processed rule" ruleID=java-18-deprecate-finalize-00001 +time="2026-05-20T08:21:10Z" level=info msg="[277/309] processed rule" ruleID=java-21-deprecate-property-00000 +time="2026-05-20T08:21:10Z" level=info msg="[278/309] processed rule" ruleID=java-21-deprecate-dynamic-agents-00000 +time="2026-05-20T08:21:10Z" level=info msg="[279/309] processed rule" ruleID=java-20-deprecate-thread-00000 +time="2026-05-20T08:21:10Z" level=info msg="[280/309] processed rule" ruleID=java-21-deprecate-file-00001 +time="2026-05-20T08:21:10Z" level=info msg="[281/309] processed rule" ruleID=java-21-deprecate-jmx-00000 +time="2026-05-20T08:21:10Z" level=info msg="[282/309] processed rule" ruleID=java-21-deprecate-jmx-00001 +time="2026-05-20T08:21:10Z" level=info msg="[283/309] processed rule" ruleID=java-21-deprecate-property-00001 +time="2026-05-20T08:21:10Z" level=info msg="[284/309] processed rule" ruleID=java-21-deprecate-signer-00000 +time="2026-05-20T08:21:11Z" level=info msg="[285/309] processed rule" ruleID=java-21-deprecate-thread-00000 +time="2026-05-20T08:21:11Z" level=info msg="[286/309] processed rule" ruleID=java-21-deprecate-file-00000 +time="2026-05-20T08:21:11Z" level=info msg="[287/309] processed rule" ruleID=utf-8-by-default-00000 +time="2026-05-20T08:21:11Z" level=info msg="[288/309] processed rule" ruleID=utf-8-by-default-00010 +time="2026-05-20T08:21:11Z" level=info msg="[289/309] processed rule" ruleID=utf-8-by-default-00020 +time="2026-05-20T08:21:11Z" level=info msg="[290/309] processed rule" ruleID=java-20-deprecate-jmx-00000 +time="2026-05-20T08:21:11Z" level=info msg="[291/309] processed rule" ruleID=utf-8-by-default-00030 +time="2026-05-20T08:21:11Z" level=info msg="[292/309] processed rule" ruleID=java-8-deprecate-odbc-00001 +time="2026-05-20T08:21:11Z" level=info msg="[293/309] processed rule" ruleID=oracle2openjdk-00002 +time="2026-05-20T08:21:11Z" level=info msg="[294/309] processed rule" ruleID=java-8-deprecate-apt-00001 +time="2026-05-20T08:21:11Z" level=info msg="[295/309] processed rule" ruleID=java-8-deprecate-callback-00001 +time="2026-05-20T08:21:11Z" level=info msg="[296/309] processed rule" ruleID=java-8-deprecate-corba-00001 +time="2026-05-20T08:21:11Z" level=info msg="[297/309] processed rule" ruleID=java-8-deprecate-javafx-builder-00001 +time="2026-05-20T08:21:11Z" level=info msg="[298/309] processed rule" ruleID=java-8-deprecate-security-00001 +time="2026-05-20T08:21:11Z" level=info msg="[299/309] processed rule" ruleID=java-8-deprecate-security-manager-00001 +time="2026-05-20T08:21:11Z" level=info msg="[300/309] processed rule" ruleID=java-8-deprecate-log-00001 +time="2026-05-20T08:21:11Z" level=info msg="[301/309] processed rule" ruleID=java-8-deprecate-pack-00001 +time="2026-05-20T08:21:11Z" level=info msg="[302/309] processed rule" ruleID=java-8-deprecate-pack-00002 +time="2026-05-20T08:21:11Z" level=info msg="[303/309] processed rule" ruleID=java-19-deprecate-thread-00000 +time="2026-05-20T08:21:11Z" level=info msg="[304/309] processed rule" ruleID=java-8-deprecate-security-00002 +time="2026-05-20T08:21:11Z" level=info msg="[305/309] processed rule" ruleID=java-8-deprecate-thread-00001 +time="2026-05-20T08:21:11Z" level=info msg="[306/309] processed rule" ruleID=java-8-deprecate-security-manager-00002 +time="2026-05-20T08:21:11Z" level=info msg="[307/309] processed rule" ruleID=java-19-deprecate-class-00010 +time="2026-05-20T08:21:11Z" level=info msg="[308/309] processed rule" ruleID=oracle2openjdk-00006 +time="2026-05-20T08:21:11Z" level=info msg="[309/309] processed rule" ruleID=java-8-deprecate-stream-00001 +time="2026-05-20T08:21:11Z" level=info msg="RunRules completed" +time="2026-05-20T08:21:11Z" level=info msg="creating and saving unified result" +time="2026-05-20T08:21:11Z" level=info msg="Unified result saved to file" file=/home/runner/work/PhotoAlbum-Java/PhotoAlbum-Java/.github/modernize/appcat/result/report.json +time="2026-05-20T08:21:11Z" level=info msg="unable to get dependency output. use source analysis result only" +time="2026-05-20T08:21:11Z" level=info msg="skipping static report generation because of --skip-static-report flag" +EXIT_CODE: 0 diff --git a/.github/modernize/appcat/assessment-config.yaml b/.github/modernize/appcat/assessment-config.yaml new file mode 100644 index 000000000..5e4777ded --- /dev/null +++ b/.github/modernize/appcat/assessment-config.yaml @@ -0,0 +1,69 @@ +# You can edit this file to configure the application assessment. Please note that any changes saved to this file will be applied the next time you run the assessment. +# The configurable [AppCAT](https://aka.ms/appcat-java) arguments +# +# - target: target Azure compute service to run the apps on. Choosing multiple targets if you haven't decided which one to use and later you can choose and compare on the assessment report. +# |----------------------|------------------------------------------------------------------------| +# | Target | Description | +# |----------------------|------------------------------------------------------------------------| +# | azure-aks | Best practices for deploying an app to Azure Kubernetes Service. | +# | azure-appservice | Best practices for deploying an app to Azure App Service. | +# | azure-container-apps | Best practices for deploying an app to Azure Container Apps. | +# |----------------------|------------------------------------------------------------------------| +# +# - capability: target technology to modernize the apps towards. +# |----------------------|------------------------------------------------------------------------| +# | Capability | Description | +# |----------------------|------------------------------------------------------------------------| +# | containerization | Best practices for containerizing applications. | +# | openjdk11 | Best practices for migrating to OpenJDK 11. | +# | openjdk17 | Best practices for migrating to OpenJDK 17. | +# | openjdk21 | Best practices for migrating to OpenJDK 21. | +# |----------------------|------------------------------------------------------------------------| +# +# - os: target operating system to run the apps on. +# |----------------------|------------------------------------------------------------------------| +# | OS name | Description | +# |----------------------|------------------------------------------------------------------------| +# | linux | Best practices for migrating applications to the Linux platform. | +# | windows | Best practices for migrating applications to the Windows platform. | +# |----------------------|------------------------------------------------------------------------| +# +# - mode: analysis mode. +# |-------------|----------------------------------------------------------------------------------------| +# | Mode | Description | +# |-------------|----------------------------------------------------------------------------------------| +# | issue-only | analyze source code to only detect issues | +# | source-only | analyze source code to detect both issues and used technologies | +# | full | analyze source code to detect both issues and used technologies, and list dependencies | +# |-------------|----------------------------------------------------------------------------------------| +# +# Three examples on how to configure properly. +# +# Example one: you'd like to migrate your apps to AKS as linux containers and want to understand what are the issues to be fixed: +# appcat: +# - target: +# - azure-aks +# os: +# - linux +# mode: issue-only +# +# Example two: you'd like to migrate your apps to App Service Linux and want to understand what are the issues to be fixed: +# appcat: +# - target: +# - azure-appservice +# os: +# - linux +# mode: issue-only +# +# Example three: you'd like to modernize your apps to JDK21 and want to understand what are the issues to be fixed: +# appcat: +# - capability: +# - openjdk21 +# mode: issue-only + +appcat: + - target: + - azure-aks + - azure-appservice + - azure-container-apps + mode: issue-only diff --git a/.github/modernize/appcat/result/analysis.log b/.github/modernize/appcat/result/analysis.log new file mode 100644 index 000000000..978af2c2c --- /dev/null +++ b/.github/modernize/appcat/result/analysis.log @@ -0,0 +1,3074 @@ +time="2026-05-20T08:20:28Z" level=info msg="maven wrapper path" mvnwPath=/home/runner/.appcat/maven-wrapper/mvnw provider=java wrapperPaths="[\"/home/runner/work/PhotoAlbum-Java/PhotoAlbum-Java/.mvn\",\"/home/runner/work/PhotoAlbum-Java/PhotoAlbum-Java/.mvn/wrapper/maven-wrapper.jar\",\"/home/runner/work/PhotoAlbum-Java/PhotoAlbum-Java/.mvn/wrapper/maven-wrapper.properties\"]" +time="2026-05-20T08:20:28Z" level=info msg="setting parallelism parameters" java.util.concurrent.ForkJoinPool.common.parallelism=4 provider=java runtime.NumCPU=4 +time="2026-05-20T08:20:28Z" level=info msg="Stderr pipe created successfully" provider=java +time="2026-05-20T08:20:28Z" level=info msg="preparing to start JDTLS language server process" provider=java +time="2026-05-20T08:20:28Z" level=info msg="JDTLS process started successfully" provider=java +time="2026-05-20T08:20:28Z" level=info msg="configuring RPC concurrency limit" forkJoinParallelism=4 provider=java rpcConcurrencyLimit=1 +time="2026-05-20T08:20:28Z" level=info msg="Starting RPC connection run loop" provider=java +time="2026-05-20T08:20:29Z" level=info msg="[JDTLS]" output="May 20, 2026 8:20:29 AM org.apache.aries.spifly.BaseActivator log" provider=java +time="2026-05-20T08:20:29Z" level=info msg="[JDTLS]" output="INFO: Registered provider ch.qos.logback.classic.spi.LogbackServiceProvider of service org.slf4j.spi.SLF4JServiceProvider in bundle ch.qos.logback.classic" provider=java +time="2026-05-20T08:20:32Z" level=info msg="inject span info" carrier="{}" +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:33Z" level=info msg="rule returned" ruleID=azure-aws-config-region-02000 +time="2026-05-20T08:20:33Z" level=info msg="processed rule" logger=process-rule processed=1 ruleID=azure-aws-config-region-02000 total=309 +time="2026-05-20T08:20:33Z" level=info msg="rule returned" ruleID=azure-aws-config-credential-01000 +time="2026-05-20T08:20:33Z" level=info msg="processed rule" logger=process-rule processed=2 ruleID=azure-aws-config-credential-01000 total=309 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:20:33Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:33Z" level=info msg="rule returned" ruleID=hardcoded-ip-address +time="2026-05-20T08:20:33Z" level=info msg="processed rule" logger=process-rule processed=3 ruleID=hardcoded-ip-address total=309 +time="2026-05-20T08:20:34Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:34Z" level=info msg="rule returned" ruleID=azure-aws-config-sqs-04004 +time="2026-05-20T08:20:34Z" level=info msg="processed rule" logger=process-rule processed=4 ruleID=azure-aws-config-sqs-04004 total=309 +time="2026-05-20T08:20:34Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:34Z" level=info msg="rule returned" ruleID=azure-cache-redis-01000 +time="2026-05-20T08:20:34Z" level=info msg="processed rule" logger=process-rule processed=5 ruleID=azure-cache-redis-01000 total=309 +time="2026-05-20T08:20:34Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:34Z" level=info msg="rule returned" ruleID=azure-database-config-mongodb-02000 +time="2026-05-20T08:20:34Z" level=info msg="processed rule" logger=process-rule processed=6 ruleID=azure-database-config-mongodb-02000 total=309 +time="2026-05-20T08:20:34Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:34Z" level=info msg="rule returned" ruleID=azure-file-system-02000 +time="2026-05-20T08:20:34Z" level=info msg="processed rule" logger=process-rule processed=7 ruleID=azure-file-system-02000 total=309 +time="2026-05-20T08:20:34Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:34Z" level=info msg="rule returned" ruleID=azure-file-system-03000 +time="2026-05-20T08:20:34Z" level=info msg="processed rule" logger=process-rule processed=8 ruleID=azure-file-system-03000 total=309 +time="2026-05-20T08:20:36Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:36Z" level=info msg="rule returned" ruleID=azure-java-version-01000 +time="2026-05-20T08:20:36Z" level=info msg="processed rule" logger=process-rule processed=9 ruleID=azure-java-version-01000 total=309 +time="2026-05-20T08:20:36Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:36Z" level=info msg="rule returned" ruleID=azure-java-version-02000 +time="2026-05-20T08:20:36Z" level=info msg="processed rule" logger=process-rule processed=10 ruleID=azure-java-version-02000 total=309 +time="2026-05-20T08:20:36Z" level=info msg="rule returned" ruleID=azure-keystore-certificates-01000 +time="2026-05-20T08:20:36Z" level=info msg="processed rule" logger=process-rule processed=11 ruleID=azure-keystore-certificates-01000 total=309 +time="2026-05-20T08:20:36Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:47Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@76ae7207" provider=java +time="2026-05-20T08:20:47Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:47Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:47Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <software.amazon.awssdk.services.sqs*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <software.amazon.awssdk.services.sqs*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:53Z" level=info msg="dependency analysis result shared from concurrent request" provider=java +time="2026-05-20T08:20:53Z" level=info msg="dependency analysis result shared from concurrent request" provider=java +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:20:53Z" level=info msg="dependency analysis result shared from concurrent request" provider=java +time="2026-05-20T08:20:53Z" level=info msg="dependency analysis result shared from concurrent request" provider=java +time="2026-05-20T08:20:53Z" level=info msg="dependency analysis result shared from concurrent request" provider=java +time="2026-05-20T08:20:53Z" level=info msg="dependency analysis result shared from concurrent request" provider=java +time="2026-05-20T08:20:53Z" level=info msg="dependency analysis result shared from concurrent request" provider=java +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=azure-aws-config-s3-03001 +time="2026-05-20T08:20:53Z" level=info msg="dependency analysis result shared from concurrent request" provider=java +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=12 ruleID=azure-aws-config-s3-03001 total=309 +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=azure-aws-config-sqs-04000 +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=13 ruleID=azure-aws-config-sqs-04000 total=309 +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=aws-lambda-to-azure-functions-01000 +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=14 ruleID=aws-lambda-to-azure-functions-01000 total=309 +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=azure-aws-config-sqs-04002 +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=15 ruleID=azure-aws-config-sqs-04002 total=309 +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=azure-message-queue-config-kafka-01000 +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=16 ruleID=azure-message-queue-config-kafka-01000 total=309 +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=azure-message-queue-config-rabbitmq-01000 +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=17 ruleID=azure-message-queue-config-rabbitmq-01000 total=309 +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=azure-message-queue-spring-jms-rabbitmq-01000 +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=18 ruleID=azure-message-queue-spring-jms-rabbitmq-01000 total=309 +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=azure-message-queue-config-artemis-01000 +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=19 ruleID=azure-message-queue-config-artemis-01000 total=309 +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=azure-message-queue-amqp-02000 +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=20 ruleID=azure-message-queue-amqp-02000 total=309 +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=azure-message-queue-ibm-jms-01000 +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=21 ruleID=azure-message-queue-ibm-jms-01000 total=309 +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=amazon-sns-to-azure-servicebus-01000 +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=22 ruleID=amazon-sns-to-azure-servicebus-01000 total=309 +time="2026-05-20T08:20:53Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:20:53Z" level=info msg="rule returned" ruleID=azure-message-queue-activemq-01000 +time="2026-05-20T08:20:53Z" level=info msg="processed rule" logger=process-rule processed=23 ruleID=azure-message-queue-activemq-01000 total=309 +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"software.amazon.awssdk.services.sqs*\" and location type: 11" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:56Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"software.amazon.awssdk.services.sqs*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:56Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:20:56Z" level=info msg="rule returned" ruleID=azure-aws-config-sqs-04003 +time="2026-05-20T08:20:56Z" level=info msg="processed rule" logger=process-rule processed=24 ruleID=azure-aws-config-sqs-04003 total=309 +time="2026-05-20T08:20:56Z" level=info msg="rule returned" ruleID=amazon-kinesis-to-azure-eventhubs-01000 +time="2026-05-20T08:20:56Z" level=info msg="processed rule" logger=process-rule processed=25 ruleID=amazon-kinesis-to-azure-eventhubs-01000 total=309 +time="2026-05-20T08:20:56Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:20:56Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:20:56Z" level=info msg="rule returned" ruleID=apache-pulsar-to-azure-eventhubs-01000 +time="2026-05-20T08:20:56Z" level=info msg="processed rule" logger=process-rule processed=26 ruleID=apache-pulsar-to-azure-eventhubs-01000 total=309 +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@69142cf8" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.amazonaws.services.sqs*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.amazonaws.services.sqs*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.amazonaws.services.sqs*\" and location type: 11" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:56Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.amazonaws.services.sqs*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:56Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:20:56Z" level=info msg="rule returned" ruleID=azure-aws-config-sqs-04001 +time="2026-05-20T08:20:56Z" level=info msg="processed rule" logger=process-rule processed=27 ruleID=azure-aws-config-sqs-04001 total=309 +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3d521337" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <software.amazon.awssdk.services.s3.presigner*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <software.amazon.awssdk.services.s3.presigner*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"software.amazon.awssdk.services.s3.presigner*\" and location type: 11" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:56Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"software.amazon.awssdk.services.s3.presigner*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7b2bc5a8" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.security.keystore.getinstance*(...), pattern match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.KeyStore.getInstance*\" and location type: 2" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:56Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.KeyStore.getInstance*\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6dfb6014" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:56Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<software.amazon.awssdk.services>, type<secretsmanager*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<secretsmanager*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<software.amazon.awssdk.services>, type<secretsmanager*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"software.amazon.awssdk.services.secretsmanager*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"software.amazon.awssdk.services.secretsmanager*\" and location type: 8" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=azure-aws-config-secret-manager-05000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=28 ruleID=azure-aws-config-secret-manager-05000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4acd1789" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.amazonaws.services.s3*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.amazonaws.services.s3*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.amazonaws.services.s3*\" and location type: 11" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.amazonaws.services.s3*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6cd4df8" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <org.springframework.amqp.rabbit*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <org.springframework.amqp.rabbit*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.springframework.amqp.rabbit*\" and location type: 11" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.springframework.amqp.rabbit*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@38b022d5" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.rabbitmq.client*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.rabbitmq.client*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.rabbitmq.client*\" and location type: 11" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.rabbitmq.client*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7dbc3d8d" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.solacesystems>, type<jms*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<jms*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.solacesystems>, type<jms*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.solacesystems.jms*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.solacesystems.jms*\" and location type: 8" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5f6f1cec" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.tibco>, type<tibjms*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<tibjms*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.tibco>, type<tibjms*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.tibco.tibjms*\" and location type: 8" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.tibco.tibjms*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=tibco-ems-jms-to-azure-servicebus-jms-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=29 ruleID=tibco-ems-jms-to-azure-servicebus-jms-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-config-server-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=30 ruleID=spring-boot-to-azure-config-server-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@33212874" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.system.getenv(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-eureka-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=31 ruleID=spring-boot-to-azure-eureka-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.System.getenv\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.System.getenv\" and location type: 2" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1474d4c9" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.amazonaws.services.s3.model>, type<GeneratePresignedUrlRequest> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<GeneratePresignedUrlRequest>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.amazonaws.services.s3.model>, type<GeneratePresignedUrlRequest>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: com.amazonaws.services.s3.model.generatepresignedurlrequest(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: com.amazonaws.services.s3.model.GeneratePresignedUrlRequest(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.amazonaws.services.s3.model.GeneratePresignedUrlRequest\" and location type: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.amazonaws.services.s3.model.GeneratePresignedUrlRequest\",\"Location\":\"\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3a2963f5" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.security.keystore.load*(...), pattern match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.KeyStore.load*\" and location type: 2" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.KeyStore.load*\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=azure-keystore-certificates-02000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=32 ruleID=azure-keystore-certificates-02000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@47bf18be" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <io.awspring.cloud.s3*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <io.awspring.cloud.s3*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"io.awspring.cloud.s3*\" and location type: 11" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"io.awspring.cloud.s3*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@616f291e" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.rabbitmq.client*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.rabbitmq.client*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.rabbitmq.client*\" and location type: 11" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.rabbitmq.client*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=azure-message-queue-rabbitmq-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=33 ruleID=azure-message-queue-rabbitmq-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-port-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=34 ruleID=spring-boot-to-azure-port-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-restricted-config-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=35 ruleID=spring-boot-to-azure-restricted-config-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=quartz-scheduler-to-azure-functions-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=36 ruleID=quartz-scheduler-to-azure-functions-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:57Z" level=error msg="failed to get location for dependency" dep=org.springframework.boot.spring-boot-autoconfigure error="unable to get location for dep org.springframework.boot.spring-boot-autoconfigure, search error - %!w(<nil>)" ruleID=spring-boot-to-azure-spring-boot-version-01000 worker=3 +time="2026-05-20T08:20:57Z" level=error msg="failed to get location for dependency" dep=org.springframework.boot.spring-boot error="unable to get location for dep org.springframework.boot.spring-boot, search error - %!w(<nil>)" ruleID=spring-boot-to-azure-spring-boot-version-01000 worker=3 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=spring-batch-to-azure-durable-functions-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=37 ruleID=spring-batch-to-azure-durable-functions-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-spring-boot-version-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=38 ruleID=spring-boot-to-azure-spring-boot-version-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:57Z" level=error msg="failed to get location for dependency" dep=org.springframework.boot.spring-boot error="unable to get location for dep org.springframework.boot.spring-boot due to a previous scan" ruleID=spring-boot-to-azure-spring-boot-version-02000 worker=3 +time="2026-05-20T08:20:57Z" level=error msg="failed to get location for dependency" dep=org.springframework.boot.spring-boot-autoconfigure error="unable to get location for dep org.springframework.boot.spring-boot-autoconfigure due to a previous scan" ruleID=spring-boot-to-azure-spring-boot-version-02000 worker=3 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-spring-boot-version-02000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=39 ruleID=spring-boot-to-azure-spring-boot-version-02000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-spring-cloud-version-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=40 ruleID=spring-boot-to-azure-spring-cloud-version-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-spring-cloud-version-02000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=41 ruleID=spring-boot-to-azure-spring-cloud-version-02000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@59dce942" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <org.springframework.amqp.rabbit*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <org.springframework.amqp.rabbit*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.springframework.amqp.rabbit*\" and location type: 11" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.springframework.amqp.rabbit*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=azure-message-queue-java-ee-rabbitmq-amqp-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=42 ruleID=azure-message-queue-java-ee-rabbitmq-amqp-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@289b0f47" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.solacesystems>, type<jcsmp*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<jcsmp*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.solacesystems>, type<jcsmp*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.solacesystems.jcsmp*\" and location type: 8" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.solacesystems.jcsmp*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=solace-pubsubplus-to-azure-servicebus-01000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=43 ruleID=solace-pubsubplus-to-azure-servicebus-01000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@175e8802" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.system.getproperty(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.System.getProperty\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.System.getProperty\" and location type: 2" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.amazonaws.services.s3.transfer*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@515589ef" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.amazonaws.services.s3.transfer*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.amazonaws.services.s3.transfer*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.amazonaws.services.s3.transfer*\" and location type: 11" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5f98847f" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <software.amazon.awssdk.services.s3*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <software.amazon.awssdk.services.s3*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"software.amazon.awssdk.services.s3*\" and location type: 11" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:57Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"software.amazon.awssdk.services.s3*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:57Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:20:57Z" level=info msg="rule returned" ruleID=azure-aws-config-s3-03000 +time="2026-05-20T08:20:57Z" level=info msg="processed rule" logger=process-rule processed=44 ruleID=azure-aws-config-s3-03000 total=309 +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7b07641" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:57Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.system.setproperty(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:20:58Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.System.setProperty\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.System.setProperty\" and location type: 2" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@310e877c" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<software.amazon.awssdk.transfer.s3>, type<S3TransferManager> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<S3TransferManager>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<software.amazon.awssdk.transfer.s3>, type<S3TransferManager>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: software.amazon.awssdk.transfer.s3.s3transfermanager(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: software.amazon.awssdk.transfer.s3.S3TransferManager(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"software.amazon.awssdk.transfer.s3.S3TransferManager\" and location type: 0" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:58Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"software.amazon.awssdk.transfer.s3.S3TransferManager\",\"Location\":\"\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3b241885" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.system.setproperties(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=azure-aws-config-s3-03002 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=45 ruleID=azure-aws-config-s3-03002 total=309 +time="2026-05-20T08:20:58Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.System.setProperties\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.System.setProperties\" and location type: 2" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=azure-system-config-01000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=46 ruleID=azure-system-config-01000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=azure-tas-binding-01000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=47 ruleID=azure-tas-binding-01000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-eureka-02000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=48 ruleID=spring-boot-to-azure-eureka-02000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=database-reliability-01000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=49 ruleID=database-reliability-01000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=azure-database-microsoft-cassandra-04000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=50 ruleID=azure-database-microsoft-cassandra-04000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-eureka-03000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=51 ruleID=spring-boot-to-azure-eureka-03000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=azure-database-microsoft-mongodb-05000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=52 ruleID=azure-database-microsoft-mongodb-05000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=azure-database-microsoft-sql-03000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=53 ruleID=azure-database-microsoft-sql-03000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=azure-database-microsoft-mariadb-06000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=54 ruleID=azure-database-microsoft-mariadb-06000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=ibm-db2-to-azure-postgresql-01000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=55 ruleID=ibm-db2-to-azure-postgresql-01000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=firebird-to-azure-postgresql-01000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=56 ruleID=firebird-to-azure-postgresql-01000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=sqlite-to-azure-postgresql-01000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=57 ruleID=sqlite-to-azure-postgresql-01000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=apm-00001 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=58 ruleID=apm-00001 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=apm-00002 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=59 ruleID=apm-00002 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=azure-database-microsoft-oracle-07000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=60 ruleID=azure-database-microsoft-oracle-07000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=auth-01000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=61 ruleID=auth-01000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=auth-00000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=62 ruleID=auth-00000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=auth-02000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=63 ruleID=auth-02000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=auth-03000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=64 ruleID=auth-03000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=auth-04000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=65 ruleID=auth-04000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-openfeign-01000 +time="2026-05-20T08:20:58Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"(javax|jakarta).persistence.EntityManager\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=66 ruleID=spring-boot-to-azure-openfeign-01000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=openliberty-database-00002 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=67 ruleID=openliberty-database-00002 total=309 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@432a7ae9" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.persistence>, type<EntityManager> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<EntityManager>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.persistence>, type<EntityManager>, exact match, case sensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<jakarta.persistence>, type<EntityManager> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<EntityManager>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<jakarta.persistence>, type<EntityManager>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"(javax|jakarta).persistence.EntityManager\" and location type: 8" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@76bbdc38" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.annotation>, type<Resource> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.annotation>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<jakarta.annotation>, type<Resource> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<jakarta.annotation>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=spring-boot-to-azure-key-vault-01000 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=68 ruleID=spring-boot-to-azure-key-vault-01000 total=309 +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"(javax|jakarta).annotation.Resource\" and location type: 4" provider=java +time="2026-05-20T08:20:58Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:20:58Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"(javax|jakarta).annotation.Resource\",\"Location\":\"ANNOTATION\",\"annotated\":{\"pattern\":\"\",\"elements\":[{\"name\":\"name\",\"value\":\"jdbc/[a-zA-Z0-9_-]+\"}]},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:20:58Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:20:58Z" level=info msg="rule returned" ruleID=openliberty-database-00005 +time="2026-05-20T08:20:58Z" level=info msg="processed rule" logger=process-rule processed=69 ruleID=openliberty-database-00005 total=309 +time="2026-05-20T08:20:59Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:20:59Z" level=info msg="rule returned" ruleID=azure-database-mysql-01000 +time="2026-05-20T08:20:59Z" level=info msg="processed rule" logger=process-rule processed=70 ruleID=azure-database-mysql-01000 total=309 +time="2026-05-20T08:20:59Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:20:59Z" level=info msg="rule returned" ruleID=azure-database-postgresql-02000 +time="2026-05-20T08:20:59Z" level=info msg="processed rule" logger=process-rule processed=71 ruleID=azure-database-postgresql-02000 total=309 +time="2026-05-20T08:20:59Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:00Z" level=info msg="rule returned" ruleID=openliberty-database-00004 +time="2026-05-20T08:21:00Z" level=info msg="processed rule" logger=process-rule processed=72 ruleID=openliberty-database-00004 total=309 +time="2026-05-20T08:21:00Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:00Z" level=info msg="rule returned" ruleID=openliberty-database-00007 +time="2026-05-20T08:21:00Z" level=info msg="processed rule" logger=process-rule processed=73 ruleID=openliberty-database-00007 total=309 +time="2026-05-20T08:21:00Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:00Z" level=info msg="rule returned" ruleID=openliberty-database-00006 +time="2026-05-20T08:21:00Z" level=info msg="processed rule" logger=process-rule processed=74 ruleID=openliberty-database-00006 total=309 +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@44f58769" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.annotation>, type<Resource> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.annotation>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<jakarta.annotation>, type<Resource> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<jakarta.annotation>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"(javax|jakarta).annotation.Resource\" and location type: 4" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:00Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"(javax|jakarta).annotation.Resource\",\"Location\":\"ANNOTATION\",\"annotated\":{\"pattern\":\"\",\"elements\":[{\"name\":\"name\",\"value\":\".*(?i)(path|dir|directory|folder|file|store|upload|download|temp|cache|log|data|config).*\"}]},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:00Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:00Z" level=info msg="rule returned" ruleID=openliberty-filesystem-00003 +time="2026-05-20T08:21:00Z" level=info msg="processed rule" logger=process-rule processed=75 ruleID=openliberty-filesystem-00003 total=309 +time="2026-05-20T08:21:00Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.servlet.ServletContext.getRealPath\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@52c589d2" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.servlet.servletcontext.getrealpath(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.servlet.ServletContext.getRealPath\" and location type: 2" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2ae238e1" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: jakarta.servlet.servletcontext.getrealpath(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"jakarta.servlet.ServletContext.getRealPath\" and location type: 2" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:00Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:00Z" level=info msg="rule returned" ruleID=apm-00003 +time="2026-05-20T08:21:00Z" level=info msg="processed rule" logger=process-rule processed=76 ruleID=apm-00003 total=309 +time="2026-05-20T08:21:00Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"jakarta.servlet.ServletContext.getRealPath\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:00Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:00Z" level=info msg="rule returned" ruleID=openliberty-filesystem-00004 +time="2026-05-20T08:21:00Z" level=info msg="processed rule" logger=process-rule processed=77 ruleID=openliberty-filesystem-00004 total=309 +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@63c86fa1" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.annotation>, type<Resource> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.annotation>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<jakarta.annotation>, type<Resource> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<jakarta.annotation>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"(javax|jakarta).annotation.Resource\" and location type: 4" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:00Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"(javax|jakarta).annotation.Resource\",\"Location\":\"ANNOTATION\",\"annotated\":{\"pattern\":\"\",\"elements\":[{\"name\":\"name\",\"value\":\"jms/[a-zA-Z0-9_-]+\"}]},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@403f093f" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:00Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.annotation>, type<Resource> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.annotation>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<jakarta.annotation>, type<Resource> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<jakarta.annotation>, type<Resource>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:01Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"(javax|jakarta).annotation.Resource\",\"Location\":\"ANNOTATION\",\"annotated\":{\"pattern\":\"\",\"elements\":[{\"name\":\"lookup\",\"value\":\"jms/[a-zA-Z0-9_-]+\"}]},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:01Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"(javax|jakarta).annotation.Resource\" and location type: 4" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:01Z" level=info msg="rule returned" ruleID=openliberty-jms-00002 +time="2026-05-20T08:21:01Z" level=info msg="processed rule" logger=process-rule processed=78 ruleID=openliberty-jms-00002 total=309 +time="2026-05-20T08:21:01Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"(javax|jakarta).ejb.MessageDriven\",\"Location\":\"ANNOTATION\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:01Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@65abc5f7" provider=java +time="2026-05-20T08:21:01Z" level=info msg="rule returned" ruleID=openliberty-jms-00003 +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:01Z" level=info msg="processed rule" logger=process-rule processed=79 ruleID=openliberty-jms-00003 total=309 +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.ejb>, type<MessageDriven> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<MessageDriven>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.ejb>, type<MessageDriven>, exact match, case sensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<jakarta.ejb>, type<MessageDriven> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<MessageDriven>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<jakarta.ejb>, type<MessageDriven>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"(javax|jakarta).ejb.MessageDriven\" and location type: 4" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:01Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:01Z" level=info msg="rule returned" ruleID=openliberty-database-00001 +time="2026-05-20T08:21:01Z" level=info msg="processed rule" logger=process-rule processed=80 ruleID=openliberty-database-00001 total=309 +time="2026-05-20T08:21:01Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:01Z" level=info msg="rule returned" ruleID=openliberty-jms-00006 +time="2026-05-20T08:21:01Z" level=info msg="processed rule" logger=process-rule processed=81 ruleID=openliberty-jms-00006 total=309 +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6327617b" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax>, type<jms*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<jms*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax>, type<jms*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<jakarta>, type<jms*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<jms*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<jakarta>, type<jms*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"(javax|jakarta).jms*\" and location type: 8" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:01Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"(javax|jakarta).jms*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:01Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:01Z" level=info msg="rule returned" ruleID=openliberty-jms-00005 +time="2026-05-20T08:21:01Z" level=info msg="processed rule" logger=process-rule processed=82 ruleID=openliberty-jms-00005 total=309 +time="2026-05-20T08:21:01Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:01Z" level=info msg="rule returned" ruleID=azure-password-01000 +time="2026-05-20T08:21:01Z" level=info msg="processed rule" logger=process-rule processed=83 ruleID=azure-password-01000 total=309 +time="2026-05-20T08:21:01Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:01Z" level=info msg="rule returned" ruleID=openliberty-database-00003 +time="2026-05-20T08:21:01Z" level=info msg="processed rule" logger=process-rule processed=84 ruleID=openliberty-database-00003 total=309 +time="2026-05-20T08:21:01Z" level=info msg="rule returned" ruleID=spring-framework-version-01000 +time="2026-05-20T08:21:01Z" level=info msg="processed rule" logger=process-rule processed=85 ruleID=spring-framework-version-01000 total=309 +time="2026-05-20T08:21:01Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:01Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:01Z" level=info msg="rule returned" ruleID=spring-framework-version-02000 +time="2026-05-20T08:21:01Z" level=info msg="processed rule" logger=process-rule processed=86 ruleID=spring-framework-version-02000 total=309 +time="2026-05-20T08:21:01Z" level=info msg="rule returned" ruleID=jakarta-ee-version-01000 +time="2026-05-20T08:21:01Z" level=info msg="processed rule" logger=process-rule processed=87 ruleID=jakarta-ee-version-01000 total=309 +time="2026-05-20T08:21:01Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4f5e4ffa" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.springframework.security>, type<ldap*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<ldap*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.springframework.security>, type<ldap*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.springframework.security.ldap*\" and location type: 8" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:01Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.springframework.security.ldap*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@33f786c2" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:01Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.springframework.ldap>, type<core*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<core*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.springframework.ldap>, type<core*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.springframework.ldap.core*\" and location type: 8" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.springframework.ldap.core*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7c7e71ec" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.unboundid>, type<ldap*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<ldap*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.unboundid>, type<ldap*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.unboundid.ldap*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.unboundid.ldap*\" and location type: 8" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4ac09b45" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.apache.directory.ldap.client>, type<api*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<api*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.apache.directory.ldap.client>, type<api*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=openliberty-filesystem-00001 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=88 ruleID=openliberty-filesystem-00001 total=309 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.apache.directory.ldap.client.api*\" and location type: 8" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.apache.directory.ldap.client.api*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1041dbe6" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.google.cloud>, type<firestore*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<firestore*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.google.cloud>, type<firestore*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.google.cloud.firestore*\" and location type: 8" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.google.cloud.firestore*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=google-firestore-to-azure-cosmosdb-01000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=89 ruleID=google-firestore-to-azure-cosmosdb-01000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=google-cloud-bigtable-to-azure-cosmosdb-01000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=90 ruleID=google-cloud-bigtable-to-azure-cosmosdb-01000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=google-pubsub-to-azure-service-bus-01000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=91 ruleID=google-pubsub-to-azure-service-bus-01000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@476730b4" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.naming>, type<ldap*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<ldap*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.naming>, type<ldap*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.naming.ldap*\" and location type: 8" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.naming.ldap*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4819d8a5" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.novell>, type<ldap*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<ldap*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.novell>, type<ldap*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.novell.ldap*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=java-ldap-to-msft-entra-id-01000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=92 ruleID=java-ldap-to-msft-entra-id-01000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=google-cloud-storage-to-azure-blob-storage-01000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=93 ruleID=google-cloud-storage-to-azure-blob-storage-01000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=google-cloud-functions-to-azure-functions-01000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=94 ruleID=google-cloud-functions-to-azure-functions-01000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=google-cloud-spanner-to-azure-postgresql-01000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=95 ruleID=google-cloud-spanner-to-azure-postgresql-01000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=sybase-ase-to-azure-database-01000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=96 ruleID=sybase-ase-to-azure-database-01000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-01000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=97 ruleID=embedded-cache-01000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-02000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=98 ruleID=embedded-cache-02000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-03000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=99 ruleID=embedded-cache-03000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-04000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=100 ruleID=embedded-cache-04000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-05000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=101 ruleID=embedded-cache-05000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.microsoft.azure.(applicationinsights|batch|cognitiveservices|cosmosdb|documentdb|eventgrid|eventhubs|eventprocessorhost|keyvault|loganalytics|servicebus|credentials|management|serializer|storage)*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.novell.ldap*\" and location type: 8" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@64d6850" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.microsoft.azure>, type<applicationinsights*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<applicationinsights*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<applicationinsights*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<batch*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<batch*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<batch*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<cognitiveservices*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<cognitiveservices*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<cognitiveservices*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<cosmosdb*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<cosmosdb*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<cosmosdb*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<documentdb*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<documentdb*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<documentdb*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<eventgrid*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<eventgrid*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<eventgrid*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<eventhubs*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<eventhubs*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<eventhubs*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<eventprocessorhost*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<eventprocessorhost*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<eventprocessorhost*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<keyvault*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<keyvault*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<keyvault*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<loganalytics*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<loganalytics*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<loganalytics*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<servicebus*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<servicebus*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<servicebus*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<credentials*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<credentials*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<credentials*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<management*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<management*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<management*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<serializer*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<serializer*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<serializer*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.azure>, type<storage*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<storage*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.azure>, type<storage*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.microsoft.azure.(applicationinsights|batch|cognitiveservices|cosmosdb|documentdb|eventgrid|eventhubs|eventprocessorhost|keyvault|loganalytics|servicebus|credentials|management|serializer|storage)*\" and location type: 8" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@184d0d94" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com>, type<hazelcast*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<hazelcast*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com>, type<hazelcast*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.hazelcast*\" and location type: 8" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.hazelcast*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-06000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=102 ruleID=embedded-cache-06000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@66d17cb9" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.microsoft>, type<windowsazure*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<windowsazure*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft>, type<windowsazure*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft>, type<rest*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<rest*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft>, type<rest*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<com.microsoft.aad>, type<adal4j*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<adal4j*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.microsoft.aad>, type<adal4j*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-07000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=103 ruleID=embedded-cache-07000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=openliberty-database-00009 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=104 ruleID=openliberty-database-00009 total=309 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-08000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=105 ruleID=embedded-cache-08000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-09000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=106 ruleID=embedded-cache-09000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-10000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=107 ruleID=embedded-cache-10000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.microsoft.(windowsazure|rest|aad.adal4j)*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-11000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=108 ruleID=embedded-cache-11000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-12000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=109 ruleID=embedded-cache-12000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-13000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=110 ruleID=embedded-cache-13000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-14000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=111 ruleID=embedded-cache-14000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-16000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=112 ruleID=embedded-cache-16000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.microsoft.(windowsazure|rest|aad.adal4j)*\" and location type: 8" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@600b5c36" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.springframework>, type<cache*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<cache*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.springframework>, type<cache*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=openliberty-jms-00001 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=113 ruleID=openliberty-jms-00001 total=309 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.springframework.cache*\" and location type: 8" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.springframework.cache*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=embedded-cache-15000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=114 ruleID=embedded-cache-15000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@47c50a1f" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.sun.corba*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.sun.corba*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.corba*\" and location type: 11" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.corba*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.rmi.Remote\",\"Location\":\"INHERITANCE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=java-rmi-00000 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@29b19886" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: SuperInterfaceReferencePattern: <Remote>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.rmi.Remote\" and location type: 1" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=115 ruleID=java-rmi-00000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.rmi*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=java-rmi-00001 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=116 ruleID=java-rmi-00001 total=309 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7a66c15" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <java.rmi*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <java.rmi*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.rmi*\" and location type: 11" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@685c1b0c" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <org.omg.CORBA*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <org.omg.corba*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.omg.CORBA*\" and location type: 11" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.omg.CORBA*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"(javax|jakarta).xml.rpc*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4d0cdb29" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <javax.xml.rpc*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <javax.xml.rpc*>, pattern match, case insensitive, generic full match, fine grain: none | PackageDeclarationPattern: <jakarta.xml.rpc*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <jakarta.xml.rpc*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"(javax|jakarta).xml.rpc*\" and location type: 11" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@765d6483" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.iona.corba*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.iona.corba*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.iona.corba*\" and location type: 11" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.iona.corba*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=java-corba-00000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=117 ruleID=java-corba-00000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@422f7899" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <org.apache.xmlrpc*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <org.apache.xmlrpc*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.apache.xmlrpc*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.apache.xmlrpc*\" and location type: 11" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4aa38fab" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: loadlibrary(...), exact match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"loadLibrary\" and location type: 2" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"loadLibrary\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@61ddc045" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <redstone.xmlrpc*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <redstone.xmlrpc*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"redstone.xmlrpc*\" and location type: 11" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"redstone.xmlrpc*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=java-rpc-00000 +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=118 ruleID=java-rpc-00000 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:02Z" level=info msg="rule returned" ruleID=openliberty-database-00008 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7cb9d981" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.lang.Process(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Process\" and location type: 3" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:02Z" level=info msg="processed rule" logger=process-rule processed=119 ruleID=openliberty-database-00008 total=309 +time="2026-05-20T08:21:02Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Process\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@456b9d3f" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: maplibraryname(...), exact match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"mapLibraryName\" and location type: 2" provider=java +time="2026-05-20T08:21:02Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"mapLibraryName\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@13e38cee" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.io.(File|FileWriter|FileReader|BufferedReader|BufferedWriter|PrintReader|PrintWriter|FileInputStream|FileOutputStream|PrintStream|RandomAccessFile)\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Process\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.io.File(...), exact match, case sensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.FileWriter(...), exact match, case sensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.FileReader(...), exact match, case sensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.BufferedReader(...), exact match, case sensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.BufferedWriter(...), exact match, case sensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.PrintReader(...), exact match, case sensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.PrintWriter(...), exact match, case sensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.FileInputStream(...), exact match, case sensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.FileOutputStream(...), exact match, case sensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.PrintStream(...), exact match, case sensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.RandomAccessFile(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.io.(File|FileWriter|FileReader|BufferedReader|BufferedWriter|PrintReader|PrintWriter|FileInputStream|FileOutputStream|PrintStream|RandomAccessFile)\" and location type: 3" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1c33a93f" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.lang>, type<Process> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Process>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.lang>, type<Process>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Process\" and location type: 8" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:03Z" level=info msg="rule returned" ruleID=openliberty-logging-00001 +time="2026-05-20T08:21:03Z" level=info msg="processed rule" logger=process-rule processed=120 ruleID=openliberty-logging-00001 total=309 +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.jna*\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2e741ee9" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: com.sun.jna*(...), pattern match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.jna*\" and location type: 3" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@376fec7d" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.io>, type<file*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<file*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.io>, type<file*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.io>, type<filereader*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<filereader*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.io>, type<filereader*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.io>, type<filewriter*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<filewriter*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.io>, type<filewriter*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.io>, type<bufferedreader*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<bufferedreader*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.io>, type<bufferedreader*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.io>, type<bufferedwriter*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<bufferedwriter*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.io>, type<bufferedwriter*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.io>, type<printreader*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<printreader*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.io>, type<printreader*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.io>, type<printwriter*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<printwriter*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.io>, type<printwriter*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.io>, type<fileinputstream*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<fileinputstream*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.io>, type<fileinputstream*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.io>, type<fileoutputstream*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<fileoutputstream*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.io>, type<fileoutputstream*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.io.(File|FileReader|FileWriter|BufferedReader|BufferedWriter|PrintReader|PrintWriter|FileInputStream|FileOutputStream)*\" and location type: 8" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.io.(File|FileReader|FileWriter|BufferedReader|BufferedWriter|PrintReader|PrintWriter|FileInputStream|FileOutputStream)*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Process\",\"Location\":\"INHERITANCE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@63971e7d" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: SuperInterfaceReferencePattern: <Process>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Process\" and location type: 1" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.net.(URL|URI)*\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4c9c6133" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.net.url*(...), pattern match, case insensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.net.uri*(...), pattern match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.net.(URL|URI)*\" and location type: 3" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="rule returned" ruleID=local-storage-00002 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@325f28bc" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun>, type<jna*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<jna*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun>, type<jna*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="processed rule" logger=process-rule processed=121 ruleID=local-storage-00002 total=309 +time="2026-05-20T08:21:03Z" level=info msg="rule returned" ruleID=local-storage-00003 +time="2026-05-20T08:21:03Z" level=info msg="processed rule" logger=process-rule processed=122 ruleID=local-storage-00003 total=309 +time="2026-05-20T08:21:03Z" level=info msg="rule returned" ruleID=openliberty-filesystem-00002 +time="2026-05-20T08:21:03Z" level=info msg="processed rule" logger=process-rule processed=123 ruleID=openliberty-filesystem-00002 total=309 +time="2026-05-20T08:21:03Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.jna*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.jna*\" and location type: 8" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@447217c2" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeReferencePattern: qualification<java.lang>, type<Process>, exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Process\" and location type: 9" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Process\",\"Location\":\"VARIABLE_DECLARATION\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1fcd8dc7" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.zip.ZipFile\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.util.zip.ZipFile(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.zip.ZipFile\" and location type: 3" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@30f7f2f4" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: SuperInterfaceReferencePattern: <jna*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.jna*\" and location type: 1" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.jna*\",\"Location\":\"INHERITANCE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.nio.channels.AsynchronousFileChannel*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7ba6269e" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.nio.channels>, type<asynchronousfilechannel*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<asynchronousfilechannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.channels>, type<asynchronousfilechannel*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.nio.channels.AsynchronousFileChannel*\" and location type: 8" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ProcessBuilder\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2fbee22f" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.lang.ProcessBuilder(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ProcessBuilder\" and location type: 3" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5ceee1aa" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.io.file.createtempfile(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.io.File.createTempFile\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.io.File.createTempFile\" and location type: 2" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@412ea037" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: com.sun.jna*(...), pattern match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.jna*\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.jna*\" and location type: 2" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6ae6ea09" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.nio.channels>, type<filechannel*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<filechannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.channels>, type<filechannel*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.nio.channels.FileChannel*\" and location type: 8" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.nio.channels.FileChannel*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="rule returned" ruleID=local-storage-00001 +time="2026-05-20T08:21:03Z" level=info msg="processed rule" logger=process-rule processed=124 ruleID=local-storage-00001 total=309 +time="2026-05-20T08:21:03Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:03Z" level=info msg="rule returned" ruleID=openliberty-logging-00002 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@37fe6294" provider=java +time="2026-05-20T08:21:03Z" level=info msg="processed rule" logger=process-rule processed=125 ruleID=openliberty-logging-00002 total=309 +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ProcessBuilder\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.lang>, type<ProcessBuilder> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<ProcessBuilder>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.lang>, type<ProcessBuilder>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ProcessBuilder\" and location type: 8" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.jna*\",\"Location\":\"VARIABLE_DECLARATION\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6247c69c" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeReferencePattern: qualification<com.sun>, type<jna*>, pattern match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.jna*\" and location type: 9" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="rule returned" ruleID=jni-native-code-00000 +time="2026-05-20T08:21:03Z" level=info msg="processed rule" logger=process-rule processed=126 ruleID=jni-native-code-00000 total=309 +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.nio.channels.FileLock*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@56dcfdfb" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.nio.channels>, type<filelock*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<filelock*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.channels>, type<filelock*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.nio.channels.FileLock*\" and location type: 8" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="rule returned" ruleID=google-gcr-to-azure-acr-01000 +time="2026-05-20T08:21:03Z" level=info msg="processed rule" logger=process-rule processed=127 ruleID=google-gcr-to-azure-acr-01000 total=309 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@bb7f38b" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.apache.commons.io>, type<input*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<input*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.apache.commons.io>, type<input*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.apache.commons.io.input*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.apache.commons.io.input*\" and location type: 8" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4f99daab" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: SuperInterfaceReferencePattern: <ProcessBuilder>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ProcessBuilder\" and location type: 1" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ProcessBuilder\",\"Location\":\"INHERITANCE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@13b696e2" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.nio>, type<file*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<file*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio>, type<file*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.nio.file*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.nio.file*\" and location type: 8" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1330af10" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.apache.commons.io>, type<output*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<output*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.apache.commons.io>, type<output*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.apache.commons.io.output*\" and location type: 8" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.apache.commons.io.output*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ProcessBuilder\",\"Location\":\"VARIABLE_DECLARATION\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3554814c" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeReferencePattern: qualification<java.lang>, type<ProcessBuilder>, exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ProcessBuilder\" and location type: 9" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5cfa6f7" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.nio.file.files.createtempfile(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.nio.file.files.createtempdirectory(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:03Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:03Z" level=info msg="rule returned" ruleID=jca-00000 +time="2026-05-20T08:21:03Z" level=info msg="processed rule" logger=process-rule processed=128 ruleID=jca-00000 total=309 +time="2026-05-20T08:21:03Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.nio.file.Files.(createTempFile|createTempDirectory)\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.nio.file.Files.(createTempFile|createTempDirectory)\" and location type: 2" provider=java +time="2026-05-20T08:21:03Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ProcessHandle\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1ab362fb" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.lang.ProcessHandle(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ProcessHandle\" and location type: 3" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@538d7fec" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: org.apache.commons.io.fileutils.gettempdirectory(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.apache.commons.io.FileUtils.getTempDirectory\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.apache.commons.io.FileUtils.getTempDirectory\" and location type: 2" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=local-storage-00006 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=129 ruleID=local-storage-00006 total=309 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@203e7fef" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.nio.file.paths.get(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.nio.file.Paths.get\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.nio.file.Paths.get\" and location type: 2" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ProcessHandle\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@28b79e21" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.lang>, type<ProcessHandle> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<ProcessHandle>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.lang>, type<ProcessHandle>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ProcessHandle\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@72620236" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.apache.*log4j>, type<*fileappender*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<*fileappender*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.apache.*log4j>, type<*fileappender*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.apache.*log4j.*FileAppender*\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.apache.*log4j.*FileAppender*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@68963cc" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.nio.file>, type<files*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<files*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.file>, type<files*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.nio.file>, type<paths*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<paths*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.file>, type<paths*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.nio.file.(Files|Paths)*\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.nio.file.(Files|Paths)*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=local-storage-00005 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=130 ruleID=local-storage-00005 total=309 +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ProcessHandle\",\"Location\":\"INHERITANCE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@24c431b0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: SuperInterfaceReferencePattern: <ProcessHandle>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ProcessHandle\" and location type: 1" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.logging.FileHandler*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6532d81" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ProcessHandle\",\"Location\":\"VARIABLE_DECLARATION\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=jni-native-code-00001 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=131 ruleID=jni-native-code-00001 total=309 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.util.logging>, type<filehandler*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<filehandler*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.util.logging>, type<filehandler*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.logging.FileHandler*\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1a046f1c" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeReferencePattern: qualification<java.lang>, type<ProcessHandle>, exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ProcessHandle\" and location type: 9" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@448635fc" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.util.logging>, type<sockethandler*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<sockethandler*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.util.logging>, type<sockethandler*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.logging.SocketHandler*\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.logging.SocketHandler*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=logging-0001 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=132 ruleID=logging-0001 total=309 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=logging-0003 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=133 ruleID=logging-0003 total=309 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=logging-0004 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=134 ruleID=logging-0004 total=309 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=logging-0005 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=135 ruleID=logging-0005 total=309 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@41cad56d" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<ch.qos.logback.core>, type<FileAppender> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<FileAppender>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<ch.qos.logback.core>, type<FileAppender>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"ch.qos.logback.core.FileAppender\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"ch.qos.logback.core.FileAppender\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"(javax|jakarta).mail*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5e6ad7f0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <javax.mail*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <javax.mail*>, pattern match, case insensitive, generic full match, fine grain: none | PackageDeclarationPattern: <jakarta.mail*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <jakarta.mail*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"(javax|jakarta).mail*\" and location type: 11" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.pmw.tinylog.writers.FileWriter\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=logging-0000 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=136 ruleID=logging-0000 total=309 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@672f2fae" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.pmw.tinylog.writers>, type<FileWriter> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<FileWriter>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.pmw.tinylog.writers>, type<FileWriter>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.pmw.tinylog.writers.FileWriter\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.mail*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@12f3df62" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.sun.mail*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.sun.mail*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.mail*\" and location type: 11" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@50511ec" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.servlet.http.httpsession.setattribute(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.servlet.http.HttpSession.setAttribute\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.servlet.http.HttpSession.setAttribute\" and location type: 2" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3237a211" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <org.simplejavamail*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <org.simplejavamail*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.simplejavamail*\" and location type: 11" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.simplejavamail*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.apache.commons.mail*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.servlet.http.HttpSession.putValue\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7bb92877" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <org.apache.commons.mail*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <org.apache.commons.mail*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.apache.commons.mail*\" and location type: 11" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4c67c936" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.servlet.http.httpsession.putvalue(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.servlet.http.HttpSession.putValue\" and location type: 2" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1e850593" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: jakarta.servlet.http.httpsession.setattribute(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"jakarta.servlet.http.HttpSession.setAttribute\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"jakarta.servlet.http.HttpSession.setAttribute\" and location type: 2" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=local-storage-00004 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=137 ruleID=local-storage-00004 total=309 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@77df3ffe" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: jakarta.servlet.http.httpsession.putvalue(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=openliberty-jms-00004 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=138 ruleID=openliberty-jms-00004 total=309 +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"jakarta.servlet.http.HttpSession.putValue\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"jakarta.servlet.http.HttpSession.putValue\" and location type: 2" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@38689f21" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.net>, type<socket*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<socket*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.net>, type<socket*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.net>, type<multicastsocket*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<multicastsocket*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.net>, type<multicastsocket*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.net>, type<datagramsocket*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<datagramsocket*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.net>, type<datagramsocket*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.net>, type<inetsocketaddress*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<inetsocketaddress*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.net>, type<inetsocketaddress*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.net.(Socket|MulticastSocket|DatagramSocket|InetSocketAddress)*\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.net.(Socket|MulticastSocket|DatagramSocket|InetSocketAddress)*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@36c6771d" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.nio.channels.(NetworkChannel|MulticastChannel|DatagramChannel|AsynchronousSocketChannel|SocketChannel)*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=socket-communication-00001 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=139 ruleID=socket-communication-00001 total=309 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.nio.channels>, type<networkchannel*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<networkchannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.channels>, type<networkchannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.nio.channels>, type<multicastchannel*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<multicastchannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.channels>, type<multicastchannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.nio.channels>, type<datagramchannel*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<datagramchannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.channels>, type<datagramchannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.nio.channels>, type<asynchronoussocketchannel*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<asynchronoussocketchannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.channels>, type<asynchronoussocketchannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.nio.channels>, type<socketchannel*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<socketchannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.channels>, type<socketchannel*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.nio.channels.(NetworkChannel|MulticastChannel|DatagramChannel|AsynchronousSocketChannel|SocketChannel)*\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@77ef5493" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.servlet.http>, type<HttpSession> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<HttpSession>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.servlet.http>, type<HttpSession>, exact match, case sensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<jakarta.servlet.http>, type<HttpSession> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<HttpSession>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<jakarta.servlet.http>, type<HttpSession>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"(javax|jakarta).servlet.http.HttpSession\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"(javax|jakarta).servlet.http.HttpSession\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=session-00001 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=140 ruleID=session-00001 total=309 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=web-11000 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=141 ruleID=web-11000 total=309 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.net.ServerSocket*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@353083e0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.net>, type<serversocket*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<serversocket*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.net>, type<serversocket*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.net.ServerSocket*\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@49dd83f0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax>, type<swing*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<swing*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax>, type<swing*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.swing*\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.swing*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=web-10000 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=142 ruleID=web-10000 total=309 +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.nio.channels.AsynchronousServerSocketChannel*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4c266b49" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.nio.channels>, type<asynchronousserversocketchannel*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<asynchronousserversocketchannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.channels>, type<asynchronousserversocketchannel*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.nio.channels.AsynchronousServerSocketChannel*\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@41e0f592" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.xml.parsers.documentbuilder.parse(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.xml.parsers.DocumentBuilder.parse\" and location type: 2" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.xml.parsers.DocumentBuilder.parse\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.nio.channels.ServerSocketChannel*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=socket-communication-00000 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=143 ruleID=socket-communication-00000 total=309 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@707e51cd" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.nio.channels>, type<serversocketchannel*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<serversocketchannel*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.nio.channels>, type<serversocketchannel*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.nio.channels.ServerSocketChannel*\" and location type: 8" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=localhost-http-00001 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=144 ruleID=localhost-http-00001 total=309 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=localhost-jdbc-00002 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=145 ruleID=localhost-jdbc-00002 total=309 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=localhost-ws-00003 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=146 ruleID=localhost-ws-00003 total=309 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=hardcoded-urls-00001 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=147 ruleID=hardcoded-urls-00001 total=309 +time="2026-05-20T08:21:04Z" level=info msg="rule returned" ruleID=hardcoded-urls-00002 +time="2026-05-20T08:21:04Z" level=info msg="processed rule" logger=process-rule processed=148 ruleID=hardcoded-urls-00002 total=309 +time="2026-05-20T08:21:04Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@55198e31" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:04Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<sun>, type<net*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<net*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<sun>, type<net*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:05Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.net*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:05Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.servlet.http.HttpServletRequest\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:05Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.jna.platform.win32.Advapi32Util\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:05Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.jna.platform.win32.WinReg\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.net*\" and location type: 8" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2a9adbf8" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.servlet.http>, type<HttpServletRequest> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<HttpServletRequest>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.servlet.http>, type<HttpServletRequest>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.servlet.http.HttpServletRequest\" and location type: 8" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6c90e75c" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun.jna.platform.win32>, type<Advapi32Util> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Advapi32Util>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun.jna.platform.win32>, type<Advapi32Util>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.jna.platform.win32.Advapi32Util\" and location type: 8" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6e62333a" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun.jna.platform.win32>, type<WinReg> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<WinReg>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun.jna.platform.win32>, type<WinReg>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.jna.platform.win32.WinReg\" and location type: 8" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@779340c1" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: com.sun.jna.platform.win32.advapi32util.registrygetstringvalue(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.jna.platform.win32.Advapi32Util.registryGetStringValue\" and location type: 2" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:05Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.jna.platform.win32.Advapi32Util.registryGetStringValue\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:05Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.apache.http.impl.client.HttpClients\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@baa10d0" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.apache.http.impl.client>, type<HttpClients> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<HttpClients>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.apache.http.impl.client>, type<HttpClients>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.apache.http.impl.client.HttpClients\" and location type: 8" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:05Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.jna.platform.win32.Advapi32Util.registrySetStringValue\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:05Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:05Z" level=info msg="rule returned" ruleID=windows-registry-00000 +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@606bbcfe" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: com.sun.jna.platform.win32.advapi32util.registrysetstringvalue(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.jna.platform.win32.Advapi32Util.registrySetStringValue\" and location type: 2" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:05Z" level=info msg="processed rule" logger=process-rule processed=149 ruleID=windows-registry-00000 total=309 +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1f6fa82a" provider=java +time="2026-05-20T08:21:05Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.apache.http.impl.client.CloseableHttpClient\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:05Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:05Z" level=info msg="rule returned" ruleID=unsecure-network-protocol-00000 +time="2026-05-20T08:21:05Z" level=info msg="processed rule" logger=process-rule processed=150 ruleID=unsecure-network-protocol-00000 total=309 +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.apache.http.impl.client>, type<CloseableHttpClient> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<CloseableHttpClient>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.apache.http.impl.client>, type<CloseableHttpClient>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.apache.http.impl.client.CloseableHttpClient\" and location type: 8" provider=java +time="2026-05-20T08:21:05Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:05Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:05Z" level=info msg="rule returned" ruleID=localhost-00004 +time="2026-05-20T08:21:05Z" level=info msg="processed rule" logger=process-rule processed=151 ruleID=localhost-00004 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=logging-0002 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=152 ruleID=logging-0002 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=ant-build-tool-00001 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=153 ruleID=ant-build-tool-00001 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=webform-auth-00000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=154 ruleID=webform-auth-00000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=jakarta-auth-00001 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=155 ruleID=jakarta-auth-00001 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=jakarta-database-00001 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=156 ruleID=jakarta-database-00001 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=jakarta-database-00002 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=157 ruleID=jakarta-database-00002 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=jakarta-database-00003 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=158 ruleID=jakarta-database-00003 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=jakarta-service-00001 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=159 ruleID=jakarta-service-00001 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=jakarta-service-00002 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=160 ruleID=jakarta-service-00002 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=external-config-00000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=161 ruleID=external-config-00000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=dockerfile-00000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=162 ruleID=dockerfile-00000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=dockerfile-00010 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=163 ruleID=dockerfile-00010 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=dockerfile-00020 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=164 ruleID=dockerfile-00020 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=dockerfile-00030 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=165 ruleID=dockerfile-00030 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7217664e" provider=java +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.springframework>, type<mail*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<mail*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.springframework>, type<mail*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.springframework.mail*\" and location type: 8" provider=java +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:06Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.springframework.mail*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2960d44c" provider=java +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<jakarta.validation.constraints>, type<Email> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Email>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<jakarta.validation.constraints>, type<Email>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"jakarta.validation.constraints.Email\" and location type: 4" provider=java +time="2026-05-20T08:21:06Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:06Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"jakarta.validation.constraints.Email\",\"Location\":\"ANNOTATION\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=mail-00000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=166 ruleID=mail-00000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=clustering-00000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=167 ruleID=clustering-00000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=cra-weak-crypto-md5-01000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=168 ruleID=cra-weak-crypto-md5-01000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=cra-weak-crypto-sha1-02000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=169 ruleID=cra-weak-crypto-sha1-02000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=cra-weak-crypto-des-03000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=170 ruleID=cra-weak-crypto-des-03000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=cra-weak-crypto-rc4-04000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=171 ruleID=cra-weak-crypto-rc4-04000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=cra-weak-crypto-ecb-05000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=172 ruleID=cra-weak-crypto-ecb-05000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=cra-weak-crypto-password-hash-07000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=173 ruleID=cra-weak-crypto-password-hash-07000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="rule returned" ruleID=cra-weak-crypto-blowfish-06000 +time="2026-05-20T08:21:06Z" level=info msg="processed rule" logger=process-rule processed=174 ruleID=cra-weak-crypto-blowfish-06000 total=309 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:06Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=cra-hardcoded-credential-password-01000 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=175 ruleID=cra-hardcoded-credential-password-01000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=cra-hardcoded-credential-apikey-02000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=176 ruleID=cra-hardcoded-credential-apikey-02000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=cra-insecure-tls-hostname-verify-04000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=177 ruleID=cra-insecure-tls-hostname-verify-04000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.apache.http.conn.ssl.NoopHostnameVerifier\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=cra-insecure-tls-protocol-01000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=178 ruleID=cra-insecure-tls-protocol-01000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.apache.http.conn.ssl.AllowAllHostnameVerifier\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@14d111d2" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.apache.http.conn.ssl>, type<NoopHostnameVerifier> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<NoopHostnameVerifier>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.apache.http.conn.ssl>, type<NoopHostnameVerifier>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.apache.http.conn.ssl.NoopHostnameVerifier\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@761dc59a" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<org.apache.http.conn.ssl>, type<AllowAllHostnameVerifier> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<AllowAllHostnameVerifier>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<org.apache.http.conn.ssl>, type<AllowAllHostnameVerifier>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.apache.http.conn.ssl.AllowAllHostnameVerifier\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3ff1e801" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.util>, type<Random> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Random>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.util>, type<Random>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.Random\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.Random\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@101c9907" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.util.random*(...), pattern match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.Random*\" and location type: 3" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.Random*\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=cra-insecure-random-math-02000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=179 ruleID=cra-insecure-random-math-02000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=cra-insecure-tls-trust-all-03000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=180 ruleID=cra-insecure-tls-trust-all-03000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=cra-insecure-random-01000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=181 ruleID=cra-insecure-random-01000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@cdf4557" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun.java.browser.plugin2>, type<dom*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<dom*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun.java.browser.plugin2>, type<dom*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.java.browser.plugin2.DOM*\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=cra-hardcoded-credential-crypto-key-05000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=182 ruleID=cra-hardcoded-credential-crypto-key-05000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.java.browser.plugin2.DOM*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.concurrent.ThreadLocalRandom\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@14f67043" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.util.concurrent>, type<ThreadLocalRandom> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<ThreadLocalRandom>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.util.concurrent>, type<ThreadLocalRandom>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.concurrent.ThreadLocalRandom\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=cra-insecure-random-threadlocal-03000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=183 ruleID=cra-insecure-random-threadlocal-03000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@24f7333c" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javafx.application.hostservices.getwebcontext(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javafx.application.HostServices.getWebContext\" and location type: 2" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javafx.application.HostServices.getWebContext\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-10-deprecate-javafx-00000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=184 ruleID=java-10-deprecate-javafx-00000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@50d74204" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.runtime.getlocalizedinputstream(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Runtime.getLocalizedInputStream\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Runtime.getLocalizedInputStream\" and location type: 2" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.plugin.dom.DOMObject*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@265450b4" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<sun.plugin.dom>, type<domobject*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<domobject*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<sun.plugin.dom>, type<domobject*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.plugin.dom.DOMObject*\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-10-deprecate-dom-00000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=185 ruleID=java-10-deprecate-dom-00000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1075855" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.securitymanager.getincheck(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.lang.securitymanager.classdepth(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.lang.securitymanager.classloaderdepth(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.lang.securitymanager.currentclassloader(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.lang.securitymanager.currentloadedclass(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.lang.securitymanager.inclass(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.lang.securitymanager.inclassloader(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.SecurityManager.(getInCheck|classDepth|classLoaderDepth|currentClassLoader|currentLoadedClass|inClass|inClassLoader)\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.SecurityManager.(getInCheck|classDepth|classLoaderDepth|currentClassLoader|currentLoadedClass|inClass|inClassLoader)\" and location type: 2" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-10-deprecate-security-00000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=186 ruleID=java-10-deprecate-security-00000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1cf4f59a" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun.security>, type<auth*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<auth*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun.security>, type<auth*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.security.auth*\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.security.auth*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-10-deprecate-security-00001 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=187 ruleID=java-10-deprecate-security-00001 total=309 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@76595362" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.runtime.getlocalizedoutputstream(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Runtime.getLocalizedOutputStream\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-10-deprecate-runtime-00000 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Runtime.getLocalizedOutputStream\" and location type: 2" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=188 ruleID=java-10-deprecate-runtime-00000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@728c7ced" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.security>, type<Certificate> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Certificate>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<Certificate>, exact match, case sensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.security>, type<Identity> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Identity>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<Identity>, exact match, case sensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.security>, type<IdentityScope> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<IdentityScope>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<IdentityScope>, exact match, case sensitive, generic full match, fine grain: none | TypeDeclarationPattern: qualification<java.security>, type<Signer> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Signer>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<Signer>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.(Certificate|Identity|IdentityScope|Signer)\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.(Certificate|Identity|IdentityScope|Signer)\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@49f24719" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.security>, type<acl*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<acl*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<acl*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-10-deprecate-security-00002 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=189 ruleID=java-10-deprecate-security-00002 total=309 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=azure-java-sdk-legacy-migration-01000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=190 ruleID=azure-java-sdk-legacy-migration-01000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.acl*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.acl*\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-10-deprecate-security-00003 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=191 ruleID=java-10-deprecate-security-00003 total=309 +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.security.auth.Policy*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@72112398" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.security.auth>, type<policy*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<policy*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.security.auth>, type<policy*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.security.auth.Policy*\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-10-deprecate-security-00004 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=192 ruleID=java-10-deprecate-security-00004 total=309 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4e6facfb" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun.awt>, type<awtutilities*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<awtutilities*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun.awt>, type<awtutilities*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.awt.AWTUtilities*\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.awt.AWTUtilities*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-11-deprecate-awt-00000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=193 ruleID=java-11-deprecate-awt-00000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5f15cacf" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <javax.activity*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <javax.activity*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.activity*\" and location type: 11" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.activity*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@48494bb" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <javax.annotation*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <javax.annotation*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.annotation*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-11-deprecate-javaee-00001 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=194 ruleID=java-11-deprecate-javaee-00001 total=309 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.annotation*\" and location type: 11" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-11-deprecate-property-00000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=195 ruleID=java-11-deprecate-property-00000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-11-deprecate-property-00001 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=196 ruleID=java-11-deprecate-property-00001 total=309 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4added85" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <javax.activation*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <javax.activation*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.activation*\" and location type: 11" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.activation*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-11-deprecate-javaee-00000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=197 ruleID=java-11-deprecate-javaee-00000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.jar.Pack200\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@13d738ab" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.util.jar>, type<Pack200> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Pack200>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.util.jar>, type<Pack200>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.jar.Pack200\" and location type: 8" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="rule returned" ruleID=java-11-deprecate-pack-00000 +time="2026-05-20T08:21:07Z" level=info msg="processed rule" logger=process-rule processed=198 ruleID=java-11-deprecate-pack-00000 total=309 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@204eec1c" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.awt.font.getpeer(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.awt.Font.getPeer\" and location type: 2" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@63046934" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <javax.rmi*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <javax.rmi*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.rmi*\" and location type: 11" provider=java +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.awt.Font.getPeer\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.rmi*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@46101114" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:07Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.securitymanager.checkawteventqueueaccess(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.lang.securitymanager.checksystemclipboardaccess(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.lang.securitymanager.checktoplevelwindow(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=cra-insecure-tls-cipher-suite-05000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=199 ruleID=cra-insecure-tls-cipher-suite-05000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.SecurityManager.(checkAwtEventQueueAccess|checkSystemClipboardAccess|checkTopLevelWindow)\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.SecurityManager.(checkAwtEventQueueAccess|checkSystemClipboardAccess|checkTopLevelWindow)\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-11-deprecate-security-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=200 ruleID=java-11-deprecate-security-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6c287b1d" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.securitymanager.checkmemberaccess(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.SecurityManager.checkMemberAccess\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.SecurityManager.checkMemberAccess\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-11-deprecate-security-00001 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=201 ruleID=java-11-deprecate-security-00001 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3bd14488" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: org.ietf.jgss.gsscontext.initseccontext(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: org.ietf.jgss.gsscontext.acceptseccontext(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: org.ietf.jgss.gsscontext.wrap(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: org.ietf.jgss.gsscontext.unwrap(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: org.ietf.jgss.gsscontext.getmic(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: org.ietf.jgss.gsscontext.verifymic(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"org.ietf.jgss.GSSContext.(initSecContext|acceptSecContext|wrap|unwrap|getMIC|verifyMIC)\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"org.ietf.jgss.GSSContext.(initSecContext|acceptSecContext|wrap|unwrap|getMIC|verifyMIC)\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-11-deprecate-stream-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=202 ruleID=java-11-deprecate-stream-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7bdcc70f" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.awt.component.getpeer(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=cra-hardcoded-credential-config-03000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=203 ruleID=cra-hardcoded-credential-config-03000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.awt.Component.getPeer\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.awt.Component.getPeer\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-11-deprecate-peer-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=204 ruleID=java-11-deprecate-peer-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.corba*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@28ac542" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.sun.corba*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.sun.corba*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.corba*\" and location type: 11" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-11-deprecate-corba-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=205 ruleID=java-11-deprecate-corba-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3d9a0b99" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.thread.stop(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=cra-hardcoded-credential-default-pwd-04000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=206 ruleID=cra-hardcoded-credential-default-pwd-04000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Thread.stop\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Thread.stop\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7794d7f2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: sun.misc.unsafe.defineclass(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.misc.Unsafe.defineClass\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.misc.Unsafe.defineClass\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-11-deprecate-unsafe-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=207 ruleID=java-11-deprecate-unsafe-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.misc.Unsafe*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1a3fcc5a" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<sun.misc>, type<unsafe*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<unsafe*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<sun.misc>, type<unsafe*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.misc.Unsafe*\" and location type: 8" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-11-deprecate-unsafe-00001 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=208 ruleID=java-11-deprecate-unsafe-00001 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@349fd49e" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<sun.misc>, type<base64encoder*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<base64encoder*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<sun.misc>, type<base64encoder*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.misc.BASE64Encoder*\" and location type: 8" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.misc.BASE64Encoder*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"runFinalizersOnExit\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-removals-00010 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=209 ruleID=java-removals-00010 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@12e9ecfa" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: runfinalizersonexit(...), exact match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"runFinalizersOnExit\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.java.browser.plugin2.DOM*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@43938212" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun.java.browser.plugin2>, type<dom*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<dom*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun.java.browser.plugin2>, type<dom*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.java.browser.plugin2.DOM*\" and location type: 8" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javafx.scene.*Builder\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-javafx-00000 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@27aacb26" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javafx.scene>, type<*builder> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<*builder>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javafx.scene>, type<*builder>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javafx.scene.*Builder\" and location type: 8" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=210 ruleID=java-9-deprecate-javafx-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6ddbd069" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.thread.destroy(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-property-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=211 ruleID=java-9-deprecate-property-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-property-00001 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=212 ruleID=java-9-deprecate-property-00001 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Thread.destroy\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Thread.destroy\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-11-deprecate-thread-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=213 ruleID=java-11-deprecate-thread-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1ed6ed22" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.logging.logmanager.addpropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.logging.LogManager.addPropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.logging.LogManager.addPropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3f740bf4" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.jar.pack200.packer.addpropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.jar.Pack200.Packer.addPropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.jar.Pack200.Packer.addPropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7b7db765" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<sun.misc>, type<base64decoder*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<base64decoder*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<sun.misc>, type<base64decoder*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.misc.BASE64Decoder*\" and location type: 8" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.misc.BASE64Decoder*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-removals-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=214 ruleID=java-removals-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.awt.peer*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@51ca9953" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <java.awt.peer*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <java.awt.peer*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.awt.peer*\" and location type: 11" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5573dd6e" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<sun.plugin.dom>, type<domobject*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<domobject*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<sun.plugin.dom>, type<domobject*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.plugin.dom.DOMObject*\" and location type: 8" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.plugin.dom.DOMObject*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-dom-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=215 ruleID=java-9-deprecate-dom-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.reflect.Reflection\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4ac7579f" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<sun.reflect>, type<Reflection> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Reflection>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<sun.reflect>, type<Reflection>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.reflect.Reflection\" and location type: 8" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5c17173d" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<sun.reflect>, type<callersensitive*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<callersensitive*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<sun.reflect>, type<callersensitive*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.reflect.CallerSensitive*\" and location type: 8" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.reflect.CallerSensitive*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@59120ded" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.logging.logmanager.removepropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.logging.LogManager.removePropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.logging.LogManager.removePropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-log-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=216 ruleID=java-9-deprecate-log-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4f34b0a7" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.jar.pack200.packer.removepropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.jar.Pack200.Packer.removePropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.jar.Pack200.Packer.removePropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5476b30e" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun.security.auth.callback>, type<dialogcallbackhandler*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<dialogcallbackhandler*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun.security.auth.callback>, type<dialogcallbackhandler*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.security.auth.callback.DialogCallbackHandler*\" and location type: 8" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.security.auth.callback.DialogCallbackHandler*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-security-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=217 ruleID=java-9-deprecate-security-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@61a29da1" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <java.awt.dnd.peer*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <java.awt.dnd.peer*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.awt.dnd.peer*\" and location type: 11" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.awt.dnd.peer*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-peer-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=218 ruleID=java-9-deprecate-peer-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@62e696ba" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <java.security.acl*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <java.security.acl*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.acl*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.acl*\" and location type: 11" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-security-00001 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=219 ruleID=java-9-deprecate-security-00001 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@83db3c9" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: sun.reflect.reflection.getcallerclass(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.reflect.Reflection.getCallerClass\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.reflect.Reflection.getCallerClass\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-reflect-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=220 ruleID=java-9-deprecate-reflect-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-url-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=221 ruleID=java-9-deprecate-url-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.reflect.CallerSensitive*\",\"Location\":\"ANNOTATION\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2fcb1f1f" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<sun.reflect>, type<callersensitive*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<callersensitive*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<sun.reflect>, type<callersensitive*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.reflect.CallerSensitive*\" and location type: 4" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-reflect-00010 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=222 ruleID=java-9-deprecate-reflect-00010 total=309 +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.security.cert*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-security-00002 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@527c4772" provider=java +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=223 ruleID=java-9-deprecate-security-00002 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <javax.security.cert*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <javax.security.cert*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.security.cert*\" and location type: 11" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@c6ac57c" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.jar.pack200.unpacker.addpropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.jar.Pack200.Unpacker.addPropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.jar.Pack200.Unpacker.addPropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.tracing\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2c3484b3" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.sun.tracing>, exact match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.sun.tracing>, exact match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.tracing\" and location type: 11" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5b7045cd" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: sun.misc.unsafe.trymonitorenter(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: sun.misc.unsafe.monitorenter(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: sun.misc.unsafe.monitorexit(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.misc.Unsafe.(tryMonitorEnter|monitorEnter|monitorExit)\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-unsafe-00000 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=224 ruleID=java-9-deprecate-unsafe-00000 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.misc.Unsafe.(tryMonitorEnter|monitorEnter|monitorExit)\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6b87ce06" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: sun.misc.unsafe.defineclass(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.misc.Unsafe.defineClass\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.misc.Unsafe.defineClass\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:08Z" level=info msg="rule returned" ruleID=java-9-deprecate-unsafe-00001 +time="2026-05-20T08:21:08Z" level=info msg="processed rule" logger=process-rule processed=225 ruleID=java-9-deprecate-unsafe-00001 total=309 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@311ca72f" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.io.fileinputstream.finalize(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:08Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.io.FileInputStream.finalize\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.io.FileInputStream.finalize\" and location type: 2" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3905bca3" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:08Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.zipfile.finalize(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.ZipFile.finalize\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.ZipFile.finalize\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.awt.SecurityWarning\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6002d863" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun.awt>, type<SecurityWarning> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<SecurityWarning>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun.awt>, type<SecurityWarning>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.awt.SecurityWarning\" and location type: 8" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-12-deprecate-security-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=226 ruleID=java-12-deprecate-security-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@35a0cd9b" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.jar.pack200.unpacker.removepropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.jar.Pack200.Unpacker.removePropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.jar.Pack200.Unpacker.removePropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-9-deprecate-pack-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=227 ruleID=java-9-deprecate-pack-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-14-deprecate-property-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=228 ruleID=java-14-deprecate-property-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.tracing.dtrace\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-9-deprecate-tracing-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=229 ruleID=java-9-deprecate-tracing-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@61d121df" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.sun.tracing.dtrace>, exact match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.sun.tracing.dtrace>, exact match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.tracing.dtrace\" and location type: 11" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@75a579e2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.runtime.traceinstructions(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Runtime.traceInstructions\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Runtime.traceInstructions\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@39276f5" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <javax.security.cert*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <javax.security.cert*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.security.cert*\" and location type: 11" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.security.cert*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-13-deprecate-security-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=230 ruleID=java-13-deprecate-security-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@30edbf09" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.io.fileoutputstream.finalize(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-9-deprecate-agent-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=231 ruleID=java-9-deprecate-agent-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=eclipse-00002 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=232 ruleID=eclipse-00002 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.io.FileOutputStream.finalize\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.io.FileOutputStream.finalize\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-12-deprecate-finalize-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=233 ruleID=java-12-deprecate-finalize-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@585abf12" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.inflator.finalize(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.Inflator.finalize\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.Inflator.finalize\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@66eb792" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.util.jar>, type<Pack200> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Pack200>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.util.jar>, type<Pack200>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.util.jar.pack200(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.util.jar.Pack200(...), exact match, case sensitive, generic erasure match, fine grain: none | TypeDeclarationPattern: qualification<java.util.jar.Pack200>, type<Packer> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Packer>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.util.jar.Pack200>, type<Packer>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.util.jar.pack200.packer(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.util.jar.Pack200.Packer(...), exact match, case sensitive, generic erasure match, fine grain: none | TypeDeclarationPattern: qualification<java.util.jar.Pack200>, type<Unpacker> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Unpacker>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.util.jar.Pack200>, type<Unpacker>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.util.jar.pack200.unpacker(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.util.jar.Pack200.Unpacker(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.jar.(Pack200|Pack200.Packer|Pack200.Unpacker)\" and location type: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.jar.(Pack200|Pack200.Packer|Pack200.Unpacker)\",\"Location\":\"\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-14-deprecate-pack-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=234 ruleID=java-14-deprecate-pack-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-15-deprecate-ssl-00001 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=235 ruleID=java-15-deprecate-ssl-00001 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@463c281e" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: netscape.javascript.jsobject.getwindow(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"netscape.javascript.JSObject.getWindow\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"netscape.javascript.JSObject.getWindow\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-14-deprecate-property-00001 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=236 ruleID=java-14-deprecate-property-00001 total=309 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@359dc56c" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <java.security.acl*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <java.security.acl*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.acl*\" and location type: 11" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.acl*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-14-deprecate-security-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=237 ruleID=java-14-deprecate-security-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@79690747" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.runtime.tracemethodcalls(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Runtime.traceMethodCalls\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Runtime.traceMethodCalls\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-13-deprecate-runtime-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=238 ruleID=java-13-deprecate-runtime-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2fcedd8f" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.thread.suspend(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Thread.suspend\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Thread.suspend\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@621a187c" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.management.remote.rmi>, type<rmiconnectorserver*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<rmiconnectorserver*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.management.remote.rmi>, type<rmiconnectorserver*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.management.remote.rmi.RMIConnectorServer*\" and location type: 8" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.management.remote.rmi.RMIConnectorServer*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6372e4ce" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.sun.jarsigner.ContentSigner*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.sun.jarsigner.contentsigner*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.jarsigner.ContentSigner*\" and location type: 11" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-15-deprecate-property-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=239 ruleID=java-15-deprecate-property-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.jarsigner.ContentSigner*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-15-deprecate-signer-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=240 ruleID=java-15-deprecate-signer-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6db516d0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.net.ssl.sslsession.getpeercertificatechain(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.net.ssl.SSLSession.getPeerCertificateChain\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-15-deprecate-ssl-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=241 ruleID=java-15-deprecate-ssl-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.net.ssl.SSLSession.getPeerCertificateChain\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3be18315" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.deflater.finalize(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.Deflater.finalize\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.Deflater.finalize\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-12-deprecate-finalize-00001 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=242 ruleID=java-12-deprecate-finalize-00001 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@18329835" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.security.cert.x509certificate.getissuerdn(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.security.cert.x509certificate.getsubjectdn(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.cert.X509Certificate.(getIssuerDN|getSubjectDN)\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.cert.X509Certificate.(getIssuerDN|getSubjectDN)\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@829a66e" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.destroy(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.destroy\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.destroy\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3ac286ef" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <java.applet*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <java.applet*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.applet*\" and location type: 11" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.applet*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@d0c5389" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.security>, type<AccessController> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<AccessController>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<AccessController>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.security.accesscontroller(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.security.AccessController(...), exact match, case sensitive, generic erasure match, fine grain: none | TypeDeclarationPattern: qualification<java.security>, type<AccessControlContext> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<AccessControlContext>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<AccessControlContext>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.security.accesscontrolcontext(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.security.AccessControlContext(...), exact match, case sensitive, generic erasure match, fine grain: none | TypeDeclarationPattern: qualification<java.security>, type<AccessControlException> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<AccessControlException>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<AccessControlException>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.security.accesscontrolexception(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.security.AccessControlException(...), exact match, case sensitive, generic erasure match, fine grain: none | TypeDeclarationPattern: qualification<java.security>, type<DomainCombiner> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<DomainCombiner>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<DomainCombiner>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.security.domaincombiner(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.security.DomainCombiner(...), exact match, case sensitive, generic erasure match, fine grain: none | TypeDeclarationPattern: qualification<java.security>, type<Policy> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Policy>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<Policy>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.security.policy(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.security.Policy(...), exact match, case sensitive, generic erasure match, fine grain: none | TypeDeclarationPattern: qualification<java.security>, type<PolicySpi> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<PolicySpi>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<PolicySpi>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.security.policyspi(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.security.PolicySpi(...), exact match, case sensitive, generic erasure match, fine grain: none | TypeDeclarationPattern: qualification<java.security.Policy>, type<Parameters> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Parameters>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security.Policy>, type<Parameters>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.security.policy.parameters(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.security.Policy.Parameters(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.(AccessController|AccessControlContext|AccessControlException|DomainCombiner|Policy|PolicySpi|Policy.Parameters)\" and location type: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.(AccessController|AccessControlContext|AccessControlException|DomainCombiner|Policy|PolicySpi|Policy.Parameters)\",\"Location\":\"\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-17-deprecate-security-manager-00000 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=243 ruleID=java-17-deprecate-security-manager-00000 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@38c5a134" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.thread.resume(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Thread.resume\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Thread.resume\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2d9b1cfb" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.lang>, type<SecurityManager> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<SecurityManager>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.lang>, type<SecurityManager>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.lang.securitymanager(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.lang.SecurityManager(...), exact match, case sensitive, generic erasure match, fine grain: none | TypeDeclarationPattern: qualification<java.rmi>, type<RMISecurityManager> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<RMISecurityManager>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.rmi>, type<RMISecurityManager>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: java.rmi.rmisecuritymanager(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: java.rmi.RMISecurityManager(...), exact match, case sensitive, generic erasure match, fine grain: none | TypeDeclarationPattern: qualification<javax.security.auth>, type<SubjectDomainCombiner> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<SubjectDomainCombiner>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.security.auth>, type<SubjectDomainCombiner>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: javax.security.auth.subjectdomaincombiner(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: javax.security.auth.SubjectDomainCombiner(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"(java.lang.SecurityManager|java.rmi.RMISecurityManager|javax.security.auth.SubjectDomainCombiner)\" and location type: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"(java.lang.SecurityManager|java.rmi.RMISecurityManager|javax.security.auth.SubjectDomainCombiner)\",\"Location\":\"\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-17-deprecate-security-manager-00010 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=244 ruleID=java-17-deprecate-security-manager-00010 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3842d47d" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.system.getsecuritymanager(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.System.getSecurityManager\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.System.getSecurityManager\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5bfef9e9" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.thread.checkaccess(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Thread.checkAccess\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Thread.checkAccess\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-17-deprecate-security-manager-00030 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=245 ruleID=java-17-deprecate-security-manager-00030 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6b6948cf" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.checkaccess(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.checkAccess\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.checkAccess\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-17-deprecate-security-manager-00040 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=246 ruleID=java-17-deprecate-security-manager-00040 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4774c5fa" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.security.cert.x509crl.getissuerdn(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.cert.X509CRL.getIssuerDN\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.cert.X509CRL.getIssuerDN\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6a8867e2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.isdestroyed(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.isDestroyed\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.isDestroyed\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@698a8fbe" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.beans.AppletInitializer\",\"Location\":\"IMPLEMENTS_TYPE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: SuperInterfaceReferencePattern: <AppletInitializer>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.beans.AppletInitializer\" and location type: 5" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2c881ceb" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.logging.logmanager.checkaccess(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.logging.LogManager.checkAccess\" and location type: 2" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:09Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.logging.LogManager.checkAccess\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:09Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:09Z" level=info msg="rule returned" ruleID=java-17-deprecate-security-manager-00050 +time="2026-05-20T08:21:09Z" level=info msg="processed rule" logger=process-rule processed=247 ruleID=java-17-deprecate-security-manager-00050 total=309 +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4ca7e3a4" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:09Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.suspend(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.suspend\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.suspend\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@52d842d9" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.concurrent.executors.privilegedcallable*(...), pattern match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.util.concurrent.executors.privilegedcallableusingcurrentclassloader*(...), pattern match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.util.concurrent.executors.privilegedthreadfactory*(...), pattern match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.concurrent.Executors.(privilegedCallable|privilegedCallableUsingCurrentClassLoader|privilegedThreadFactory)*\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.concurrent.Executors.(privilegedCallable|privilegedCallableUsingCurrentClassLoader|privilegedThreadFactory)*\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-17-deprecate-security-manager-00060 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=248 ruleID=java-17-deprecate-security-manager-00060 total=309 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=lombok-incompatibility-00001 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=249 ruleID=lombok-incompatibility-00001 total=309 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3d62d2ae" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.system.setsecuritymanager(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.System.setSecurityManager\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.System.setSecurityManager\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-17-deprecate-security-manager-00020 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=250 ruleID=java-17-deprecate-security-manager-00020 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@14814969" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.security.auth.subject.doasprivileged*(...), pattern match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: javax.security.auth.subject.getsubject*(...), pattern match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.security.auth.Subject.(doAsPrivileged|getSubject)*\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.security.auth.Subject.(doAsPrivileged|getSubject)*\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-17-deprecate-security-manager-00070 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=251 ruleID=java-17-deprecate-security-manager-00070 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2911bb46" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.net.serversocket.setsocketfactory(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.net.ServerSocket.setSocketFactory\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.net.ServerSocket.setSocketFactory\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5c70565e" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.security.cert.x509certselector.setissuer(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.security.cert.x509certselector.setsubject(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.security.cert.x509certselector.getissuerasstring(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | MethodReferencePattern: java.security.cert.x509certselector.getsubjectasstring(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.cert.X509CertSelector.(setIssuer|setSubject|getIssuerAsString|getSubjectAsString)\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.cert.X509CertSelector.(setIssuer|setSubject|getIssuerAsString|getSubjectAsString)\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@39273d13" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.setdaemon(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.setDaemon\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.setDaemon\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@403c25db" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.swing>, type<JApplet> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<JApplet>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.swing>, type<JApplet>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.swing.JApplet\" and location type: 10" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.swing.JApplet\",\"Location\":\"TYPE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-17-deprecate-applet-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=252 ruleID=java-17-deprecate-applet-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@64d36d11" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: sun.misc.unsafe.defineanonymousclass(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.misc.Unsafe.defineAnonymousClass\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.misc.Unsafe.defineAnonymousClass\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-17-deprecate-unsafe-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=253 ruleID=java-17-deprecate-unsafe-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-18-deprecate-property-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=254 ruleID=java-18-deprecate-property-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3acf0573" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.resume(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.resume\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.resume\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3a00789c" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <java.rmi.activation*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <java.rmi.activation*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.rmi.activation*\" and location type: 11" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.rmi.activation*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=removed-packages-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=255 ruleID=removed-packages-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1bb380fa" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <jdk.nashorn.api.scripting*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <jdk.nashorn.api.scripting*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"jdk.nashorn.api.scripting*\" and location type: 11" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"jdk.nashorn.api.scripting*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@64f7dd78" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.awt.color.icc_profile.finalize(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=cra-insecure-tls-config-02000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=256 ruleID=cra-insecure-tls-config-02000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-18-deprecate-socket-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=257 ruleID=java-18-deprecate-socket-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.awt.color.ICC_Profile.finalize\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.awt.color.ICC_Profile.finalize\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@26d1b808" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.net.socket.setsocketimplfactory(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.net.Socket.setSocketImplFactory\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.net.Socket.setSocketImplFactory\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@42d915ff" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.security.cert.x509crlselector.addissuername(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.cert.X509CRLSelector.addIssuerName\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.cert.X509CRLSelector.addIssuerName\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-16-deprecate-security-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=258 ruleID=java-16-deprecate-security-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6963f454" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.isdaemon(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.isDaemon\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.isDaemon\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@113113fe" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.object.finalize(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Object.finalize\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Object.finalize\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@71f26d0e" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.runtime.exec(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Runtime.exec\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Runtime.exec\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=7 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-18-deprecate-runtime-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=259 ruleID=java-18-deprecate-runtime-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7b0ee822" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.allowthreadsuspension(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.allowThreadSuspension\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.allowThreadSuspension\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-14-deprecate-thread-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=260 ruleID=java-14-deprecate-thread-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@d397243" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.security.auth.subject.doas(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.security.auth.Subject.doAs\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.security.auth.Subject.doAs\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-18-deprecate-security-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=261 ruleID=java-18-deprecate-security-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@329ca323" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <jdk.nashorn.api.tree*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <jdk.nashorn.api.tree*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"jdk.nashorn.api.tree*\" and location type: 11" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"jdk.nashorn.api.tree*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=removed-packages-00010 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=262 ruleID=removed-packages-00010 total=309 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=6 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-19-deprecate-param-spec-00001 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=263 ruleID=java-19-deprecate-param-spec-00001 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4987b190" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.thread.stop(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Thread.stop\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Thread.stop\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-18-deprecate-thread-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=264 ruleID=java-18-deprecate-thread-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6e2bd065" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.awt.image.colormodel.finalize(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.awt.image.ColorModel.finalize\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.awt.image.ColorModel.finalize\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1ad4f701" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.net.datagramsocket.setdatagramsocketimplfactory(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.net.DatagramSocket.setDatagramSocketImplFactory\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.net.DatagramSocket.setDatagramSocketImplFactory\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-17-deprecate-socket-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=265 ruleID=java-17-deprecate-socket-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6c9d59ec" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: sun.misc.unsafe.objectfieldoffset(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.misc.Unsafe.objectFieldOffset\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.misc.Unsafe.objectFieldOffset\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1adc8a54" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.stop(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.stop\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.stop\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-16-deprecate-thread-group-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=266 ruleID=java-16-deprecate-thread-group-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2ac4d992" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.runtime.runfinalization(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Runtime.runFinalization\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Runtime.runFinalization\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@17155f34" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.swing.plaf.basic.BasicMenuItemUI>, type<MouseInputHandler> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<MouseInputHandler>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.swing.plaf.basic.BasicMenuItemUI>, type<MouseInputHandler>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: javax.swing.plaf.basic.basicmenuitemui.mouseinputhandler(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: javax.swing.plaf.basic.BasicMenuItemUI.MouseInputHandler(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.swing.plaf.basic.BasicMenuItemUI.MouseInputHandler\" and location type: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.swing.plaf.basic.BasicMenuItemUI.MouseInputHandler\",\"Location\":\"\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@11c13603" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.util.locale*(...), pattern match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.Locale*\" and location type: 3" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.Locale*\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-19-deprecate-locale-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=267 ruleID=java-19-deprecate-locale-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6fb18045" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.security.spec.pssparameterspec*(...), pattern match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.spec.PSSParameterSpec*\" and location type: 3" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.spec.PSSParameterSpec*\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-19-deprecate-param-spec-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=268 ruleID=java-19-deprecate-param-spec-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6335cc68" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.destroy(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.destroy\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.destroy\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5e64c3c5" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.thread.getid(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Thread.getId\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Thread.getId\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-19-deprecate-thread-00001 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=269 ruleID=java-19-deprecate-thread-00001 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@38d25e42" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.awt.image.indexcolormodel.finalize(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.awt.image.IndexColorModel.finalize\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.awt.image.IndexColorModel.finalize\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-18-deprecate-finalize-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=270 ruleID=java-18-deprecate-finalize-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1ccdd826" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.security.auth.subject.current(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.security.auth.Subject.current\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.security.auth.Subject.current\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@474c17bf" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: sun.misc.unsafe.staticfieldoffset(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.misc.Unsafe.staticFieldOffset\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.misc.Unsafe.staticFieldOffset\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@546c344e" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.management.loading>, type<MLet> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<MLet>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.management.loading>, type<MLet>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.management.loading.MLet\" and location type: 8" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.management.loading.MLet\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2e99c6ab" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.system.runfinalization(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.System.runFinalization\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.System.runFinalization\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5842816b" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.swing.plaf.basic.BasicScrollPaneUI>, type<HSBChangeListener> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<HSBChangeListener>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.swing.plaf.basic.BasicScrollPaneUI>, type<HSBChangeListener>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: javax.swing.plaf.basic.basicscrollpaneui.hsbchangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: javax.swing.plaf.basic.BasicScrollPaneUI.HSBChangeListener(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.swing.plaf.basic.BasicScrollPaneUI.HSBChangeListener\" and location type: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.swing.plaf.basic.BasicScrollPaneUI.HSBChangeListener\",\"Location\":\"\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@57f9bd1e" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.net.URL(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.net.URL\" and location type: 3" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.net.URL\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-20-deprecate-net-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=271 ruleID=java-20-deprecate-net-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@38506d2c" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.thread.suspend(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Thread.suspend\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Thread.suspend\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@378c3bfe" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.isdestroyed(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.isDestroyed\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.isDestroyed\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@c0e092e" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.thread.stop(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Thread.stop\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Thread.stop\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-20-deprecate-thread-00001 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=272 ruleID=java-20-deprecate-thread-00001 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3a0aefd4" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.lang>, type<ThreadDeath> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<ThreadDeath>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.lang>, type<ThreadDeath>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadDeath\" and location type: 8" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadDeath\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-20-deprecate-thread-00002 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=273 ruleID=java-20-deprecate-thread-00002 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@46b1c6c2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.security.auth.subject.callas(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.security.auth.Subject.callAs\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.security.auth.Subject.callAs\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-19-deprecate-thread-00002 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=274 ruleID=java-19-deprecate-thread-00002 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@55482e6" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: sun.misc.unsafe.staticfieldbase(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"sun.misc.Unsafe.staticFieldBase\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"sun.misc.Unsafe.staticFieldBase\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-18-deprecate-unsafe-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=275 ruleID=java-18-deprecate-unsafe-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@349d356f" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.management.loading>, type<MLetContent> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<MLetContent>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.management.loading>, type<MLetContent>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.management.loading.MLetContent\" and location type: 8" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.management.loading.MLetContent\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@218149c" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.enum.finalize(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Enum.finalize\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Enum.finalize\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-18-deprecate-finalize-00001 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=276 ruleID=java-18-deprecate-finalize-00001 total=309 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-21-deprecate-property-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=277 ruleID=java-21-deprecate-property-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7d7771e8" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.swing.plaf.basic.BasicScrollPaneUI>, type<PropertyChangeHandler> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<PropertyChangeHandler>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.swing.plaf.basic.BasicScrollPaneUI>, type<PropertyChangeHandler>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: javax.swing.plaf.basic.basicscrollpaneui.propertychangehandler(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: javax.swing.plaf.basic.BasicScrollPaneUI.PropertyChangeHandler(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.swing.plaf.basic.BasicScrollPaneUI.PropertyChangeHandler\" and location type: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.swing.plaf.basic.BasicScrollPaneUI.PropertyChangeHandler\",\"Location\":\"\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5c159f12" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <java.lang.instrument*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <java.lang.instrument*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.instrument*\" and location type: 11" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.instrument*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-21-deprecate-dynamic-agents-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=278 ruleID=java-21-deprecate-dynamic-agents-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@17effb2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.thread.resume(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Thread.resume\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Thread.resume\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-20-deprecate-thread-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=279 ruleID=java-20-deprecate-thread-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@752384e6" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.setdaemon(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.setDaemon\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.setDaemon\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3d6669f" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.io.file.getcanonicalpath(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.io.File.getCanonicalPath\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.io.File.getCanonicalPath\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5ab872c8" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun.nio.file>, type<sensitivitywatcheventmodifier*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<sensitivitywatcheventmodifier*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun.nio.file>, type<sensitivitywatcheventmodifier*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.nio.file.SensitivityWatchEventModifier*\" and location type: 8" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.nio.file.SensitivityWatchEventModifier*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-21-deprecate-file-00001 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=280 ruleID=java-21-deprecate-file-00001 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6aea159e" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.management.remote.rmi>, type<RMIIIOPServerImpl> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<RMIIIOPServerImpl>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.management.remote.rmi>, type<RMIIIOPServerImpl>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.management.remote.rmi.RMIIIOPServerImpl\" and location type: 8" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.management.remote.rmi.RMIIIOPServerImpl\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-21-deprecate-jmx-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=281 ruleID=java-21-deprecate-jmx-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@55caa972" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.management.remote.jmxconnector.getmbeanserverconnection(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.management.remote.JMXConnector.getMBeanServerConnection\" and location type: 2" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.management.remote.JMXConnector.getMBeanServerConnection\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-21-deprecate-jmx-00001 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=282 ruleID=java-21-deprecate-jmx-00001 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@48a505ff" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.management.loading>, type<MLetMBean> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<MLetMBean>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.management.loading>, type<MLetMBean>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.management.loading.MLetMBean\" and location type: 8" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.management.loading.MLetMBean\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Compiler*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-21-deprecate-property-00001 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=283 ruleID=java-21-deprecate-property-00001 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@51921011" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.lang>, type<compiler*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<compiler*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.lang>, type<compiler*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Compiler*\" and location type: 8" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@6beeb958" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.swing.plaf.basic.BasicScrollPaneUI>, type<ViewportChangeHandler> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<ViewportChangeHandler>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.swing.plaf.basic.BasicScrollPaneUI>, type<ViewportChangeHandler>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: javax.swing.plaf.basic.basicscrollpaneui.viewportchangehandler(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: javax.swing.plaf.basic.BasicScrollPaneUI.ViewportChangeHandler(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.swing.plaf.basic.BasicScrollPaneUI.ViewportChangeHandler\" and location type: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.swing.plaf.basic.BasicScrollPaneUI.ViewportChangeHandler\",\"Location\":\"\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@13be88a" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.sun.jarsigner.ContentSigner>, exact match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.sun.jarsigner.contentsigner>, exact match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.jarsigner.ContentSigner\" and location type: 11" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:10Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.jarsigner.ContentSigner\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:10Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:10Z" level=info msg="rule returned" ruleID=java-21-deprecate-signer-00000 +time="2026-05-20T08:21:10Z" level=info msg="processed rule" logger=process-rule processed=284 ruleID=java-21-deprecate-signer-00000 total=309 +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@47144c69" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:10Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.allowthreadsuspension(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.allowThreadSuspension\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.allowThreadSuspension\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=1 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-21-deprecate-thread-00000 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=285 ruleID=java-21-deprecate-thread-00000 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@30f02d50" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.isdaemon(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.isDaemon\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.isDaemon\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3f35d711" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.io.file.getcanonicalfile(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.io.File.getCanonicalFile\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.io.File.getCanonicalFile\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@352d5ff7" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.io.filereader*(...), pattern match, case insensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.filewriter*(...), pattern match, case insensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.inputstreamreader*(...), pattern match, case insensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.outputstreamwriter*(...), pattern match, case insensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.io.printstream*(...), pattern match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.io.(FileReader|FileWriter|InputStreamReader|OutputStreamWriter|PrintStream)*\" and location type: 3" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.io.(FileReader|FileWriter|InputStreamReader|OutputStreamWriter|PrintStream)*\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-21-deprecate-file-00000 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=286 ruleID=java-21-deprecate-file-00000 total=309 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=utf-8-by-default-00000 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=287 ruleID=utf-8-by-default-00000 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@24319b1c" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: java.util.formatter*(...), pattern match, case insensitive, generic erasure match, fine grain: none | ConstructorCombinedPattern: java.util.scanner*(...), pattern match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.(Formatter|Scanner)*\" and location type: 3" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.(Formatter|Scanner)*\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=utf-8-by-default-00010 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=288 ruleID=utf-8-by-default-00010 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@655a0a60" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.net.urlencoder.encode(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.net.URLEncoder.encode\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.net.URLEncoder.encode\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=utf-8-by-default-00020 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=289 ruleID=utf-8-by-default-00020 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2563d0ef" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.management.loading>, type<PrivateMLet> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<PrivateMLet>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.management.loading>, type<PrivateMLet>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.management.loading.PrivateMLet\" and location type: 8" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.management.loading.PrivateMLet\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-20-deprecate-jmx-00000 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=290 ruleID=java-20-deprecate-jmx-00000 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@105fc729" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.net.urldecoder.decode(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.net.URLDecoder.decode\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.net.URLDecoder.decode\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=utf-8-by-default-00030 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=291 ruleID=utf-8-by-default-00030 total=309 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=2 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-odbc-00001 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=292 ruleID=java-8-deprecate-odbc-00001 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@39ba3dff" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javax.swing.plaf.basic.BasicScrollPaneUI>, type<VSBChangeListener> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<VSBChangeListener>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javax.swing.plaf.basic.BasicScrollPaneUI>, type<VSBChangeListener>, exact match, case sensitive, generic full match, fine grain: none | MethodReferencePattern: javax.swing.plaf.basic.basicscrollpaneui.vsbchangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE | ConstructorCombinedPattern: javax.swing.plaf.basic.BasicScrollPaneUI.VSBChangeListener(...), exact match, case sensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.swing.plaf.basic.BasicScrollPaneUI.VSBChangeListener\" and location type: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.swing.plaf.basic.BasicScrollPaneUI.VSBChangeListener\",\"Location\":\"\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@269e22c7" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <jdk.management.resource*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <jdk.management.resource*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"jdk.management.resource*\" and location type: 11" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"jdk.management.resource*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=5 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=oracle2openjdk-00002 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=293 ruleID=oracle2openjdk-00002 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1dc16a53" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: ConstructorCombinedPattern: com.sun.image.codec.jpeg*(...), pattern match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.image.codec.jpeg*\" and location type: 3" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.image.codec.jpeg*\",\"Location\":\"CONSTRUCTOR_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@73c9904d" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.suspend(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.suspend\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.suspend\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@1b741e0e" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.sun.mirror.apt*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.sun.mirror.apt*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.mirror.apt*\" and location type: 11" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.mirror.apt*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-apt-00001 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=294 ruleID=java-8-deprecate-apt-00001 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4c2b8fbd" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.sun.security.auth.callback.DialogCallbackHandler>, exact match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.sun.security.auth.callback.dialogcallbackhandler>, exact match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.security.auth.callback.DialogCallbackHandler\" and location type: 11" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.security.auth.callback.DialogCallbackHandler\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=8 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-callback-00001 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=295 ruleID=java-8-deprecate-callback-00001 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5a2ef799" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun>, type<corba*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<corba*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun>, type<corba*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.corba*\" and location type: 8" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.corba*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-corba-00001 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=296 ruleID=java-8-deprecate-corba-00001 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@65da4f69" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<javafx.scene>, type<*builder> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<*builder>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<javafx.scene>, type<*builder>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javafx.scene.*Builder\" and location type: 8" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javafx.scene.*Builder\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=3 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-javafx-builder-00001 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=297 ruleID=java-8-deprecate-javafx-builder-00001 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5ee5b9b2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.logging.logmanager.addpropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.logging.LogManager.addPropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.logging.LogManager.addPropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@275196d1" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.jar.pack200.packer.addpropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.jar.Pack200.Packer.addPropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.jar.Pack200.Packer.addPropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@75bd9fac" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.swing.plaf.basic.basicdirectorymodel.intervaladded(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.swing.plaf.basic.BasicDirectoryModel.intervalAdded\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.swing.plaf.basic.BasicDirectoryModel.intervalAdded\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@779d344a" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.jar.pack200.unpacker.addpropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.jar.Pack200.Unpacker.addPropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.jar.Pack200.Unpacker.addPropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@77798ba7" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<com.sun.image.codec>, type<jpeg*> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<jpeg*>, pattern match, case insensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<com.sun.image.codec>, type<jpeg*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.image.codec.jpeg*\" and location type: 8" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.image.codec.jpeg*\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5cb56c87" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.resume(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.resume\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.resume\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@456cc842" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: PackageDeclarationPattern: <com.sun.media.sound*>, pattern match, case insensitive, generic full match, fine grain: none | PackageReferencePattern: <com.sun.media.sound*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.media.sound*\" and location type: 11" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.media.sound*\",\"Location\":\"PACKAGE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=9 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-security-00001 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=298 ruleID=java-8-deprecate-security-00001 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5bcd9bc1" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.security.security.insertproviderat(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.Security.insertProviderAt\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.Security.insertProviderAt\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@37f25718" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: checkmemberaccess(...), exact match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"checkMemberAccess\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"checkMemberAccess\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="Adding Carrier span info to context" worker=4 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-security-manager-00001 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=299 ruleID=java-8-deprecate-security-manager-00001 total=309 +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"checkTopLevelWindow\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@45a81ac2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: checktoplevelwindow(...), exact match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"checkTopLevelWindow\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@7e72ab15" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.logging.logmanager.removepropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.logging.LogManager.removePropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.logging.LogManager.removePropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-log-00001 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=300 ruleID=java-8-deprecate-log-00001 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5ffecde6" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.jar.pack200.packer.removepropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.jar.Pack200.Packer.removePropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.jar.Pack200.Packer.removePropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-pack-00001 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=301 ruleID=java-8-deprecate-pack-00001 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@11e72623" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.swing.plaf.basic.basicdirectorymodel.intervalremoved(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.swing.plaf.basic.BasicDirectoryModel.intervalRemoved\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.swing.plaf.basic.BasicDirectoryModel.intervalRemoved\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@432dca0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.util.jar.pack200.unpacker.removepropertychangelistener(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.util.jar.Pack200.Unpacker.removePropertyChangeListener\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.util.jar.Pack200.Unpacker.removePropertyChangeListener\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-pack-00002 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=302 ruleID=java-8-deprecate-pack-00002 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4fd5ba0b" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: SuperInterfaceReferencePattern: <jpeg*>, pattern match, case insensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.image.codec.jpeg*\" and location type: 1" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.image.codec.jpeg*\",\"Location\":\"INHERITANCE\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@666ddfea" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.threadgroup.stop(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.ThreadGroup.stop\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.ThreadGroup.stop\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-19-deprecate-thread-00000 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=303 ruleID=java-19-deprecate-thread-00000 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@4e133b3a" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.xml.stream.xmlinputfactory.newfactory(string, classloader), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.xml.stream.XMLInputFactory.newFactory(String,ClassLoader)\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.xml.stream.XMLInputFactory.newFactory(String,ClassLoader)\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@5cd62984" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeDeclarationPattern: qualification<java.security>, type<Provider> TypeDeclarationPattern: pkg<*>, enclosing<*>, type<Provider>, exact match, case sensitive, generic full match, fine grain: none | TypeReferencePattern: qualification<java.security>, type<Provider>, exact match, case sensitive, generic full match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.security.Provider\" and location type: 8" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.security.Provider\",\"Location\":\"IMPORT\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-security-00002 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=304 ruleID=java-8-deprecate-security-00002 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3e31d5f7" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: java.lang.thread.stop*(...), pattern match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"java.lang.Thread.stop*\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"java.lang.Thread.stop*\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-thread-00001 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=305 ruleID=java-8-deprecate-thread-00001 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@cc177fb" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: checksystemclipboardaccess(...), exact match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"checkSystemClipboardAccess\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"checkSystemClipboardAccess\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3cef85f9" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.swing.plaf.basic.basicdirectorymodel.lt(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.swing.plaf.basic.BasicDirectoryModel.lt\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.swing.plaf.basic.BasicDirectoryModel.lt\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@54562c5f" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: com.sun.image.codec.jpeg*(...), pattern match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.image.codec.jpeg*\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.image.codec.jpeg*\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@2f42aed" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.xml.stream.xmloutputfactory.newfactory(string, classloader), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.xml.stream.XMLOutputFactory.newFactory(String,ClassLoader)\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.xml.stream.XMLOutputFactory.newFactory(String,ClassLoader)\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@58dfbe7" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: checkawteventqueueaccess(...), exact match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"checkAwtEventQueueAccess\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"checkAwtEventQueueAccess\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-security-manager-00002 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=306 ruleID=java-8-deprecate-security-manager-00002 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@458d76e2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.swing.plaf.basic.basictoolbarui.createfloatingframe(...), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.swing.plaf.basic.BasicToolBarUI.createFloatingFrame\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.swing.plaf.basic.BasicToolBarUI.createFloatingFrame\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-19-deprecate-class-00010 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=307 ruleID=java-19-deprecate-class-00010 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@20dc8ed8" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: TypeReferencePattern: qualification<com.sun.image.codec>, type<jpeg*>, pattern match, case insensitive, generic erasure match, fine grain: none" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"com.sun.image.codec.jpeg*\" and location type: 9" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"com.sun.image.codec.jpeg*\",\"Location\":\"VARIABLE_DECLARATION\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=oracle2openjdk-00006 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=308 ruleID=oracle2openjdk-00006 total=309 +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Searching in target project: [Lorg.eclipse.jdt.core.IJavaProject;@3dc7b6c" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: source-only analysis mode only scoping to Sources" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: found errors: [] warnings: []" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: pattern: MethodReferencePattern: javax.xml.stream.xmleventfactory.newfactory(string, classloader), exact match, case insensitive, generic erasure match, fine grain: QUALIFIED_REFERENCE" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Got: 0 Number of search matching the query: \"javax.xml.stream.XMLEventFactory.newFactory(String,ClassLoader)\" and location type: 2" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server log" line="!MESSAGE KONVEYOR_LOG: Results size: 0" provider=java +time="2026-05-20T08:21:11Z" level=info msg="Symbols retrieved" cap=referenced conditionInfo="{\"Referenced\":{\"Pattern\":\"javax.xml.stream.XMLEventFactory.newFactory(String,ClassLoader)\",\"Location\":\"METHOD_CALL\",\"annotated\":{\"pattern\":\"\"},\"Filepaths\":null}}" provider=java symbols=0 +time="2026-05-20T08:21:11Z" level=info msg="rule returned" ruleID=java-8-deprecate-stream-00001 +time="2026-05-20T08:21:11Z" level=info msg="processed rule" logger=process-rule processed=309 ruleID=java-8-deprecate-stream-00001 total=309 +time="2026-05-20T08:21:11Z" level=info msg="log follower context cancelled" provider=java +time="2026-05-20T08:21:11Z" level=info msg="language server context cancelled closing pipes" provider=java +time="2026-05-20T08:21:11Z" level=info msg="RPC connection closed after context cancellation" error="{}" provider=java +time="2026-05-20T08:21:11Z" level=info msg="java provider shutdown complete" exitCode=-1 provider=java diff --git a/.github/modernize/appcat/result/shim.log b/.github/modernize/appcat/result/shim.log new file mode 100644 index 000000000..e69de29bb diff --git a/.github/modernize/ccacontext/.ccaskills b/.github/modernize/ccacontext/.ccaskills deleted file mode 100644 index 637e49324..000000000 --- a/.github/modernize/ccacontext/.ccaskills +++ /dev/null @@ -1,64 +0,0 @@ -assessment -create-dotnet-upgrade-plan -create-java-upgrade-plan -create-modernization-plan -execute-java-upgrade-task -execute-modernization-task -execute-upgrade-task -integration-tests -playbook-create -reconcile-tasks-with-plan -validate-playbook-compliance -validate-playbook-evidence -api-service-contracts -architecture-diagram -business-workflows -configuration-inventory -cve-known-vulnerabilities -cwe-code-quality -cwe-concurrency-synchronization -cwe-credentials-secrets -cwe-file-path-security -cwe-injection-attacks -cwe-memory-safety -data-architecture -dependency-map -fact-application-name -fact-application-port -fact-application-type -fact-architecture-pattern -fact-base-image -fact-communication-protocols -fact-compliance-requirements -fact-container-engine -fact-container-version -fact-data-classification -fact-embedded-language-usage -fact-environment-variables -fact-external-dependencies -fact-external-services -fact-hardware-requirements -fact-health-checks -fact-image-layers -fact-image-size -fact-language-dependencies -fact-licensing-information -fact-multi-stage-build -fact-network-settings -fact-operating-system -fact-orchestration-tool -fact-profile-settings -fact-resource-limits -fact-runtime-environment -fact-security-implementation -fact-service-definition -fact-servlet-container -fact-startup-instrumentation -fact-system-packages -fact-testing-framework -fact-version-information -fact-volume-mounts -fact-xml-configs -rearchitect -repository-dependency-graph -security-assessment-merge diff --git a/.github/modernize/ccacontext/cleanup.sh b/.github/modernize/ccacontext/cleanup.sh deleted file mode 100644 index 72b039d23..000000000 --- a/.github/modernize/ccacontext/cleanup.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash -# Removes CCA-copied skill directories listed in .ccaskills -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SKILLS_DIR="$(cd "$SCRIPT_DIR/../../skills" && pwd)" -SKILLS_DIR_REAL="$(cd "$SKILLS_DIR" && pwd -P)" -CCASKILLS="$SCRIPT_DIR/.ccaskills" - -if [ ! -f "$CCASKILLS" ]; then - echo "No .ccaskills file found, nothing to clean." - exit 0 -fi - -while IFS= read -r skill; do - skill="${skill%$'\r'}" - [ -z "$skill" ] && continue - - case "$skill" in - /*|*\\*|*/*|*..*) - echo "Skipping invalid skill entry: $skill" - continue - ;; - esac - - target="$SKILLS_DIR/$skill" - if [ -d "$target" ]; then - target_real="$(cd "$target" 2>/dev/null && pwd -P)" - if [ -z "$target_real" ]; then - echo "Skipping unresolved path: $skill" - continue - fi - - case "$target_real" in - "$SKILLS_DIR_REAL"/*) - rm -rf -- "$target_real" - echo "Removed: $skill" - ;; - *) - echo "Skipping out-of-scope path: $skill" - ;; - esac - fi -done < "$CCASKILLS" - -rm -f "$CCASKILLS" -echo "Cleanup complete." diff --git a/.github/skills/api-service-contracts/SKILL.md b/.github/skills/api-service-contracts/SKILL.md deleted file mode 100644 index bcbbe5e28..000000000 --- a/.github/skills/api-service-contracts/SKILL.md +++ /dev/null @@ -1,210 +0,0 @@ ---- -name: api-service-contracts -description: Generate API and service communication contracts with sequence diagram ---- - -# API & Service Communication Contracts - -Analyze the project to document all services, API endpoints, communication patterns (sync/async), DTOs, and retry/circuit-breaker policies. Generate a Mermaid sequence diagram showing the primary request flow across services. Save to `.github/modernize/assessment/engines/api-service-contracts.md`. - -## Input Parameters - -- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) - -## Scope Boundaries — Avoid Redundancy with Other Skills - -This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: - -- **Introduction**: Write a 1-2 sentence intro focused on the API surface (number of endpoints, communication style). Do NOT restate the application's technology stack, database options, or architecture type — those are covered by other skills. -- **Entity fields and persistence details** are owned by the `data-architecture` skill. In the DTOs & Contracts section, list entity/DTO **class names** and their role in the API contract (request type, response type, immutability). Do NOT reproduce full field lists, ORM annotations (cascade, fetch strategy), or table names — reference `data-architecture.md` instead. -- **Validation rules** (e.g., `@NotBlank`, custom validators) are owned by the `business-workflows` skill. Mention validation only when it affects the API contract (e.g., "returns 400 if validation fails"). Do NOT enumerate individual field constraints. -- **Caching implementation details** (provider, TTL, configuration class) are owned by the `data-architecture` skill. In the sequence diagram, you may show cache hit/miss behavior, but do NOT repeat the cache provider name, configuration details, or rationale. -- **Configuration properties and profiles** (e.g., `spring.jpa.*`, database profiles) are owned by the `configuration-inventory` skill. Do NOT list property keys/values. -- **Startup dependency chain details** (readiness probes, K8s manifests, dockerize) are owned by the `configuration-inventory` skill. Mention startup order only if it directly affects API availability. Do NOT repeat probe paths or wait mechanisms. - -## Execution Steps - -### Step 1: Generate Service Catalog Section - -Identify all independently deployable services/modules and produce the complete `## Service Catalog` section: - -- Multi-module builds: Maven modules (`pom.xml` `<modules>`), Gradle subprojects (`settings.gradle`), .NET solutions (`.sln` → `.csproj` projects), monorepo workspaces (`package.json` workspaces) -- Docker Compose services (`docker-compose.yml` service definitions) — note third-party containers vs source-built services -- Kubernetes deployments, Helm charts, or IaC definitions - -For each service extract: -- Service name and Maven module / project name -- Port number (from config files, `docker-compose.yml`, or `application.properties`/`appsettings.json`) -- Category: **API Layer** (gateways, BFFs), **Business** (domain services), **Infrastructure** (config, discovery, admin), **Observability** (tracing, metrics, dashboards) -- Purpose (one-line description) -- Key framework dependencies (from `pom.xml`, `.csproj`, `package.json`) - -### Step 2: Generate API Endpoints Inventory Section - -Scan source code for API endpoint definitions and produce the complete `## API Endpoints Inventory` section: - -- Java (Spring): `@RestController`, `@Controller`, `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`, `@RequestMapping` -- Java (Jakarta EE): `@Path`, `@GET`, `@POST`, `@PUT`, `@DELETE` (JAX-RS) -- .NET (ASP.NET Core): `[ApiController]`, `[HttpGet]`, `[HttpPost]`, `[HttpPut]`, `[HttpDelete]`, `[Route]` -- JavaScript/TypeScript: Express routes (`app.get`, `app.post`, `router.get`), Fastify routes, NestJS decorators (`@Get`, `@Post`) - -For each endpoint extract: -- HTTP method (GET, POST, PUT, DELETE, PATCH) -- URL path (including path parameters) -- Request type (body/query/path parameters, DTO class name) -- Response type (DTO class name, status codes) -- API versioning scheme if present (URL path, header, query parameter) -- Which service/controller it belongs to - -### Step 3: Generate Management & Observability Endpoints Section - -Identify management and observability endpoints and produce the complete `## Management & Observability Endpoints` section: - -- Spring Boot Actuator endpoints (`/actuator/health`, `/actuator/info`, `/actuator/metrics`, `/actuator/prometheus`) -- .NET health checks (`/health`, `/healthz`), Swagger UI (`/swagger`) -- Custom metrics annotations: `@Timed` (Micrometer), `[Meter]`, custom metric registrations — note the metric name and which service exposes it - -### Step 4: Generate DTOs & Contracts Section - -Analyze DTO and contract definitions and produce the complete `## DTOs & Contracts` section: - -- Find DTO / request / response model classes (records, POJOs, C# records/classes). List class names and their API role (request body, response, path/query param). Do NOT reproduce full field lists or ORM annotations — those belong in `data-architecture.md`. -- **Distinguish gateway-level DTOs** (aggregation/composition models that combine data from multiple services) from **service-level domain entities** (owned by a single service) -- Note which DTOs are immutable (Lombok `@Value`, Java records, C# records, frozen data classes) -- Identify OpenAPI/Swagger specifications (`openapi.yaml`, `swagger.json`, Springdoc/Swashbuckle annotations) -- Check for protobuf schemas (`.proto` files) or GraphQL schemas -- Note serialization configuration (Jackson, System.Text.Json, custom serializers) - -### Step 5: Generate Communication Patterns Section - -Identify inter-service and intra-service communication and produce the complete `## Communication Patterns` section: - -- **Synchronous**: REST (HttpClient, RestTemplate, WebClient, Feign), gRPC, direct method calls -- **Asynchronous**: Message queues (Kafka, RabbitMQ, Azure Service Bus, SQS), event-driven patterns, pub/sub -- **Resilience patterns**: Circuit breaker (Resilience4j, Polly, Spring Retry), retry policies, timeout configuration, bulkhead patterns — note specific timeout values and fallback behavior -- **Service discovery**: Eureka, Consul, Kubernetes DNS, Azure Service Discovery — note whether services register by logical name or hardcoded URL -- **API gateway**: Spring Cloud Gateway, Ocelot, Kong, custom gateway patterns -- **Gateway aggregation/composition**: Document how the gateway combines responses from multiple backend services (e.g., fetching owner details from one service and visit history from another, then merging them into a single response). Note the composition logic and fallback behavior when a downstream service is unavailable. -- **Client-side load balancing**: Spring Cloud LoadBalancer, Ribbon, or framework-provided balancing -- **Startup dependency chain**: Briefly note the service startup order if it affects API availability. For full details (probes, wait mechanisms, timeouts), refer to `configuration-inventory.md`. -- **Security posture**: Note whether transport security (HTTPS/TLS), authentication (JWT, OAuth2, Basic Auth, Spring Security), or authorization (RBAC, `@PreAuthorize`, role checks) are implemented at the API level. If absent, state it explicitly — e.g., "No authentication or TLS configured; all endpoints are publicly accessible with no authorization checks." Do NOT duplicate CWE security scan findings; focus only on presence or absence at the API contract level. - -### Step 6: Generate Service Technology Matrix Section - -For each service, identify which cross-cutting capabilities it uses and produce the complete `## Service Technology Matrix` section: - -- Web framework (MVC, Reactive/WebFlux, Minimal API) -- Data access (JPA, EF Core, Mongoose, etc.) -- Service discovery (client, server, or none) -- Gateway functionality -- Actuator/health checks -- Caching layer -- Metrics export (Prometheus, Application Insights, etc.) - -### Step 7: Generate Service Communication Sequence Section - -Create a **Mermaid `sequenceDiagram`** and produce the complete `## Service Communication Sequence` section: -- Show key actors: Client, API Gateway (if present), Controllers, Services, External Services, Message Brokers -- Annotate synchronous calls with solid arrows and asynchronous calls with dashed arrows -- Include request/response types where relevant -- Show error handling paths for critical flows (circuit breaker, retry) -- For gateway aggregation flows, show how multiple downstream calls are composed - -Example: - -~~~mermaid -sequenceDiagram - participant Client - participant Gateway as "API Gateway" - participant CustSvc as "Customers Service" - participant VisitSvc as "Visits Service" - participant DB as "Database" - - Client->>Gateway: GET /api/gateway/owners/1 - Gateway->>CustSvc: GET /owners/1 - CustSvc->>DB: findById(1) - DB-->>CustSvc: Owner + Pets - CustSvc-->>Gateway: OwnerDetails(pets=[Pet1,Pet2]) - Gateway->>VisitSvc: GET /pets/visits?petId=1,2 - alt Visits Service Available - VisitSvc->>DB: findByPetIdIn([1,2]) - DB-->>VisitSvc: Visits list - VisitSvc-->>Gateway: Visits(items=[...]) - else Circuit Breaker Open - Gateway-->>Gateway: Fallback - empty visits - end - Gateway->>Gateway: Merge visits into pets - Gateway-->>Client: 200 OwnerDetails + Visits -~~~ - -### Step 8: Save Output - -Save to `.github/modernize/assessment/engines/api-service-contracts.md` with this exact structure: - -``` -# API & Service Communication Contracts - -A brief introduction (1-2 sentences) summarizing the API surface and communication patterns found. - -## Service Catalog - -[Table: Service | Port | Category | Purpose] - -## API Endpoints Inventory - -[Table: Service | Method | Path | Request Type | Response Type] - -## Management & Observability Endpoints - -[Table: Service | Endpoint | Custom Metrics (if any)] - -## DTOs & Contracts - -[Description of gateway-level DTOs vs service-level entities, immutability, serialization] - -## Communication Patterns - -[Description of sync/async patterns, gateway aggregation/composition logic, circuit breaker/retry policies with timeout values, service discovery, startup dependency chain, and security posture (authentication/authorization/TLS — or explicit statement that none is configured)] - -## Service Technology Matrix - -[Table: Service | Web | Data Access | Discovery | Gateway | Actuator | Cache | Metrics] - -## Service Communication Sequence - -< Mermaid sequenceDiagram here > -``` - -## Scaling Rules - -- If the project has **more than 30 endpoints**, group by service/controller and show representative endpoints per group -- Keep the sequence diagram under **40 participants and messages** to ensure readability and GitHub rendering compatibility -- For multi-module projects, focus on inter-module communication in the sequence diagram and list all endpoints in the table -- Aggregate similar endpoints (e.g., CRUD operations on the same resource) into one table row if needed for brevity -- For the service technology matrix, use checkmarks or short labels; omit columns where no service uses the capability - -## Mermaid Syntax Rules - -- Use `sequenceDiagram` -- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in participant labels — use plain text or quoted labels -- Use `->>` for synchronous calls and `-->>` for responses/async messages -- Use `participant` with alias syntax for readable labels: `participant Svc as "OrderService"` -- Use `alt`/`else`/`end` blocks to show circuit breaker fallback paths -- Do not use backticks inside node labels - -## Error Handling - -- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` -- **No API endpoints found**: Output: `> ERROR: No recognized API endpoints found at {workspace-path}. Verify the path is correct.` -- **Insufficient info**: Generate a best-effort document from available data. Add a note: `> Note: Some endpoints or communication patterns could not be fully identified.` - -## Success Criteria - -- Service catalog table lists all discovered services with ports, categories, and purposes -- API endpoints table lists all discovered endpoints with HTTP method, path, and types -- Management/observability endpoints are cataloged with custom metric names -- Gateway aggregation/composition patterns are documented with fallback behavior -- Service technology matrix shows per-service capabilities -- Communication patterns section describes sync/async patterns, resilience policies, and security posture (authentication, authorization, TLS — explicitly stating if none is configured) -- Mermaid sequence diagram renders correctly showing primary request flow with aggregation and fallback -- File saved to `.github/modernize/assessment/engines/api-service-contracts.md` diff --git a/.github/skills/architecture-diagram/SKILL.md b/.github/skills/architecture-diagram/SKILL.md deleted file mode 100644 index e74695943..000000000 --- a/.github/skills/architecture-diagram/SKILL.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -name: architecture-diagram -description: Generate architecture diagram with component relationship details from project analysis ---- - -# Architecture Diagram - -This skill generates a two-layer architecture visualization: a high-level application architecture diagram and a detailed component relationship diagram. Produce both in a single pass and save to `.github/modernize/assessment/engines/architecture-diagram.md`. - -## Input Parameters - -- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) - -## Execution Steps - -### Step 1: Generate Application Architecture Section - -Analyze the project and produce the complete `## Application Architecture` section in one pass: - -**Analysis:** -- Examine build files (Java: pom.xml, build.gradle; .NET: *.csproj, *.sln; JS/TS: package.json, tsconfig.json) -- Review configuration files (application.properties, appsettings.json, .env, database/API configs) -- Scan key source files to extract: framework, major dependencies, data access patterns, external integrations, technology stack -- Identify application layers (UI, Business Logic, Data Access), data storage technologies, and external service dependencies - -**Diagram — Mermaid `flowchart TD`:** -- Application layers with technology info (use `subgraph` for grouping) -- Data storage components (specific names like "PostgreSQL", "Redis") -- External service integrations -- Data flow with descriptive arrow labels - -**Do NOT include**: individual classes/methods or migration directions. - -Example: - -~~~mermaid -flowchart TD - subgraph Client["Client Layer"] - Browser["Web Browser"] - end - subgraph App["Application Layer - Spring Boot 2.7"] - Web["Spring MVC + Thymeleaf"] - Security["Spring Security"] - Service["Business Services"] - end - subgraph Data["Data Layer"] - JPA["Spring Data JPA"] - DB[("PostgreSQL 14")] - Cache[("Redis")] - end - subgraph External["External Services"] - SMTP["SMTP Email Service"] - S3["AWS S3 Storage"] - end - - Browser -->|"HTTP requests"| Web - Web --> Security -->|"authorized"| Service - Service -->|"CRUD operations"| JPA - JPA -->|"SQL queries"| DB - Service -->|"session cache"| Cache - Service -->|"send email"| SMTP - Service -->|"file upload"| S3 -~~~ - -**Textual explanations (write immediately after the diagram):** -- **Technology Stack Summary table**: Layer | Technology | Version | Purpose (e.g., Presentation | ASP.NET MVC 5 | 5.2.7 | Server-side web framework) -- **Data Storage & External Services**: A short paragraph describing what databases, caches, message brokers, or external APIs are used and how they fit into the architecture -- **Key Architectural Decisions**: 1-3 bullet points on notable patterns (e.g., "Uses repository pattern with EF6 for data access", "Autofac provides DI with module-based registration") - -### Step 2: Generate Component Relationships Section - -Analyze component interactions and produce the complete `## Component Relationships` section in one pass: - -**Analysis:** -- Identify key component types by framework conventions: - - Java (Spring): Controllers, Services, Repositories, Configurations, Entities, DTOs, Listeners, Filters - - Java (Jakarta EE): Servlets, EJBs, CDI Beans, JPA Entities, JAX-RS Resources - - .NET (ASP.NET Core): Controllers, Services, Middleware, DbContext, Entities, Hubs, Filters - - .NET (Blazor/MVC): Pages, Components, ViewModels - - JavaScript/TypeScript (Node.js): Routes, Controllers, Services, Middleware, Models - - JavaScript/TypeScript (React/Angular/Vue): Components, Hooks, Services, Stores, Pages -- Trace dependency injection (constructor/field injection) -- Map communication patterns (REST, gRPC, message queues, events) -- Map data access patterns (service-to-repository, DbContext usage) -- Detect cross-cutting concerns (middleware, interceptors, filters) - -**Diagram — Mermaid `flowchart LR`:** -- Components grouped by architectural layer using `subgraph` (Presentation, Business Logic, Data Access, Infrastructure) -- Interaction arrows with brief labels -- Cross-cutting concerns - -**Do NOT include**: method signatures, private helpers, or external dependencies (covered by dependency-map skill). - -Example: - -~~~mermaid -flowchart LR - subgraph Presentation - UserCtrl["UserController"] - OrderCtrl["OrderController"] - end - subgraph Business["Business Logic"] - UserSvc["UserService"] - OrderSvc["OrderService"] - NotifSvc["NotificationService"] - end - subgraph DataAccess["Data Access"] - UserRepo["UserRepository"] - OrderRepo["OrderRepository"] - end - subgraph Infra["Infrastructure"] - AuthFilter["AuthenticationFilter"] - LogMiddleware["LoggingMiddleware"] - end - - UserCtrl -->|"delegates"| UserSvc - OrderCtrl -->|"delegates"| OrderSvc - OrderSvc -->|"lookups"| UserSvc - OrderSvc -->|"triggers"| NotifSvc - UserSvc -->|"queries"| UserRepo - OrderSvc -->|"queries"| OrderRepo - AuthFilter -.->|"intercepts"| UserCtrl - AuthFilter -.->|"intercepts"| OrderCtrl - LogMiddleware -.->|"wraps"| Presentation -~~~ - -**Textual explanation (write immediately after the diagram):** -- **Component Inventory table**: Component | Layer | Type | Responsibility (e.g., CatalogController | Presentation | MVC Controller | Handles catalog browsing and CRUD) - -### Step 3: Save Output - -Save the combined output to `.github/modernize/assessment/engines/architecture-diagram.md` with this exact structure: - -``` -# Architecture Diagram - -A brief introduction (1-2 sentences). - -## Application Architecture - -< Layer 1 Mermaid flowchart TD here > - -### Technology Stack Summary - -[Table: Layer | Technology | Version | Purpose] - -### Data Storage & External Services - -[Short paragraph on databases, caches, external APIs] - -### Key Architectural Decisions - -[1-3 bullet points on notable patterns] - -## Component Relationships - -< Layer 2 Mermaid flowchart LR here > - -### Component Inventory - -[Table: Component | Layer | Type | Responsibility] -``` - -## Scaling Rules - -- If the project has **more than 30 components**, aggregate by package/namespace (e.g., show `com.example.orders` as one node instead of listing every class) -- Keep each diagram under **40 nodes** to ensure readability and GitHub rendering compatibility -- For multi-module projects, focus on inter-module boundaries in Layer 1 and key components within the most important modules in Layer 2 - -## Mermaid Syntax Rules - -- Use `flowchart TD` for Layer 1 and `flowchart LR` for Layer 2 -- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in node labels — use plain text -- Always quote arrow labels with double quotes: `-->|"label"|` -- Use `subgraph` for grouping, with a display name in quotes if it contains spaces -- Verify all node IDs are unique across the entire diagram - -## Error Handling - -- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` -- **No source code found**: Output: `> ERROR: No recognized source files found at {workspace-path}. Verify the path is correct.` -- **Insufficient info**: Generate a best-effort diagram from available data. Add a note inside the diagram: `Note["Some components could not be identified"]` - -## Success Criteria - -- Layer 1 Mermaid diagram renders correctly showing architecture with technology names, data storage, and external dependencies -- Layer 1 is accompanied by Technology Stack Summary table, Data Storage & External Services paragraph, and Key Architectural Decisions -- Layer 2 Mermaid diagram renders correctly showing component interactions grouped by architectural layer -- Layer 2 is accompanied by Component Inventory table -- File saved to `.github/modernize/assessment/engines/architecture-diagram.md` diff --git a/.github/skills/assessment/SKILL.md b/.github/skills/assessment/SKILL.md deleted file mode 100644 index a9c4cae77..000000000 --- a/.github/skills/assessment/SKILL.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -name: assessment -description: Run application assessment for a single repository ---- - -# Application Assessment - -This skill performs application assessment for a single repository. It supports Java, .NET, and JavaScript/TypeScript projects. - -## Input Parameters - -- `workspace-path` (optional): Path to the project to assess. Defaults to the current directory (repository root) when not specified. All assessment outputs are written relative to this path (e.g. `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json`). For a repository with multiple sub-projects, pass the sub-project directory path so that each sub-project's outputs are isolated. - -## When to Use This Skill - -Use this skill when you need to: - -- Assess a Java or .NET application for cloud readiness and migration issues -- Assess a JavaScript/TypeScript project for outdated dependencies and available updates -- Generate detailed assessment reports with issue analysis and recommendations -- Understand application dependencies, frameworks, and potential migration blockers - -## What This Skill Does - -This skill performs a simplified assessment workflow: - -1. **Check Project Type and Prerequisites**: - - **For Java projects**: Verify that MCP tools are available ('appmod-precheck-assessment' and 'appmod-run-assessment') - - If these MCP tools are not configured, return immediately with setup instructions - - **For .NET projects**: Check if .NET SDK is available - - No MCP tools required for .NET assessment - - **For JavaScript/TypeScript projects**: Check if Node.js and npm are available - - No MCP tools required for JS/TS assessment - -2. **Run Assessment**: - - **For Java projects**: Trigger AppCAT analysis via Assessment MCP server - - Uses 'appmod-precheck-assessment' and 'appmod-run-assessment' MCP tools - - Auto-detects project configuration within `{workspace-path}` - - **For .NET projects**: Install and run AppCAT directly - - Install: `dotnet tool update dotnet-appcat` - - Find all .csproj files under `{workspace-path}` - - Join project paths with semicolons: `projectPaths="project1.csproj;project2.csproj"` - - Run: `dotnet-appcat analyze $projectPaths --source Solution --target Any --serializer APPMODJSON --code --privacyMode Restricted --non-interactive --report {workspace-path}\.github\modernize\appcat\result\report.json` - - **For JavaScript/TypeScript projects**: Install and run npm-check-updates - - Install: `npm install -g npm-check-updates@19.6.3 --prefix {tool-install-dir}` - - Run: `ncu --format group --packageFile {workspace-path}/package.json` - - Save the output to `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` - - Analyzes code for cloud migration issues or dependency updates - - Generates structured assessment data - -3. **Save Report to Versioned Directory (Java and .NET only)**: - - **For Java projects**: Search for `report.json` under `{workspace-path}/.github/modernize/appcat/result/` or `{workspace-path}/.github/appmod/appcat/result/` subdirectories - - **For .NET projects**: The report is at `{workspace-path}/.github/modernize/appcat/result/report.json` - - Read the generated `report.json` and extract the `metadata.analysisStartTime` field - - Format the timestamp as `yyyyMMddHHmmss` to produce the `reportId` (e.g. `2024-06-15T14:30:52Z` becomes `20240615143052`) - - Create the versioned directory: `mkdir -p {workspace-path}/.github/modernize/assessment/reports/report-{reportId}` - - Move the report to: `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` - - This versioned report should be included in the pull request - -## How to Use - -### Prerequisites - -**For Java projects**: -- MCP tools must be available: 'appmod-precheck-assessment' and 'appmod-run-assessment' -- If tools are not configured, the skill will return instructions for setup - -**For .NET projects**: -- .NET SDK must be installed -- No MCP tools required - appcat will be installed and run directly via .NET CLI -- The assessment will automatically install `dotnet-appcat` tool if not already present - -**For JavaScript/TypeScript projects**: -- Node.js and npm must be installed -- No MCP tools required - npm-check-updates will be installed and run directly via npm -- The assessment will automatically install `npm-check-updates` if not already present - -### Triggering Assessment - -Simply express the intent to assess the application. Example prompts: - -- "Assess the application" -- "Run assessment for this project" - -The assessment process automatically: -- Detects project language and framework within `{workspace-path}` -- **For Java**: Uses MCP tools to install and run AppCAT -- **For .NET**: Installs dotnet-appcat tool and runs analysis directly -- **For JavaScript/TypeScript**: Installs npm-check-updates and runs dependency analysis -- Executes comprehensive analysis -- **For Java**: Generates report at `{workspace-path}/.github/modernize/appcat/result/` or `{workspace-path}/.github/appmod/appcat/result/report.json` -- **For .NET**: Generates report at `{workspace-path}/.github/modernize/appcat/result/report.json` -- **For JavaScript/TypeScript**: Generates report at `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` - -### Report Saving - -**For Java projects**: -1. Search for `report.json` files under `{workspace-path}/.github/modernize/appcat/result/` or `{workspace-path}/.github/appmod/appcat/result/` subdirectories -2. If multiple reports exist, identify the most recently modified one -3. Read the report and extract `metadata.analysisStartTime`, format as `yyyyMMddHHmmss` to get `reportId` -4. Move the report to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` -5. Include this versioned report in the pull request - -**For .NET projects**: -1. Report is initially generated at `{workspace-path}/.github/modernize/appcat/result/report.json` -2. Read the report and extract `metadata.analysisStartTime`, format as `yyyyMMddHHmmss` to get `reportId` -3. Move the report to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` -4. Include this versioned report in the pull request - -**For JavaScript/TypeScript projects**: -1. Report is directly generated at `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` -2. Include this report in the pull request - -## Report Output Location - -Report location depends on project type: - -**For Java projects** (via MCP server): -- Initially stored under `{workspace-path}/.github/modernize/appcat/result/` or `{workspace-path}/.github/appmod/appcat/result/` subdirectories -- Saved to versioned directory: `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` - -Where `{reportId}` is derived from `metadata.analysisStartTime` in the report, formatted as `yyyyMMddHHmmss`. - -**For .NET projects** (direct execution): -- Initially generated at: `{workspace-path}/.github/modernize/appcat/result/report.json` -- Moved to versioned directory: `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` - -**For JavaScript/TypeScript projects** (direct execution): -- Directly generated at: `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` - -## Success Criteria - -Assessment is complete when: -- ✅ **For Java**: MCP server is available (or clear instructions provided if not) -- ✅ **For .NET**: .NET SDK is available and dotnet-appcat tool is installed -- ✅ **For JavaScript/TypeScript**: Node.js and npm are available and npm-check-updates is installed -- ✅ AppCAT analysis executes without errors (Java/.NET) or ncu analysis executes without errors (JS/TS) -- ✅ **For Java and .NET**: Report generated at `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` -- ✅ **For JavaScript/TypeScript**: Report generated at `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` -- ✅ Report metadata includes assessment tool version, timestamp, and configuration - -## Troubleshooting - -**Prerequisites Not Met**: -- **For Java**: Verify MCP tools are available ('appmod-precheck-assessment' and 'appmod-run-assessment') - - Return immediately with setup instructions if tools are not available - - Do not attempt to run assessment without MCP -- **For .NET**: Verify .NET SDK is installed - - Check with `dotnet --version` command - - Provide installation instructions if .NET SDK is missing -- **For JavaScript/TypeScript**: Verify Node.js and npm are installed - - Check with `npm --version` command - - Provide installation instructions if npm is missing - -**Assessment Failures**: -- Unsupported project type (only Java, .NET, and JavaScript/TypeScript supported) -- **For Java**: MCP server communication errors -- **For .NET**: - - dotnet-appcat tool installation failure - - dotnet-appcat command execution errors -- **For JavaScript/TypeScript**: - - npm-check-updates installation failure - - ncu command execution errors - - No package.json found at `{workspace-path}/package.json` -- Invalid project structure or build configuration - -**Report Generation Issues**: -- **For Java**: No report.json found under `{workspace-path}/.github/modernize/appcat/result/` or `{workspace-path}/.github/appmod/appcat/result/` subdirectories after MCP execution -- **For .NET**: Report not generated at `{workspace-path}/.github/modernize/appcat/result/report.json`, or `metadata.analysisStartTime` missing from report -- **For JavaScript/TypeScript**: Report not generated at `{workspace-path}/.github/modernize/assessment/js-assessment-report.md` -- Report file is corrupted or invalid JSON (Java/.NET only) - -For any failure, provide clear error messages and troubleshooting steps. diff --git a/.github/skills/business-workflows/SKILL.md b/.github/skills/business-workflows/SKILL.md deleted file mode 100644 index 73d79be9b..000000000 --- a/.github/skills/business-workflows/SKILL.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -name: business-workflows -description: Generate core business workflow documentation with sequence diagram ---- - -# Core Business Workflows - -Analyze the project to document business processes end-to-end, domain entities, business rules, service-to-domain mapping, cross-service data flows, and decision logic. Generate a Mermaid sequence diagram showing the primary business workflow. Save to `.github/modernize/assessment/engines/business-workflows.md`. - -## Input Parameters - -- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) - -## Scope Boundaries — Avoid Redundancy with Other Skills - -This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: - -- **Introduction**: Write a 1-2 sentence intro focused on the business domain (what the application does for its users). Do NOT restate the technology stack, database options, or framework versions. -- **Domain Entities table**: Focus on business meaning — entity description, bounded context, and business relationships. Do NOT reproduce entity field lists, data types, PK/FK annotations, or ORM mapping details (cascade, fetch strategy) — those are owned by the `data-architecture` skill. -- **Validation rules in workflow steps**: When describing a workflow step that involves validation, reference the rule by name (e.g., "PetValidator checks name and birthDate") rather than re-listing every constraint. Enumerate the full validation rules only once in the "Business Rules & Decision Logic" section. -- **Caching behavior**: If caching affects a workflow (e.g., vet list served from cache), mention the business impact (e.g., "vet data served from cache, reducing load") but do NOT describe the cache provider, TTL, configuration class, or JMX statistics — those are owned by the `data-architecture` skill. -- **API endpoint paths and HTTP methods**: Only mention endpoint paths as entry points for workflows (e.g., "Staff submits POST /owners/new"). Do NOT create endpoint inventory tables — those are owned by the `api-service-contracts` skill. - -## Execution Steps - -### Step 1: Generate Domain Entities Section - -Identify the domain model and produce the complete `## Domain Entities` section: - -- Identify domain entities and aggregates (DDD patterns if present) -- Focus on business meaning — entity description, bounded context, and business relationships -- Do NOT reproduce entity field lists, data types, PK/FK annotations, or ORM mapping details (cascade, fetch strategy) — those are owned by the `data-architecture` skill - -### Step 2: Generate Service-to-Domain Mapping Section - -Map each service to its bounded context and owned entities, then produce the complete `## Service-to-Domain Mapping` section (applies to microservice or multi-module architectures): - -- Service name → bounded context (e.g., `customers-service` → Customer Management, `visits-service` → Appointment Management) -- Domain entities owned by each service/context -- Cross-context data exchange patterns: how domains communicate (REST API, events, shared database) -- Data that spans contexts (e.g., `petId` as a foreign key in visits-service referencing customers-service's Pet entity) -- Aggregation boundaries: which service is the source of truth for which data - -### Step 3: Generate Primary Workflows Section - -Scan for business process entry points, trace each significant workflow end-to-end, and produce the complete `## Primary Workflows` section: - -**Entry points to scan:** -- Controllers/endpoints that initiate business processes (not just CRUD — look for multi-step operations) -- **API Gateway aggregation endpoints** that compose responses from multiple backend services — these are business workflow entry points even though they live in the gateway layer (e.g., fetching owner details combined with visit history) -- Scheduled tasks (`@Scheduled`, Quartz, Hangfire, cron jobs, `BackgroundService`) -- Event listeners (`@EventListener`, `@KafkaListener`, `INotificationHandler`, message handlers) -- CLI commands or batch job entry points -- Startup/initialization routines that set up business state - -**For each significant entry point, trace the flow:** -- Entry point → service layer → domain logic → persistence -- The sequence of operations: validation → business rule check → state mutation → side effects -- Branching logic (if/else, switch, strategy pattern) that represents business decisions -- Orchestration vs choreography patterns in multi-service workflows - -### Step 4: Generate Cross-Service Data Flows Section - -Trace cross-service data composition flows end-to-end and produce the complete `## Cross-Service Data Flows` section: - -- Gateway aggregation patterns: e.g., gateway fetches owner from customers-service → extracts pet IDs → fetches visits from visits-service → merges visits into pet records → returns composite response -- Which service provides which data and how they are joined/merged -- Circuit breaker fallback behavior that affects business outcomes (e.g., "when visits-service is unavailable, owner details are returned without visit history" — this is a business-relevant degradation, not just a technical detail) - -### Step 5: Generate Business Workflow Sequence Section - -Create a **Mermaid `sequenceDiagram`** showing the primary business workflow end-to-end and produce the complete `## Business Workflow Sequence` section: - -- Show the most important business process (e.g., "customer places order", "owner registers pet and schedules visit", "gateway aggregates owner with visit history") -- Include actors, services, and domain entities as participants -- Show business rule checks and decision points -- Annotate with business-relevant labels (not technical method names) -- Use `alt`/`else` blocks to show circuit breaker fallback paths that affect business outcomes -- Show cross-service data aggregation flows - -Example: - -~~~mermaid -sequenceDiagram - participant Owner - participant Gateway as "API Gateway" - participant CustSvc as "Customer Service" - participant VisitSvc as "Visit Service" - participant DB as "Database" - - Owner->>Gateway: View my pets and visits - Gateway->>CustSvc: Get owner details - CustSvc->>DB: Find owner with pets - DB-->>CustSvc: Owner + Pet list - CustSvc-->>Gateway: OwnerDetails(pets) - - Gateway->>Gateway: Extract pet IDs from response - Gateway->>VisitSvc: Get visits for pets (batch) - alt Visit Service Available - VisitSvc->>DB: Find visits by pet IDs - DB-->>VisitSvc: Visit records - VisitSvc-->>Gateway: Visits per pet - Gateway->>Gateway: Merge visits into pet records - else Visit Service Unavailable (Circuit Breaker) - Note over Gateway: Fallback - return owner without visits - end - Gateway-->>Owner: Complete owner profile with visits -~~~ - -### Step 6: Generate Business Rules & Decision Logic Section - -Extract and document business rules and cross-cutting concerns, and produce the complete `## Business Rules & Decision Logic` section: - -**Business Rules:** -- **Validation rules**: Input validation, field constraints, format checks, custom validators -- **Decision logic**: Conditional business logic, pricing rules, eligibility checks, approval workflows -- **State transitions**: Entity lifecycle states (e.g., Order: Created → Confirmed → Shipped → Delivered), state machines -- **Business constraints**: Uniqueness rules, capacity limits, temporal constraints (booking windows, cooldown periods) -- **Computed values**: Derived fields, calculated totals, aggregated metrics -- **Data integrity rules**: Bidirectional relationship maintenance (e.g., `owner.addPet(pet)` ensuring both sides of the relationship are set) - -**Cross-Cutting Concerns:** -- **Transactions**: Transaction boundaries, `@Transactional` scope, saga patterns, eventual consistency -- **Error handling**: Business exception types, compensating actions, dead-letter handling -- **Audit/logging**: Business event logging, audit trails, change tracking -- **Authorization**: Business-level authorization rules (role-based, attribute-based, resource ownership) - -### Step 7: Save Output - -Save to `.github/modernize/assessment/engines/business-workflows.md` with this exact structure: - -``` -# Core Business Workflows - -A brief introduction (1-2 sentences) summarizing the application's business domain. - -## Domain Entities - -[Table: Entity | Service / Bounded Context | Description | Key Relationships] - -## Service-to-Domain Mapping - -[Table: Service | Domain Context | Owned Entities | External Dependencies] - -## Primary Workflows - -### Workflow 1: [Name] - -[Description, steps, business rules involved, cross-service interactions] - -### Workflow 2: [Name] - -[Description, steps, business rules involved] - -## Cross-Service Data Flows - -[Description of aggregation/composition patterns, which service provides which data, how data is joined, fallback behavior when services are unavailable] - -## Business Workflow Sequence - -< Mermaid sequenceDiagram here, with alt/else blocks for fallback paths > - -## Business Rules & Decision Logic - -[Summary of key business rules, validation rules, state transitions, and decision points] -``` - -## Scaling Rules - -- If the project has **more than 10 distinct workflows**, focus on the 3-5 most important business processes and summarize the rest in a "Other Workflows" section -- Keep the sequence diagram under **40 participants and messages** to ensure readability and GitHub rendering compatibility -- For multi-module projects, focus on the primary end-to-end business workflow that spans modules -- Aggregate minor CRUD operations and show only workflows that involve business logic beyond simple create/read/update/delete - -## Mermaid Syntax Rules - -- Use `sequenceDiagram` -- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in participant labels — use plain text or quoted labels -- Use `->>` for synchronous calls and `-->>` for responses -- Use `participant` with alias syntax for readable labels: `participant Svc as "OrderService"` -- Use `Note over` for annotations about business decisions or fallback behavior -- Use `alt`/`else`/`end` blocks for decision points and circuit breaker fallbacks -- Do not use backticks inside participant labels - -## Error Handling - -- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` -- **No business logic found**: Output: `> ERROR: No recognized business logic or workflows found at {workspace-path}. The project may be a library or framework without business processes.` -- **Insufficient info**: Generate a best-effort document from available data. Add a note: `> Note: Some workflows or business rules could not be fully traced.` - -## Success Criteria - -- Domain entities table lists key entities with their owning service/bounded context, descriptions, and relationships -- Service-to-domain mapping table maps each service to its domain context and owned entities -- At least one primary workflow is documented with steps, business rules, and cross-service interactions -- Cross-service data flows describe aggregation/composition patterns with fallback behavior -- Mermaid sequence diagram renders correctly showing end-to-end business workflow with `alt`/`else` blocks for fallbacks -- Business rules section summarizes validation, decision logic, state transitions, and constraints -- File saved to `.github/modernize/assessment/engines/business-workflows.md` diff --git a/.github/skills/configuration-inventory/SKILL.md b/.github/skills/configuration-inventory/SKILL.md deleted file mode 100644 index 780125774..000000000 --- a/.github/skills/configuration-inventory/SKILL.md +++ /dev/null @@ -1,205 +0,0 @@ ---- -name: configuration-inventory -description: Generate comprehensive configuration and externalized settings inventory ---- - -# Configuration & Externalized Settings Inventory - -Analyze the project to produce a comprehensive inventory of all configuration sources, build profiles, runtime profiles, externalized properties, secrets workflows, feature flags, startup dependencies, and framework versions. Save to `.github/modernize/assessment/engines/configuration-inventory.md`. - -> Note: This skill produces a comprehensive reference document. For structured findings suitable for automated processing, see `fact-profile-settings`, `fact-environment-variables`, and `fact-xml-configs`. - -## Input Parameters - -- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) - -## Scope Boundaries — Avoid Redundancy with Other Skills - -This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: - -- **Introduction**: Write a 1-2 sentence intro focused on the configuration landscape (number of config sources, profiles, secrets approach). Do NOT restate the application's architecture type, business domain, or API surface. -- **Database architecture details** (entity models, ER diagrams, ORM mappings, caching strategy rationale, repository methods) are owned by the `data-architecture` skill. In the Properties Inventory, list database-related property keys and values as raw configuration entries, but do NOT explain their behavioral implications (e.g., do not explain what `spring.jpa.open-in-view=false` means for lazy loading — that belongs in `data-architecture.md`). -- **API endpoints** are owned by the `api-service-contracts` skill. Do NOT list HTTP endpoints, controller routes, or actuator paths. -- **Business workflows and validation rules** are owned by the `business-workflows` skill. Do NOT describe business processes or entity validation constraints. -- **Entity/domain model listings** are owned by `data-architecture` and `business-workflows`. Do NOT enumerate entity names, fields, or relationships. - -## Execution Steps - -### Step 1: Generate Configuration Sources Section - -Identify all configuration files and sources and produce the complete `## Configuration Sources` section: - -- Java (Spring): `application.properties`, `application.yml`, `bootstrap.properties`, `bootstrap.yml` — note that `bootstrap.*` files are distinct from `application.*` (bootstrap configures the config server connection and runs before application context; application configures the app itself) -- .NET: `appsettings.json`, `appsettings.{Environment}.json`, `web.config`, `launchSettings.json` -- JavaScript/TypeScript: `.env`, `.env.local`, `.env.production`, `config/*.js`, `config/*.ts` -- Shared: `docker-compose.yml` environment sections, Kubernetes ConfigMaps/Secrets YAML files -- Config server references: Spring Cloud Config (note the external Git repository URI), Azure App Configuration, AWS AppConfig, Consul KV -- Secret stores: HashiCorp Vault, Azure KeyVault, AWS Secrets Manager references -- External configuration repositories: document the URI/path of any external config repos (e.g., `spring.cloud.config.server.git.uri`) - -### Step 2: Generate Build Profiles Section - -Identify build-time profiles that affect compilation, packaging, and dependency resolution, and produce the complete `## Build Profiles` section: - -- **Java/Maven**: profiles in `pom.xml` (e.g., `springboot`, `buildDocker`, `dev`, `cloud`) — for each, document activation condition (auto, manual `-P`, system property `-Denv=`), purpose, and key dependencies or plugins added -- **Java/Gradle**: build types and flavors in `build.gradle` -- **.NET**: build configurations (Debug, Release), conditional compilation symbols, MSBuild properties -- **JavaScript/TypeScript**: build scripts in `package.json`, webpack/vite/esbuild configurations per environment - -For each build profile extract: -- Profile name -- Activation condition (automatic, manual flag, system property, environment variable) -- Purpose (what it enables) -- Key dependencies or plugins added/removed - -### Step 3: Generate Runtime Profiles Section - -List all runtime profile-specific or environment-specific configuration and produce the complete `## Runtime Profiles` section: - -- Java (Spring): Profile-specific files (`application-dev.yml`, `application-prod.yml`), `@Profile` annotations, `spring.profiles.active` settings, combined profile activation (e.g., `mysql,key-vault`) -- .NET: Environment-specific files (`appsettings.Development.json`, `appsettings.Production.json`), `ASPNETCORE_ENVIRONMENT` usage -- JavaScript/TypeScript: `.env.development`, `.env.production`, NODE_ENV-based branching -- Identify profile activation conditions, defaults, and how profiles compose (multiple active profiles) - -### Step 4: Generate Properties Inventory Section - -For each service/module, catalog all configuration properties and produce the complete `## Properties Inventory` section: - -- Property keys with their default values -- Which profiles/environments override each property -- Data types and expected value ranges (where inferable) -- Properties sourced from environment variables (`${ENV_VAR}`, `%ENV_VAR%`) -- Placeholder references and property resolution chain - -> Do NOT include JVM startup parameters, `-Xms`/`-Xmx` heap settings, `-D` system properties, container memory/CPU limits, or instance counts here — those belong in the `## Startup Parameters & Resource Requirements` section (Step 5). - -### Step 5: Generate Startup Parameters & Resource Requirements Section - -Document JVM startup options, runtime parameters, and per-service resource allocations, and produce the complete `## Startup Parameters & Resource Requirements` section: - -- JVM heap settings (`-Xms`, `-Xmx`) per service -- System properties passed at startup (`-Dspring.profiles.active=`, `-Dazure.keyvault.uri=`, etc.) -- Docker/container environment variable overrides (`SPRING_PROFILES_ACTIVE`, `ASPNETCORE_ENVIRONMENT`) -- Memory allocation per service (Docker `mem_limit`, Kubernetes `resources.requests/limits`, cloud deployment settings) -- CPU allocation if specified -- Instance count and scaling configuration -- JVM heap settings mapped to service memory allocation (e.g., `-Xms2048m -Xmx2048m` for 2Gi services) - -### Step 6: Generate Startup Dependency Chain Section - -Map the service startup order and readiness dependencies and produce the complete `## Startup Dependency Chain` section: - -- Which services must start before others (e.g., config-server → discovery-server → business services → gateway) -- Health-check/wait mechanisms: `dockerize` wait-for-TCP, Kubernetes readiness probes, Spring Cloud Config retry, Docker Compose `depends_on` with health checks -- Startup timeout configurations -- Service readiness indicators (actuator health endpoints, custom health checks) - -### Step 7: Generate Secrets & Sensitive Configuration Section - -Flag sensitive configuration entries and document the secrets provisioning workflow, and produce the complete `## Secrets & Sensitive Configuration` section (including the `### Secrets Provisioning Workflow` subsection): - -- Database passwords, API keys, connection strings with credentials -- Secret references: KeyVault URIs, Vault paths, encrypted property values -- Entries marked as sensitive by framework conventions (e.g., `spring.datasource.password`) -- **Do NOT output actual secret values** — show the reference path or "[MASKED]" placeholder -- Note encryption methods if present (Jasypt, DPAPI, sealed secrets) - -Document how secrets flow through the system (`### Secrets Provisioning Workflow`): -- Secret source: environment variables, Key Vault, Vault, AWS Secrets Manager, sealed secrets -- Identity/access model: managed identities, service principals, RBAC permissions (e.g., "system-assigned managed identity with `get` and `list` permissions on Key Vault") -- Provisioning sequence: how secrets are set up during deployment (e.g., GitHub Actions retrieves service principal credentials → authenticates → creates MySQL secrets → binds to services) -- Which services need which secrets (e.g., data services need MySQL connection strings, all services need config server credentials) - -### Step 8: Generate Feature Flags Section - -Identify feature toggles and conditional configuration and produce the complete `## Feature Flags` section: - -- Feature flag frameworks: Spring Feature Flags, LaunchDarkly, Unleash, .NET FeatureManagement, custom toggles -- Conditional beans/services (`@ConditionalOnProperty`, `@ConditionalOnExpression`) -- A/B testing flags and gradual rollout configurations -- Default values and controlling sources (config file, environment variable, remote service) - -### Step 9: Generate Framework & Runtime Versions Section - -Catalog the technology stack versions that affect configuration and produce the complete `## Framework & Runtime Versions` section: - -- Core framework versions: Spring Boot, Spring Cloud, ASP.NET Core, Node.js, Express -- Target language/runtime version: Java 8/11/17/21, .NET 6/7/8, Node.js 18/20 -- Key library versions: Hibernate, EF Core, Resilience4j, Eureka, etc. -- Docker base images and their versions (e.g., `openjdk:11-jre`, `mcr.microsoft.com/dotnet/aspnet:8.0`) -- Build tool versions: Maven, Gradle, MSBuild, npm/yarn/pnpm - -### Step 10: Save Output - -Save to `.github/modernize/assessment/engines/configuration-inventory.md` with this exact structure: - -``` -# Configuration & Externalized Settings Inventory - -A brief introduction (1-2 sentences) summarizing the configuration landscape. - -## Configuration Sources - -[Table: Source | Type | Path/Location | Notes] - -## Build Profiles - -[Table: Profile | Activation | Purpose | Key Dependencies/Plugins] - -## Runtime Profiles - -[Table: Profile | Activation Method | Config Files | Key Overrides] - -## Properties Inventory - -[Per-service tables: Property Key | Default | Profiles | Source] - -## Startup Parameters & Resource Requirements - -[Table: Service | JVM/Runtime Options | Memory | Instance Count] - -## Startup Dependency Chain - -[Ordered list: Service → waits for → Service, with mechanism (dockerize, health check, etc.)] - -## Secrets & Sensitive Configuration - -[Table: Secret Reference | Type | Storage (masked)] - -### Secrets Provisioning Workflow - -[Description of how secrets flow: source → identity/access → binding → services] - -## Feature Flags - -[Table: Flag Name | Default | Controlled By] - -## Framework & Runtime Versions - -[Table: Component | Version | Source] -``` - -## Scaling Rules - -- If the project has **more than 100 properties**, group by category (database, messaging, security, etc.) and show representative examples with counts -- For multi-module projects, organize the properties inventory by module/service -- Collapse repetitive property patterns (e.g., 20 similar cache TTL settings) into a summary row with count - -## Error Handling - -- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` -- **No configuration files found**: Output: `> ERROR: No recognized configuration files found at {workspace-path}. Verify the path is correct.` -- **Insufficient info**: Generate a best-effort inventory from available data. Add a note: `> Note: Some configuration sources or properties could not be fully identified.` - -## Success Criteria - -- Configuration sources table lists all discovered config files, external config repos, and secret stores -- Build profiles are documented separately from runtime profiles with activation conditions and purposes -- Runtime profiles are documented with config files and key overrides -- Properties inventory covers all discovered properties with defaults and sources -- Startup parameters and resource requirements are documented per service -- Startup dependency chain shows service boot order with wait mechanisms -- Secrets are identified with references (no actual values exposed) and the provisioning workflow is described -- Feature flags are cataloged with defaults and controlling sources -- Framework and runtime versions are documented -- File saved to `.github/modernize/assessment/engines/configuration-inventory.md` diff --git a/.github/skills/create-dotnet-upgrade-plan/SKILL.md b/.github/skills/create-dotnet-upgrade-plan/SKILL.md deleted file mode 100644 index bb6797d8e..000000000 --- a/.github/skills/create-dotnet-upgrade-plan/SKILL.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -name: create-dotnet-upgrade-plan -description: Creates a .NET upgrade plan (plan.md and tasks.json) for a repository. Analyzes the project to determine if a .NET version upgrade is needed and generates a structured upgrade task. Use when the user wants to create, generate, or prepare an upgrade/migration plan for a .NET project or solution. ---- - -# Create .NET Upgrade Plan - -Generate an upgrade plan (`plan.md` and `.metadata/tasks.json`) for a .NET project or solution. This skill **only creates the plan** — it does not execute the upgrade. The upgrade execution is handled by the `modernize-dotnet-upgrade-engineer` agent during plan execution. - -> **Supported**: .NET upgrades only. Other languages are not supported. - ---- - -## CRITICAL: HEADLESS EXECUTION MODE - -**This skill operates in fully autonomous headless mode. NO USER INTERACTION IS PERMITTED.** - -### Non-Negotiable Rules - -1. **NEVER stop, pause, or wait for user input** — not for confirmations, selections, reviews, or approvals -2. **NEVER ask "Would you like to proceed?"** — just proceed -3. **NEVER ask "Should I continue?"** — just continue -4. **ALWAYS complete the entire workflow** — from start to finish without interruption - ---- - -## Input Parameters - -| Parameter | Required | Description | -|-----------|----------|-------------| -| `upgrade-prompt` | Yes | The user's upgrade request (e.g., ".NET 10", "net10.0", "latest LTS") | -| `modernization-work-folder` | Yes | The folder to save the upgrade plan outputs | - ---- - -## Input Validation - -**Valid requests**: .NET version upgrades, LTS migrations, .NET Framework to modern .NET migrations - -**Invalid requests**: Feature additions, bug fixes, refactoring, containerization, deployment, non-.NET languages - -If invalid, output exactly and STOP: -``` -ERROR: The provided prompt is not a valid upgrade request. Please specify a target version (e.g., '.NET 10', 'net10.0'). -``` - -If unsupported language, output exactly and STOP: -``` -ERROR: Only .NET upgrades are supported. The requested language is not supported. -``` - ---- - -## Guidelines - -Refer to `dotnet-upgrade-guideline.md` for the rules on when to create an upgrade task, target version selection, and framework compatibility. - -Key rules from the guideline: -- Only add an upgrade task if: the project is EOL, has Azure SDK incompatibility, or the user explicitly requests it -- Always upgrade to the **latest LTS** version unless the user specifies a different target -- Current latest LTS: **.NET 10** (`net10.0`) -- Create a **single** upgrade task that encompasses all necessary changes - ---- - -## Workflow - -### Step 1: Analyze the Project - -Examine the project to determine: -1. **Current .NET version**: Read `.csproj` files to find `<TargetFramework>` or `<TargetFrameworks>` -2. **Project type**: Is it .NET Framework (requires SDK-style conversion), .NET Core, or modern .NET? -3. **Solution structure**: Is it a single project or a multi-project solution? List all projects. - -### Step 2: Determine Upgrade Need - -Apply the rules from `dotnet-upgrade-guideline.md`: -- If the project's .NET version is EOL → upgrade needed -- If the project targets .NET Framework < 4.6.2 (Azure SDK incompatibility) → upgrade needed -- If the user explicitly requests an upgrade → upgrade needed -- Otherwise → no upgrade needed, output: `ERROR: No upgrade is needed. The project is already on a supported .NET version.` - -### Step 3: Generate plan.md - -Create `plan.md` in `${modernization-work-folder}/` with: -- Source .NET version (detected from the project) -- Target .NET version (from user request or latest LTS) -- List of projects in the solution -- High-level description of what the upgrade entails (e.g., SDK-style conversion, TFM update, NuGet updates, API migration) - -### Step 4: Generate tasks.json - -Generate `tasks.json` in `${modernization-work-folder}/.metadata/` following `tasks-schema.json` and `upgrade-plan-template.md`. - -Create a **single** upgrade task: - -**Task Generation Rules:** - -| Rule | Requirement | -|------|-------------| -| Task type | Use `upgrade` type | -| Task count | Exactly **one** upgrade task | -| Description | Include source and target .NET versions, project names | -| Reason | Include a **non-empty** `reason` field explaining why the upgrade is needed (for example: current .NET version is outdated or unsupported, target version standardization, required compatibility/security/support improvements) | -| Requirements | High-level summary of the upgrade scope (source version, target version, general areas affected). Do not include implementation details — the upgrade agent determines the specific steps. | -| Skills | Empty array `[]` — the upgrade agent handles execution internally | -| successCriteria values | Must be **strings** (`"true"`, not `true`) | -| status | Set to `"pending"` | -| id format | Use pattern `001-upgrade-dotnet-to-{target}` (e.g., `001-upgrade-dotnet-to-net10`) | - ---- - -## Success Criteria - -All of the following must be true: - -- [ ] `plan.md` exists in `${modernization-work-folder}/` -- [ ] `tasks.json` exists in `${modernization-work-folder}/.metadata/` -- [ ] `plan.md` clearly states source and target .NET versions -- [ ] `tasks.json` follows schema with all required fields -- [ ] Exactly one upgrade task in tasks.json -- [ ] Workflow completed without user interaction - ---- - -## Error Handling - -| Problem | Solution | -|---------|----------| -| No .csproj found | Output `ERROR: No supported .NET project files (.csproj) found in the repository.` | -| Cannot determine current .NET version | Output `ERROR: Could not determine the current .NET version from project files.` | -| Project already on target version | Output `ERROR: The project is already on the target .NET version.` | - ---- - -## Anti-Patterns (NEVER DO THESE) - -| Don't | Do Instead | -|-------|------------| -| Stop to ask user for confirmation | Accept defaults and continue | -| Create multiple granular upgrade tasks | Create a single upgrade task | -| Wait for user review | Complete workflow, then show final results | -| Ask "Should I proceed?" | Just proceed | diff --git a/.github/skills/create-dotnet-upgrade-plan/dotnet-upgrade-guideline.md b/.github/skills/create-dotnet-upgrade-plan/dotnet-upgrade-guideline.md deleted file mode 100644 index a5c97e03a..000000000 --- a/.github/skills/create-dotnet-upgrade-plan/dotnet-upgrade-guideline.md +++ /dev/null @@ -1,43 +0,0 @@ -# .NET Upgrade Task Guidelines - -Only add a .NET upgrade task if one of the following conditions is met: - -1. **End of Life (EOL)**: The project's .NET version is out of mainstream support. -2. **Azure SDK Compatibility**: The project targets a .NET Framework version older than 4.6.2, which does not support `netstandard2.0` and cannot use modern Azure SDK (`Azure.*`) packages. -3. **User Request**: The user explicitly requests a .NET version upgrade. - -The upgrade task must be the first task if it exists. - -### Target Version - -Always upgrade to the **latest LTS** version unless the user explicitly specifies a different target version. - -- Current latest LTS: **.NET 10** (`net10.0`) - -### Azure SDK Minimum .NET Version - -The modern Azure SDK for .NET (`Azure.*` packages) targets `netstandard2.0` as its baseline. The following .NET Framework versions do **not** support `netstandard2.0` and require an upgrade: - -| .NET Framework Version | `netstandard2.0` Support | Action | -|------------------------|:------------------------:|--------| -| 4.5 and below | ❌ | Upgrade required | -| 4.6 | ❌ | Upgrade required | -| 4.6.1 | ⚠️ Unreliable | Upgrade recommended | -| 4.6.2+ | ✅ | No upgrade needed for Azure SDK compatibility | - -> **Note**: .NET Framework 4.6.1 is technically listed as supporting `netstandard2.0` but has known issues. Microsoft recommends 4.7.2+ for reliable support. The Azure SDK explicitly targets `net462` as its minimum. - -## Framework Compatibility - -| Source Framework | Target Framework | SDK-Style Conversion Required | -|-----------------|:----------------:|:----------------------------:| -| .NET Framework 4.x | net10.0 | Yes | -| .NET Core 3.1 | net10.0 | No | -| .NET 5–9 | net10.0 | No | - -## .NET Task Selection Rules - -- **Rule 1 — Single task only**: Always create a **single** upgrade task that encompasses all necessary changes. The `modernize-dotnet-upgrade-engineer` agent handles the detailed breakdown during execution. -- **Rule 2 — EOL or Azure SDK incompatibility**: Create task "Upgrade .NET to latest LTS (net10.0)". Set the task `skills` array to `[]` (empty) — the upgrade agent handles execution internally. -- **Rule 3 — User-specified version**: Create task "Upgrade .NET to version X". Set the task `skills` array to `[]` (empty) — the upgrade agent handles execution internally. -- **Rule 4 — No upgrade needed**: If the project's .NET version is in support **and** the project targets .NET Framework 4.6.2+ (or any .NET Core / modern .NET) **and** the user did not request an upgrade, do **not** add an upgrade task. \ No newline at end of file diff --git a/.github/skills/create-dotnet-upgrade-plan/tasks-schema.json b/.github/skills/create-dotnet-upgrade-plan/tasks-schema.json deleted file mode 100644 index 397678e03..000000000 --- a/.github/skills/create-dotnet-upgrade-plan/tasks-schema.json +++ /dev/null @@ -1,349 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "Modernization Tasks Template", - "description": "Schema for tasks-template.json. Preserve field descriptions because they are used to generate the JSON by LLM.", - "type": "object", - "required": ["$schema", "description", "tasks", "metadata"], - "additionalProperties": false, - "properties": { - "$schema": { - "type": "string", - "description": "JSON Schema reference used by the template." - }, - "description": { - "type": "string", - "description": "Tasks template for modernization plan. Generate this file alongside plan.md to track individual migration tasks." - }, - "tasks": { - "type": "array", - "description": "List of individual migration tasks.", - "items": { - "oneOf": [ - { "$ref": "#/$defs/transformTask" }, - { "$ref": "#/$defs/upgradeTask" }, - { "$ref": "#/$defs/integrationTestTask" }, - { "$ref": "#/$defs/containerizationTask" }, - { "$ref": "#/$defs/deploymentTask" }, - { "$ref": "#/$defs/securityTask" }, - { "$ref": "#/$defs/infrastructureTask" } - ] - } - }, - "metadata": { - "type": "object", - "description": "Metadata for the plan.", - "additionalProperties": false, - "required": ["planName", "projectName", "language", "createdAt", "version"], - "properties": { - "planName": { - "type": "string", - "description": "[Plan name]" - }, - "projectName": { - "type": "string", - "description": "[Application Name]" - }, - "language": { - "type": "string", - "description": "[Programming language]" - }, - "createdAt": { - "type": "string", - "description": "[ISO 8601 timestamp]", - "format": "date-time" - }, - "version": { - "type": "string", - "description": "Version of the template schema.", - "const": "1.0" - } - } - } - }, - "$defs": { - "taskBase": { - "type": "object", - "additionalProperties": false, - "required": ["type", "id", "description", "requirements"], - "properties": { - "type": { - "type": "string", - "description": "Task type identifier." - }, - "id": { - "type": "string", - "description": "[Unique identifier for this task, start with sequence and category name, like '001-transform-migration-rabbitmq-to-servicebus']" - }, - "description": { - "type": "string", - "description": "[Brief description of what this task achieves from the user's perspective. It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" - }, - "reason": { - "type": "string", - "description": "[Explain why this task is needed, e.g., the motivation, business justification, or technical necessity that drives this task]" - }, - "requirements": { - "type": "string", - "description": "[The specific requirements for this task including: what to migrate (features, APIs, patterns), constraints (backward compatibility, modules to avoid), target Azure services, and technical preferences (authentication methods, patterns). It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" - }, - "environmentConfiguration": { - "type": ["string"], - "description": "[Environment configuration from user input (e.g. endpoint, access id). Omit this field if not specified]" - }, - "status": { - "type": ["string"], - "description": "Task execution status. Only has value after task is executed.", - "enum": ["pending", "started", "success", "failed", "skipped"] - }, - "taskSummary": { - "type": "string", - "description": "Summary of task execution result. Only has value after task is executed." - }, - "dependencies": { - "type": "array", - "description": "[List of task IDs that this task depends on. The task will only be executed after all its dependencies have completed successfully.]", - "items": { - "type": "string" - } - } - } - }, - "skill": { - "type": "object", - "additionalProperties": false, - "required": ["name", "location"], - "properties": { - "name": { - "type": "string", - "description": "[The skill name that will be used for this task, e.g., 'migration-rabbitmq-to-servicebus'.]" - }, - "location": { - "type": "string", - "description": "Skill location: project, remote and builtin, builtin is renamed from custom", - "enum": ["project","remote","builtin"] - } - } - }, - "successCriteria": { - "type": "object", - "additionalProperties": false, - "required": [ - "passBuild", - "generateNewUnitTests", - "passUnitTests" - ], - "description": "The task success criteria to validate after task execution.", - "properties": { - "passBuild": { - "type": ["string"], - "default": "true", - "description": "Project must compile successfully after migration, use default value if user does not specify" - }, - "generateNewUnitTests": { - "type": ["string"], - "default": "false", - "description": "Create mock-based unit tests for newly added Azure integration code to ensure test coverage, use default value if user does not specify" - }, - "passUnitTests": { - "type": ["string"], - "default": "true", - "description": "All unit tests must pass; mock dependent Azure resources if not provided, use default value if user does not specify" - } - } - }, - "successCriteriaStatus": { - "type": "object", - "not": { - "type": "null" - }, - "additionalProperties": false, - "description": "Optional validation status for each success criterion. Omit this field until validation is complete. If present, use true/false string values.", - "properties": { - "passBuild": { - "type": ["string"], - "description": "Validation status of passBuild criterion. true means passed, false means failed." - }, - "generateNewUnitTests": { - "type": ["string"], - "description": "Validation status of generateNewUnitTests criterion. true means passed, false means failed." - }, - "passUnitTests": { - "type": ["string"], - "description": "Validation status of passUnitTests criterion. true means passed, false means failed." - } - } - }, - "transformTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "successCriteria"], - "properties": { - "type": { - "const": "transform", - "description": "transform task template" - }, - "skills": { - "type": "array", - "description": "The skills that will be used for this task, it is started with migration and looks like 'migration-rabbitmq-to-servicebus-mi'", - "items": { "$ref": "#/$defs/skill" } - }, - "successCriteria": { "$ref": "#/$defs/successCriteria" }, - "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } - } - } - ] - }, - "upgradeTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "successCriteria"], - "properties": { - "type": { - "const": "upgrade", - "description": "Upgrade task template" - }, - "successCriteria": { "$ref": "#/$defs/successCriteria" }, - "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } - } - } - ] - }, - "containerizationTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "dockerfilePath"], - "properties": { - "type": { - "const": "containerization", - "description": "Containerization task template - Only include if the target deployment requires containerization (e.g., AKS, ACA) or if the user explicitly requested containerization. Skip for non-containerized deployments." - }, - "dockerfilePath": { - "type": "string", - "description": "[Path to Dockerfile, indicate if existing or to be created]" - } - } - } - ] - }, - "deploymentTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "targetAzureService", "resourceStatus", "deploymentTool", "skills"], - "properties": { - "type": { - "const": "deployment", - "description": "Deployment task template - Containerize, provision and deploy the application to Azure. Only include if the user explicitly requested deployment." - }, - "skills": { - "type": "array", - "description": "The deployment skill to use based on targetAzureService: 'azcli-aks-deploy' for Azure Kubernetes Service, 'azcli-containerapp-deploy' for Azure Container Apps, 'azcli-appservice-deploy' for Azure App Service, 'azcli-functionapp-deploy' for Azure Function App, 'azcli-appservicemi-deploy' for Azure App Service with Managed Identity", - "items": { "$ref": "#/$defs/skill" } - }, - "targetAzureService": { - "type": "string", - "description": "[Azure service name, e.g., Azure Container Apps, AKS, App Service]" - }, - "resourceStatus": { - "type": "string", - "description": "[Specify if using existing resource or will create new service]" - }, - "deploymentTool": { - "type": "string", - "description": "Infrastructure as Code tool type. Default to 'terraform' for aks, 'bicep' for other services if not specified.", - "enum": ["bicep", "terraform"] - } - } - } - ] - }, - "integrationTestTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "layers"], - "properties": { - "type": { - "const": "integrationTest", - "description": "Integration test task template - Generate and run integration tests for migrated Azure services. Only include when user explicitly requests integration testing. This task runs after all transform/upgrade tasks but before containerization." - }, - "layers": { - "type": "array", - "description": "[Array of test layers to execute, e.g., [1, 2] for Layer 1 (Local Integration with TestContainers) and Layer 2 (Smoke Tests)]", - "items": { - "type": "number", - "enum": [1, 2] - }, - "minItems": 1 - } - } - } - ] - }, - "securityTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "successCriteria"], - "properties": { - "type": { - "const": "security", - "description": "Security task template - Include when security remediation, vulnerability scanning, or compliance checks are required." - }, - "cveReport": { - "type": ["string"], - "description": "Path to final-cve-report.json. Only has value after CVE checking is complete." - }, - "successCriteria": { "$ref": "#/$defs/successCriteria" }, - "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } - } - } - ] - }, - "infrastructureTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "skills", "iacType", "provision"], - "properties": { - "type": { - "const": "infrastructure", - "description": "Infrastructure task template - Generate IaC files (Bicep or Terraform) to provision Azure resources." - }, - "iacType": { - "type": "string", - "description": "Infrastructure as Code tool type.", - "enum": ["bicep", "terraform"] - }, - "provision": { - "type": "boolean", - "description": "Whether to provision Azure resources after generating IaC files." - }, - "skills": { - "type": "array", - "description": "The skill used for this task, e.g., 'infrastructure-bicep-generation' or 'infrastructure-terraform-generation'", - "items": { "$ref": "#/$defs/skill" } - } - } - } - ] - } - } -} diff --git a/.github/skills/create-dotnet-upgrade-plan/upgrade-plan-template.md b/.github/skills/create-dotnet-upgrade-plan/upgrade-plan-template.md deleted file mode 100644 index b534fece6..000000000 --- a/.github/skills/create-dotnet-upgrade-plan/upgrade-plan-template.md +++ /dev/null @@ -1,42 +0,0 @@ -# .NET Upgrade Plan Template - -## Schema Rules - -- Use `upgradeTask` type from `tasks-schema.json` -- `successCriteria` values: **strings** (`"true"`, `"false"`) -- `skills.location`: `"builtin"` | `"project"` | `"remote"` -- `status`: `"pending"` - -## Example: tasks.json - -```json -{ - "$schema": "tasks-schema.json", - "description": ".NET version upgrade plan from .NET Framework 4.6.1 to .NET 10.0", - "tasks": [ - { - "type": "upgrade", - "id": "001-upgrade-dotnet-to-net10", - "description": "Upgrade ContosoUniversity from .NET Framework 4.6.1 to .NET 10.0", - "reason": ".NET Framework 4.6.1 reached end of support on April 26, 2022 and does not meet the minimum .NET Framework 4.6.2 requirement for Azure SDK (.NET Standard 2.0) compatibility. Upgrading to .NET 10.0 LTS ensures long-term support, access to modern APIs, and full Azure SDK compatibility.", - "requirements": "Upgrade the project from .NET Framework 4.6.1 to .NET 10.0, including project file modernization, dependency updates, and API compatibility fixes.", - "environmentConfiguration": null, - "skills": [], - "successCriteria": { - "passBuild": "true", - "generateNewUnitTests": "false", - "passUnitTests": "true", - "securityComplianceCheck": "true" - }, - "status": "pending" - } - ], - "metadata": { - "planName": "upgrade-to-lts", - "projectName": "ContosoUniversity", - "language": "dotnet", - "createdAt": "2026-02-13T00:00:00.000Z", - "version": "1.0" - } -} -``` diff --git a/.github/skills/create-java-upgrade-plan/SKILL.md b/.github/skills/create-java-upgrade-plan/SKILL.md deleted file mode 100644 index fe4b54afb..000000000 --- a/.github/skills/create-java-upgrade-plan/SKILL.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -name: create-java-upgrade-plan -description: Create an upgrade plan to migrate a Java project to latest LTS versions ---- - -# Create Upgrade Plan - -Creates `tasks.json` (in `.metadata/` subdirectory) and `plan.md` for upgrading Java projects to target versions. - -> **Supported**: Java upgrades only. .NET and other languages are not supported. - -## ⚠️ CRITICAL: Do NOT Read Files - -**Do NOT read any workspace files** (pom.xml, build.gradle, source code, etc.). - -This plan may apply to multiple repositories not yet cloned. Generate a **generic plan** based solely on the user's prompt—never detect or mention "current versions." - -## User Input - -upgrade-prompt (Mandatory): The user's upgrade request (e.g., "Java 17", "Spring Boot 3.2", or "Upgrade to the latest LTS versions") -modernization-work-folder (Mandatory): The folder to save the upgrade plan - -## Validation - -**Valid requests**: Java/framework version upgrades, LTS migrations, dependency bumps -**Invalid requests**: Feature additions, bug fixes, refactoring, containerization, deployment, non-Java languages (.NET, Python, etc.) - -If invalid, output exactly: -``` -ERROR: The provided prompt is not a valid upgrade request. Please specify a target version (e.g., 'Java 17', 'Spring Boot 3.2'). -``` - -If unsupported language, output exactly: -``` -ERROR: Only Java upgrades are supported. The requested language is not supported. -``` -Then STOP—do not create files or ask for clarification. - -## Workflow - -1. **Parse request** → Extract target versions (defaults: Java 25, Spring Boot 4.x) -2. **Generate tasks.json** → Follow `tasks-schema.json` and `upgrade-plan-template.md`, and save it to `.metadata/tasks.json` -3. **Generate plan.md** → Brief overview of the upgrade plan - -## Task Rules - -- **Java Upgrade Task Guidelines**: You must refer to the ./java-upgrade-guideline.md for specific rules and guidelines when creating Java upgrade tasks. -- Create **only** `upgrade` type tasks -- Specify **target versions only**—never "from version X" -- Use `builtin` skills (e.g., `java-version-upgrade`) -- `successCriteria` values must be **strings** (`"true"`, not `true`) -- Set `status` to `"pending"` - -## Output - -Save to `${modernization-work-folder}/`: -- `.metadata/tasks.json` — Upgrade tasks per schema -- `plan.md` — Plan overview diff --git a/.github/skills/create-java-upgrade-plan/java-upgrade-guideline.md b/.github/skills/create-java-upgrade-plan/java-upgrade-guideline.md deleted file mode 100644 index 270412a96..000000000 --- a/.github/skills/create-java-upgrade-plan/java-upgrade-guideline.md +++ /dev/null @@ -1,44 +0,0 @@ -# Java Upgrade Task Guidelines - -Only add an upgrade task if the user explicitly requests it. The upgrade task must be the first task if it exists. - -## Latest Stable Versions - -- Java: 25 -- Spring Boot: 4.x -- Spring Framework: 7.x - -## Supported Upgrade Versions - -- Java: 11, 17, 21, 25 -- Spring Boot: 3.x, 4.x -- Spring Framework: 6.x, 7.x - -## Framework Compatibility - -| Spring Boot | Spring Framework | Jakarta EE | Minimum Java | Maximum Java | -|-------------|:----------------:|:----------:|:------------:|:------------:| -| 2.x | 5.x | JavaEE (javax.*) | 8 | 11 | -| 3.x | 6.x | Jakarta EE (jakarta.*) | 17 | 21 | -| 4.x | 7.x | Jakarta EE (jakarta.*) | 25 | 25 | - -## Upgrade Task Types and Included Changes - -| Task Type | Spring Framework Upgrade | Jakarta EE Migration (javax.* → jakarta.*) | JDK/Java | -|-----------|:------------------------:|:------------------------------------------:|:-----------:| -| Spring Boot 4.x upgrade | 7.x | ✓ | 25 | -| Spring Boot 3.x upgrade | 6.x | ✓ | 21 | -| Spring Framework 7.x upgrade | — | ✓ | 25 | -| Spring Framework 6.x upgrade | — | ✓ | 21 | -| Jakarta EE upgrade | — | ✓ | 21 | -| JDK/Java upgrade | — | — | to specified version | - -## Java Task Selection Rules - -When selecting the Java upgrade task type, follow these rules in order: - -- **Rule 1 — No redundant sub-tasks**: Each upgrade type (Spring Boot, Spring Framework, Jakarta EE, JDK/Java) is hierarchical — higher-level tasks already include lower-level ones. Never create a lower-level task that is already covered by a selected higher-level task. For example, if a Spring Boot 4.x upgrade task is selected (which already includes JDK 25), do NOT also create a separate JDK/Java upgrade task. -- **Rule 2 — User-specified framework request doesn't fully match system state**: When the user requests a **framework** upgrade (e.g., Spring Boot, Spring Framework) but the target version they specify is not the latest available, select the highest-level task applicable and prompt the user to clarify. For example, if the user asks to "upgrade Spring Boot to 3.x" but Spring Boot 4.x is available, create a Spring Boot 3.x upgrade task and add a clarification question asking whether they want 4.x. **This rule does NOT apply to pure JDK/Java upgrade requests — see Rule 4.** -- **Rule 3 — User-specified request matches system state**: Select the most closely matching task type that directly matches the user's request and fits the system. For example, if the user asks to "upgrade JDK" and the JDK is outdated, create a JDK/Java upgrade task — NOT a higher-level Spring Boot or Spring Framework upgrade task. -- **Rule 4 — Never upgrade other frameworks on a JDK/Java request**: When the user explicitly requests a JDK/Java upgrade, you MUST NOT upgrade Spring Boot, Spring Framework, or Jakarta EE — create only a JDK/Java upgrade task targeting the user-specified version. If the project's existing Spring Boot, Spring Framework, or Jakarta EE versions are incompatible with the target Java version (per the Framework Compatibility table above), add a clarification question asking the user whether they also want to upgrade the incompatible framework(s) to a compatible version. -- **Rule 5 — Ask for clarification when the selected task diverges from the user's request**: Whenever the task you create differs from what the user explicitly asked for (e.g., upgrading to a different version, choosing a higher-level task type, or skipping a requested change due to compatibility), you MUST use the `ask_user` tool to explain what was selected, why it differs, and ask the user to confirm or adjust. If `ask_user` is not available, add the question to the "## Open Questions" section of `plan.md`. Never silently override the user's intent. \ No newline at end of file diff --git a/.github/skills/create-java-upgrade-plan/tasks-schema.json b/.github/skills/create-java-upgrade-plan/tasks-schema.json deleted file mode 100644 index 397678e03..000000000 --- a/.github/skills/create-java-upgrade-plan/tasks-schema.json +++ /dev/null @@ -1,349 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "Modernization Tasks Template", - "description": "Schema for tasks-template.json. Preserve field descriptions because they are used to generate the JSON by LLM.", - "type": "object", - "required": ["$schema", "description", "tasks", "metadata"], - "additionalProperties": false, - "properties": { - "$schema": { - "type": "string", - "description": "JSON Schema reference used by the template." - }, - "description": { - "type": "string", - "description": "Tasks template for modernization plan. Generate this file alongside plan.md to track individual migration tasks." - }, - "tasks": { - "type": "array", - "description": "List of individual migration tasks.", - "items": { - "oneOf": [ - { "$ref": "#/$defs/transformTask" }, - { "$ref": "#/$defs/upgradeTask" }, - { "$ref": "#/$defs/integrationTestTask" }, - { "$ref": "#/$defs/containerizationTask" }, - { "$ref": "#/$defs/deploymentTask" }, - { "$ref": "#/$defs/securityTask" }, - { "$ref": "#/$defs/infrastructureTask" } - ] - } - }, - "metadata": { - "type": "object", - "description": "Metadata for the plan.", - "additionalProperties": false, - "required": ["planName", "projectName", "language", "createdAt", "version"], - "properties": { - "planName": { - "type": "string", - "description": "[Plan name]" - }, - "projectName": { - "type": "string", - "description": "[Application Name]" - }, - "language": { - "type": "string", - "description": "[Programming language]" - }, - "createdAt": { - "type": "string", - "description": "[ISO 8601 timestamp]", - "format": "date-time" - }, - "version": { - "type": "string", - "description": "Version of the template schema.", - "const": "1.0" - } - } - } - }, - "$defs": { - "taskBase": { - "type": "object", - "additionalProperties": false, - "required": ["type", "id", "description", "requirements"], - "properties": { - "type": { - "type": "string", - "description": "Task type identifier." - }, - "id": { - "type": "string", - "description": "[Unique identifier for this task, start with sequence and category name, like '001-transform-migration-rabbitmq-to-servicebus']" - }, - "description": { - "type": "string", - "description": "[Brief description of what this task achieves from the user's perspective. It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" - }, - "reason": { - "type": "string", - "description": "[Explain why this task is needed, e.g., the motivation, business justification, or technical necessity that drives this task]" - }, - "requirements": { - "type": "string", - "description": "[The specific requirements for this task including: what to migrate (features, APIs, patterns), constraints (backward compatibility, modules to avoid), target Azure services, and technical preferences (authentication methods, patterns). It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" - }, - "environmentConfiguration": { - "type": ["string"], - "description": "[Environment configuration from user input (e.g. endpoint, access id). Omit this field if not specified]" - }, - "status": { - "type": ["string"], - "description": "Task execution status. Only has value after task is executed.", - "enum": ["pending", "started", "success", "failed", "skipped"] - }, - "taskSummary": { - "type": "string", - "description": "Summary of task execution result. Only has value after task is executed." - }, - "dependencies": { - "type": "array", - "description": "[List of task IDs that this task depends on. The task will only be executed after all its dependencies have completed successfully.]", - "items": { - "type": "string" - } - } - } - }, - "skill": { - "type": "object", - "additionalProperties": false, - "required": ["name", "location"], - "properties": { - "name": { - "type": "string", - "description": "[The skill name that will be used for this task, e.g., 'migration-rabbitmq-to-servicebus'.]" - }, - "location": { - "type": "string", - "description": "Skill location: project, remote and builtin, builtin is renamed from custom", - "enum": ["project","remote","builtin"] - } - } - }, - "successCriteria": { - "type": "object", - "additionalProperties": false, - "required": [ - "passBuild", - "generateNewUnitTests", - "passUnitTests" - ], - "description": "The task success criteria to validate after task execution.", - "properties": { - "passBuild": { - "type": ["string"], - "default": "true", - "description": "Project must compile successfully after migration, use default value if user does not specify" - }, - "generateNewUnitTests": { - "type": ["string"], - "default": "false", - "description": "Create mock-based unit tests for newly added Azure integration code to ensure test coverage, use default value if user does not specify" - }, - "passUnitTests": { - "type": ["string"], - "default": "true", - "description": "All unit tests must pass; mock dependent Azure resources if not provided, use default value if user does not specify" - } - } - }, - "successCriteriaStatus": { - "type": "object", - "not": { - "type": "null" - }, - "additionalProperties": false, - "description": "Optional validation status for each success criterion. Omit this field until validation is complete. If present, use true/false string values.", - "properties": { - "passBuild": { - "type": ["string"], - "description": "Validation status of passBuild criterion. true means passed, false means failed." - }, - "generateNewUnitTests": { - "type": ["string"], - "description": "Validation status of generateNewUnitTests criterion. true means passed, false means failed." - }, - "passUnitTests": { - "type": ["string"], - "description": "Validation status of passUnitTests criterion. true means passed, false means failed." - } - } - }, - "transformTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "successCriteria"], - "properties": { - "type": { - "const": "transform", - "description": "transform task template" - }, - "skills": { - "type": "array", - "description": "The skills that will be used for this task, it is started with migration and looks like 'migration-rabbitmq-to-servicebus-mi'", - "items": { "$ref": "#/$defs/skill" } - }, - "successCriteria": { "$ref": "#/$defs/successCriteria" }, - "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } - } - } - ] - }, - "upgradeTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "successCriteria"], - "properties": { - "type": { - "const": "upgrade", - "description": "Upgrade task template" - }, - "successCriteria": { "$ref": "#/$defs/successCriteria" }, - "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } - } - } - ] - }, - "containerizationTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "dockerfilePath"], - "properties": { - "type": { - "const": "containerization", - "description": "Containerization task template - Only include if the target deployment requires containerization (e.g., AKS, ACA) or if the user explicitly requested containerization. Skip for non-containerized deployments." - }, - "dockerfilePath": { - "type": "string", - "description": "[Path to Dockerfile, indicate if existing or to be created]" - } - } - } - ] - }, - "deploymentTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "targetAzureService", "resourceStatus", "deploymentTool", "skills"], - "properties": { - "type": { - "const": "deployment", - "description": "Deployment task template - Containerize, provision and deploy the application to Azure. Only include if the user explicitly requested deployment." - }, - "skills": { - "type": "array", - "description": "The deployment skill to use based on targetAzureService: 'azcli-aks-deploy' for Azure Kubernetes Service, 'azcli-containerapp-deploy' for Azure Container Apps, 'azcli-appservice-deploy' for Azure App Service, 'azcli-functionapp-deploy' for Azure Function App, 'azcli-appservicemi-deploy' for Azure App Service with Managed Identity", - "items": { "$ref": "#/$defs/skill" } - }, - "targetAzureService": { - "type": "string", - "description": "[Azure service name, e.g., Azure Container Apps, AKS, App Service]" - }, - "resourceStatus": { - "type": "string", - "description": "[Specify if using existing resource or will create new service]" - }, - "deploymentTool": { - "type": "string", - "description": "Infrastructure as Code tool type. Default to 'terraform' for aks, 'bicep' for other services if not specified.", - "enum": ["bicep", "terraform"] - } - } - } - ] - }, - "integrationTestTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "layers"], - "properties": { - "type": { - "const": "integrationTest", - "description": "Integration test task template - Generate and run integration tests for migrated Azure services. Only include when user explicitly requests integration testing. This task runs after all transform/upgrade tasks but before containerization." - }, - "layers": { - "type": "array", - "description": "[Array of test layers to execute, e.g., [1, 2] for Layer 1 (Local Integration with TestContainers) and Layer 2 (Smoke Tests)]", - "items": { - "type": "number", - "enum": [1, 2] - }, - "minItems": 1 - } - } - } - ] - }, - "securityTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "successCriteria"], - "properties": { - "type": { - "const": "security", - "description": "Security task template - Include when security remediation, vulnerability scanning, or compliance checks are required." - }, - "cveReport": { - "type": ["string"], - "description": "Path to final-cve-report.json. Only has value after CVE checking is complete." - }, - "successCriteria": { "$ref": "#/$defs/successCriteria" }, - "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } - } - } - ] - }, - "infrastructureTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "skills", "iacType", "provision"], - "properties": { - "type": { - "const": "infrastructure", - "description": "Infrastructure task template - Generate IaC files (Bicep or Terraform) to provision Azure resources." - }, - "iacType": { - "type": "string", - "description": "Infrastructure as Code tool type.", - "enum": ["bicep", "terraform"] - }, - "provision": { - "type": "boolean", - "description": "Whether to provision Azure resources after generating IaC files." - }, - "skills": { - "type": "array", - "description": "The skill used for this task, e.g., 'infrastructure-bicep-generation' or 'infrastructure-terraform-generation'", - "items": { "$ref": "#/$defs/skill" } - } - } - } - ] - } - } -} diff --git a/.github/skills/create-java-upgrade-plan/upgrade-plan-template.md b/.github/skills/create-java-upgrade-plan/upgrade-plan-template.md deleted file mode 100644 index 144ae61e4..000000000 --- a/.github/skills/create-java-upgrade-plan/upgrade-plan-template.md +++ /dev/null @@ -1,51 +0,0 @@ -# Upgrade Plan Template - -> **Important**: Specify only TARGET versions—never "current" or "from" versions. Do NOT read project files. - -## Schema Rules - -- Use `upgradeTask` type from `tasks-schema.json` -- `successCriteria` values: **strings** (`"true"`, `"false"`) -- `skills.location`: `"builtin"` | `"project"` | `"remote"` -- `status`: `"pending"` - -## Example: tasks.json -{ - "description": "Upgrade plan to migrate project to latest LTS versions", - "tasks": [ - { - "type": "upgrade", - "id": "001-upgrade-java-spring-boot", - "description": "Upgrade to Java 25 and Spring Boot 4.x", - "requirements": "Upgrade JDK to 25, Spring Boot to 4.x, Spring Framework to 7.x, and migrate javax.* to jakarta.* if needed", - "environmentConfiguration": null, - "skills": [{ "name": "java-version-upgrade", "location": "builtin" }], - "successCriteria": { - "passBuild": "true", - "generateNewUnitTests": "false", - "passUnitTests": "true" - }, - "status": "pending" - } - ], - "metadata": { - "planName": "upgrade-to-lts", - "projectName": "application", - "language": "java", - "createdAt": "2026-02-06T00:00:00.000Z", - "version": "1.0" - } -} -``` - -## Example: plan.md - -```markdown -# Upgrade Plan - -## Overview -Upgrade to latest LTS versions. - -## Tasks -See the .metadata/tasks.json for detailed task breakdown. -``` diff --git a/.github/skills/create-modernization-plan/SKILL.md b/.github/skills/create-modernization-plan/SKILL.md deleted file mode 100644 index fbc539737..000000000 --- a/.github/skills/create-modernization-plan/SKILL.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -name: create-modernization-plan -description: Create a modernization plan to migrate the project to Azure ---- - -# Create modernization plan - -This skill is used to create a modernization plan to migrate the a given project to Azure - -## User Input - -modernization-prompt: The user input to generate the modernization plan -modernization-work-folder (Mandatory): The folder to save the modernization plan -github-issue-link (Optional): A github issue to track the modernization status, to be filled into plan template -assessment-report (Optional): A assessment report for the project will be modernized, it will provide the data about the project for modernization -plan-name (Optional): The plan name to be filled into plan template -language (Mandatory): The programming language of the project (java or dotnet) - -## Supported Task Patterns - -Read the supported patterns file based on the language: -- For .NET projects: Read `supported-patterns-dotnet.md` -- For all other projects: Read `supported-patterns-java.md`. Default option. - -These files contain the list of supported task patterns with and without skill definitions. If a skill is available, the skill location should be set to `builtin`. - -## Workflow - -Given the user input, do this: - -1. Double Check the issues - **IMPORTANT**: - - If you are given an assessment-report, you need to double check if the issue really exist in current project. If not, please ignore this issue when you generate the plan - -2. **Load context**: Retrieve information for plan, you can read - 1) Analysis the supported patterns to find the right tasks for the issues - 2) Analysis modernization requirement from user input - -3. **Clarification and Questionnaire** (only when the `ask_user` tool is available): If there are any open issues or ambiguities that need user input, use the following steps to answer any questions. Also ask the questions outlined in `questionnaire.md` via `ask_user` tool to scope the modernization plan. For questionnaire questions, if the user input already provides the answer, skip asking that question and use the provided information as the answer. - 1) Use the `ask_user` tool to ask the user each clarification question directly. Wait for the user's response before proceeding. - 2) Record each question and answer for use in the summary step. - 3) If the `ask_user` tool is not available, skip this step entirely and proceed to plan generation using best-effort defaults. - -4. **Summary & Confirmation** (only when the `ask_user` tool is available): - 1) Present a summary to the user via `ask_user` that includes: - - All clarification questions and the user's answers (if any were asked in step 3) - - The planned task list with key details for each task: task name, type, matched skill/pattern, and a brief description of what it will do - 2) Ask the user to confirm the summary is correct, or provide additional input to adjust any answers or task list. - 3) If the user provides additional input, incorporate the changes. If the user chooses to skip or confirms, proceed to plan generation. - 4) If the `ask_user` tool is not available, skip this step entirely. - -5. **Generate plan and tasks**: Generate plan.md and tasks.json using the appropriate templates: - - **Template Selection**: - - Use **plan-template.md** for code migration, containerization, and deployment tasks - - Use **security-plan-template.md** to include a security/CVE remediation task in every modernization plan. - - Use **infra-plan-template.md** ONLY when user explicitly requests infrastructure (e.g., "prepare infrastructure", "create landing zone", "provision resources", "generate Bicep/Terraform") - - **Plan Generation**: - 1) Follow the structure of the selected template to generate the plan - 2) Follow the rules defined in the template to fill in the sections with relevant information based on the analysis of user input and content of mentioned files - 3) Save the plan in folder ${modernization-work-folder} with the filename plan.md. If a plan already exists, overwrite it. - 4) Generate a separate tasks.json file following the tasks-schema.json schema with all upgrade, transform, security, integration test, infrastructure, containerization, and deployment tasks - 5) Save the tasks in folder ${modernization-work-folder}/.metadata/ with the filename tasks.json. If tasks.json already exists, overwrite it. - - **Clarification Outcomes in Plan**: Incorporate all clarification answers from steps 3–4 into `plan.md` and `tasks.json`: - - Update the relevant task's `requirements` or `description` in `tasks.json` based on the answer. Do NOT create a separate task for an implementation detail—only add a new task when the answer introduces entirely new migration scope. - - Record all clarification questions and their outcomes in the **"## Open Questions & Questionnaire"** section of `plan.md`: - - Answered: `- [x] Q: ... → A: ...` - - Unanswered/skipped: `- [ ] ...` - - Remove the section entirely if no clarification questions were raised. - - **IMPORTANT**: The plan.md should NOT contain the detailed task breakdown. Those details go into tasks.json for better tracking and programmatic access. - - **Task Breakdown Rules**: When creating tasks for tasks.json and plan.md: - - Purpose: Break down coding work into discrete migration tasks. Each task represents a user-requested migration from one service/component to another, or a specific business logic modernization. - - Create tasks ONLY based on what the user explicitly requested - do not infer or add implicit tasks, **except** for the security/CVE remediation task which must always be included in every plan - - If an `assessment-report` is provided, the task description must identify which specific issues from the assessment report are addressed by that task (e.g., "Addresses issues: <issue-title-1>, <issue-title-2>") - - Group related changes that serve a single user goal into one task (e.g., all changes needed to migrate to PostgreSQL) - - Find a matched skill / pattern for the task, following the following priority order. - 1. Skills available for the project, which will be listed in the `skill` tool description. - 2. Patterns that will be attached and available at plan execution phase, listed in the supported patterns file. - 3. Otherwise if no relevant pattern is available for the task pattern, use the prompt segment from the user directly. DO NOT expand the request scope. - - **IMPORTANT**: - - You MUST NOT use the pattern name as the skill name in the generated plan and tasks.json. - - If there are similar skills defined in project skill `.github/skills/` versus other skills, MUST use the one defined in project. - - Skills must be fully matched. For migration scenarios, both the source product and target product must match the task intent. - - Each task should be independently testable with integration tests - - Do not add tests for unimpacted code or existing functionality unless user requested - - **IMPORTANT**: Do NOT read individual skill files at this stage; Do Not include the skill detail in the tasks. - - **Integration Test Task Rules**: When user explicitly requests integration testing (e.g., "add integration tests", "generate integration tests", "test the migration"): - - Add an integration test task with type "integrationTest" after all transform/upgrade tasks but before containerization tasks - - This integration test task should: - - Have id format: "{sequence}-integrationTest" where sequence is the next number after the last migration task (e.g., if last migration is 001, use "002-integrationTest") - - Have description: "Generate and run integration tests for Azure service migrations" - - Have dependencies on ALL transform and upgrade task ids (so it runs after all migrations are complete) - - Have requirements: "Generate Layer 1 (Local Integration with TestContainers) and Layer 2 (Smoke Tests) for all Azure service migrations" - - Have layers: [1, 2] (only Layer 1 and Layer 2 tests) - - Omit environmentConfiguration unless explicitly provided by user input - - The integration test task appears in plan.md as a separate section after migration tasks but before containerization - - **Java Upgrade Task Guidelines**: Only add an upgrade task if the user explicitly requests it. You must refer to the ./java-upgrade-guideline.md for specific rules and guidelines when creating Java upgrade tasks. - - **.NET Upgrade Task Guidelines**: You must refer to the ./dotnet-upgrade-guideline.md for specific rules and guidelines when creating .NET upgrade tasks. - - **Deployment Task Rules**: - - **IMPORTANT** Do NOT create task type with `containerization` if deployment task already exists, deployment task will cover the containerization work if needed. - - Deployment Task Options: Azure App Service, Azure Kubernetes Service, Azure Container Apps (default), Azure App Service Managed Instance, Azure Static Web App, Azure Function App - - **Security Task Guidelines**: The security task order should be after all the upgrade and transform tasks and before the deployment tasks in the generated plan. If the user provides specific security requirements, incorporate them into the security task; otherwise, use the default requirements from the template. - - **IMPORTANT**: The upgrade task must be the first task in the task list because subsequent transform tasks (e.g., migrating to Azure services) depend on the upgraded runtime and project format. - -6. **Playbook Compliance Validation** (only when playbook attachments are present): - After generating the plan and tasks, call skill `validate-playbook-compliance` to validate that the plan tasks cover the playbook rules: - - tasks-json-path: `${modernization-work-folder}/.metadata/tasks.json` - - compliance-output-path: `${modernization-work-folder}/playbook-compliance.md` - - This validation is **best-effort only** and must **not** block or fail plan creation. - - If the validation call cannot run, fails, or required context/attachments are missing, you must still complete the workflow and emit `${modernization-work-folder}/plan.md` and `${modernization-work-folder}/.metadata/tasks.json`. - - If validation cannot be completed successfully, write a minimal warning/status report to `${modernization-work-folder}/playbook-compliance.md` explaining that validation was skipped or failed and why, if known. - -## Completion Criteria - -1. All clarification & questionnaire questions have been asked (or skipped with defaults) via `ask_user`, answers incorporated into `plan.md` and `tasks.json`, and outcomes recorded in the "## Open Questions & Questionnaire" section of `plan.md` -2. The modernization task list is built -3. The modernization task list MUST be scoped according to user input -4. DON'T RUN the plan if user does not explicitly ask you to run the plan -5. The generated plan.md and tasks.json are saved in the specified folder `${modernization-work-folder}` \ No newline at end of file diff --git a/.github/skills/create-modernization-plan/dotnet-upgrade-guideline.md b/.github/skills/create-modernization-plan/dotnet-upgrade-guideline.md deleted file mode 100644 index a5c97e03a..000000000 --- a/.github/skills/create-modernization-plan/dotnet-upgrade-guideline.md +++ /dev/null @@ -1,43 +0,0 @@ -# .NET Upgrade Task Guidelines - -Only add a .NET upgrade task if one of the following conditions is met: - -1. **End of Life (EOL)**: The project's .NET version is out of mainstream support. -2. **Azure SDK Compatibility**: The project targets a .NET Framework version older than 4.6.2, which does not support `netstandard2.0` and cannot use modern Azure SDK (`Azure.*`) packages. -3. **User Request**: The user explicitly requests a .NET version upgrade. - -The upgrade task must be the first task if it exists. - -### Target Version - -Always upgrade to the **latest LTS** version unless the user explicitly specifies a different target version. - -- Current latest LTS: **.NET 10** (`net10.0`) - -### Azure SDK Minimum .NET Version - -The modern Azure SDK for .NET (`Azure.*` packages) targets `netstandard2.0` as its baseline. The following .NET Framework versions do **not** support `netstandard2.0` and require an upgrade: - -| .NET Framework Version | `netstandard2.0` Support | Action | -|------------------------|:------------------------:|--------| -| 4.5 and below | ❌ | Upgrade required | -| 4.6 | ❌ | Upgrade required | -| 4.6.1 | ⚠️ Unreliable | Upgrade recommended | -| 4.6.2+ | ✅ | No upgrade needed for Azure SDK compatibility | - -> **Note**: .NET Framework 4.6.1 is technically listed as supporting `netstandard2.0` but has known issues. Microsoft recommends 4.7.2+ for reliable support. The Azure SDK explicitly targets `net462` as its minimum. - -## Framework Compatibility - -| Source Framework | Target Framework | SDK-Style Conversion Required | -|-----------------|:----------------:|:----------------------------:| -| .NET Framework 4.x | net10.0 | Yes | -| .NET Core 3.1 | net10.0 | No | -| .NET 5–9 | net10.0 | No | - -## .NET Task Selection Rules - -- **Rule 1 — Single task only**: Always create a **single** upgrade task that encompasses all necessary changes. The `modernize-dotnet-upgrade-engineer` agent handles the detailed breakdown during execution. -- **Rule 2 — EOL or Azure SDK incompatibility**: Create task "Upgrade .NET to latest LTS (net10.0)". Set the task `skills` array to `[]` (empty) — the upgrade agent handles execution internally. -- **Rule 3 — User-specified version**: Create task "Upgrade .NET to version X". Set the task `skills` array to `[]` (empty) — the upgrade agent handles execution internally. -- **Rule 4 — No upgrade needed**: If the project's .NET version is in support **and** the project targets .NET Framework 4.6.2+ (or any .NET Core / modern .NET) **and** the user did not request an upgrade, do **not** add an upgrade task. \ No newline at end of file diff --git a/.github/skills/create-modernization-plan/infra-plan-template.md b/.github/skills/create-modernization-plan/infra-plan-template.md deleted file mode 100644 index a0bf419fb..000000000 --- a/.github/skills/create-modernization-plan/infra-plan-template.md +++ /dev/null @@ -1,48 +0,0 @@ -# Infrastructure Plan Template - -Use this template when user explicitly requests infrastructure preparation (e.g., "prepare infrastructure", "create landing zone", "provision resources", "generate Bicep/Terraform/IaC files"). - ---- - -# Infrastructure Plan: [Plan Title] - -## User Requirements - -[A concise summary of the user's inputs, requirements and preferences for the infrastructure, may include: project codes, assessment report, architecture diagram] - -**Plan Configuration**: - -| Parameter | Value | Description | -|-----------|-------|-------------| -| IaC Tool | [bicep (default) / terraform] | Infrastructure as Code tool | -| Provision | [true (default) / false] | Whether to provision resources after generating IaC | -| Subscription | [Azure subscription ID] | Target Azure subscription | - ---- - -## Proposed Architecture - -[A high-level text diagram illustrating the proposed Azure resource architecture that meets the user's requirements] - ---- - -## Azure Resource List -A complete list of Azure resources to be generated. - -| Resource Type | Resource Name | SKU | Purpose | -|---------------|---------------|-----|---------| -| [e.g., SQL Database] | [e.g., sqldb-myapp-prod] | [e.g., S1] | [Purpose] | - ---- - -## Task - -**Description**: Generate IaC files to provision the required Azure resources. - -**Output**: Files of infrastructure as code - -**Skill**: [infrastructure-bicep-generation | infrastructure-terraform-generation] - -**Success Criteria**: -- IaC files generated and validated -- Resources provisioned successfully (if Provision=true) diff --git a/.github/skills/create-modernization-plan/java-upgrade-guideline.md b/.github/skills/create-modernization-plan/java-upgrade-guideline.md deleted file mode 100644 index 270412a96..000000000 --- a/.github/skills/create-modernization-plan/java-upgrade-guideline.md +++ /dev/null @@ -1,44 +0,0 @@ -# Java Upgrade Task Guidelines - -Only add an upgrade task if the user explicitly requests it. The upgrade task must be the first task if it exists. - -## Latest Stable Versions - -- Java: 25 -- Spring Boot: 4.x -- Spring Framework: 7.x - -## Supported Upgrade Versions - -- Java: 11, 17, 21, 25 -- Spring Boot: 3.x, 4.x -- Spring Framework: 6.x, 7.x - -## Framework Compatibility - -| Spring Boot | Spring Framework | Jakarta EE | Minimum Java | Maximum Java | -|-------------|:----------------:|:----------:|:------------:|:------------:| -| 2.x | 5.x | JavaEE (javax.*) | 8 | 11 | -| 3.x | 6.x | Jakarta EE (jakarta.*) | 17 | 21 | -| 4.x | 7.x | Jakarta EE (jakarta.*) | 25 | 25 | - -## Upgrade Task Types and Included Changes - -| Task Type | Spring Framework Upgrade | Jakarta EE Migration (javax.* → jakarta.*) | JDK/Java | -|-----------|:------------------------:|:------------------------------------------:|:-----------:| -| Spring Boot 4.x upgrade | 7.x | ✓ | 25 | -| Spring Boot 3.x upgrade | 6.x | ✓ | 21 | -| Spring Framework 7.x upgrade | — | ✓ | 25 | -| Spring Framework 6.x upgrade | — | ✓ | 21 | -| Jakarta EE upgrade | — | ✓ | 21 | -| JDK/Java upgrade | — | — | to specified version | - -## Java Task Selection Rules - -When selecting the Java upgrade task type, follow these rules in order: - -- **Rule 1 — No redundant sub-tasks**: Each upgrade type (Spring Boot, Spring Framework, Jakarta EE, JDK/Java) is hierarchical — higher-level tasks already include lower-level ones. Never create a lower-level task that is already covered by a selected higher-level task. For example, if a Spring Boot 4.x upgrade task is selected (which already includes JDK 25), do NOT also create a separate JDK/Java upgrade task. -- **Rule 2 — User-specified framework request doesn't fully match system state**: When the user requests a **framework** upgrade (e.g., Spring Boot, Spring Framework) but the target version they specify is not the latest available, select the highest-level task applicable and prompt the user to clarify. For example, if the user asks to "upgrade Spring Boot to 3.x" but Spring Boot 4.x is available, create a Spring Boot 3.x upgrade task and add a clarification question asking whether they want 4.x. **This rule does NOT apply to pure JDK/Java upgrade requests — see Rule 4.** -- **Rule 3 — User-specified request matches system state**: Select the most closely matching task type that directly matches the user's request and fits the system. For example, if the user asks to "upgrade JDK" and the JDK is outdated, create a JDK/Java upgrade task — NOT a higher-level Spring Boot or Spring Framework upgrade task. -- **Rule 4 — Never upgrade other frameworks on a JDK/Java request**: When the user explicitly requests a JDK/Java upgrade, you MUST NOT upgrade Spring Boot, Spring Framework, or Jakarta EE — create only a JDK/Java upgrade task targeting the user-specified version. If the project's existing Spring Boot, Spring Framework, or Jakarta EE versions are incompatible with the target Java version (per the Framework Compatibility table above), add a clarification question asking the user whether they also want to upgrade the incompatible framework(s) to a compatible version. -- **Rule 5 — Ask for clarification when the selected task diverges from the user's request**: Whenever the task you create differs from what the user explicitly asked for (e.g., upgrading to a different version, choosing a higher-level task type, or skipping a requested change due to compatibility), you MUST use the `ask_user` tool to explain what was selected, why it differs, and ask the user to confirm or adjust. If `ask_user` is not available, add the question to the "## Open Questions" section of `plan.md`. Never silently override the user's intent. \ No newline at end of file diff --git a/.github/skills/create-modernization-plan/plan-template.md b/.github/skills/create-modernization-plan/plan-template.md deleted file mode 100644 index 907521214..000000000 --- a/.github/skills/create-modernization-plan/plan-template.md +++ /dev/null @@ -1,70 +0,0 @@ -# Modernization Plan Template - -Use this template to generate modernization plans for applications. Replace placeholders with actual values and customize content based on the specific modernization scenario. - -**Planning Philosophy**: -- **Focus on GOALS, not implementation**: Describe WHAT needs to be achieved from the user's perspective -- **Skills define HOW**: All implementation details (frameworks, SDKs, libraries, code patterns, authentication methods) will be determined by the referenced skills -- **No assumptions**: Do not assume or specify any technical implementation approach in the plan - let skills handle all "how" decisions - ---- - -# Modernization Plan: [Modernization Title] - -**Project**: [Application Name] - ---- - -## Technical Framework - -**Purpose**: Document the application's current technology stack to provide context for the migration. - -**Template**: -```markdown -- **Language**: [Programming language and version, e.g., Java 11, Python 3.9, .NET 6] -- **Framework**: [Application framework and version, e.g., Spring Boot 2.7.18, Django 4.2, ASP.NET Core 6.0] -- **Build Tool**: [Build system, e.g., Maven 3.9, Gradle 8.0, npm] -- **Database**: [Current database, e.g., Oracle 19c, PostgreSQL 14, SQL Server 2019] -- **Key Dependencies**: [Major libraries/frameworks, e.g., Spring Data JPA, Hibernate, Entity Framework] -``` - ---- - -## Overview - -**Purpose**: Describe the high-level modernization goals without technical details. Focus on business objectives and what will change. - -**Template**: -> This migration [describe what is being migrated]. The application currently [describe current state]. The new architecture will: -> -> - [First key change and its business benefit] -> - [Second key change and its business benefit] -> - [Third key change and its business benefit] -> -> The migration follows [describe phased approach without technical specifics]. - ---- - -## Migration Impact Summary - -**Purpose**: Create a simple table showing migration impact for each application and its affected services. -**Rule**: Each line should be limited to a maximum of 80 characters. -**Template**: -``` -| Application | Original Service | New Azure Service | Authentication | Comments | -|-------------|------------------|-------------------|-------------|----------------|----------| -| [App Name] | [Old Service] | [Azure Service] | [Auth method (Default is Managed Identity if user not specified)] | [User specified request for the migration] | -``` - ---- - -## Open Questions & Questionnaire - -**Purpose**: Record all clarification questions raised during plan creation and their resolution status. Record all answers to questionnaire questions. - -**Template**: -```markdown -- [x] Q: What authentication method should be used for Azure Storage? → A: Use managed identity -- [ ] Which region should the deployment target? -``` - diff --git a/.github/skills/create-modernization-plan/questionnaire.md b/.github/skills/create-modernization-plan/questionnaire.md deleted file mode 100644 index 7a87a9bfa..000000000 --- a/.github/skills/create-modernization-plan/questionnaire.md +++ /dev/null @@ -1,19 +0,0 @@ -# Try to answer these from the user context, and otherwise ask the user where required. - -1. Deployment to Azure -* Azure Container Apps (must include containerization) -* Azure Kubernetes Service (must include containerization) -* Azure App Service -* Azure App Service Managed Instance -* Azure Function App -* Azure Static Web App -* (Default) No deployment - -2. Should the Modernization Plan include Integration Testing? -* Yes, Local Integration with Containers -* Yes, Local Integration and Smoke Tests -* (Default) No - -3. Should the Modernization Plan include Containerization (Dockerfile generation)? -* Yes -* (Default) No \ No newline at end of file diff --git a/.github/skills/create-modernization-plan/security-plan-template.md b/.github/skills/create-modernization-plan/security-plan-template.md deleted file mode 100644 index 3a641b72a..000000000 --- a/.github/skills/create-modernization-plan/security-plan-template.md +++ /dev/null @@ -1,26 +0,0 @@ -## Security Compliance - -**Purpose**: Scan and remediate CVEs (Common Vulnerabilities and Exposures) in project dependencies to ensure the modernized application is free of known security vulnerabilities. - -**Condition**: Always include this task in every modernization plan. Do not include this task if the user explicitly requests that it be removed. - -**Template**: - -**Description**: Scan all project dependencies for known CVEs and remediate any identified vulnerabilities to ensure the application is secure before deployment. - -**Requirements**: - Upgrade vulnerable dependencies to the minimum patched version. If a CVE fix requires a major version upgrade, document the affected dependency, the current version, the upgraded major version, and the breaking change risk. Verify that the project builds and all tests pass after remediation. - If the user provided specific security requirements, incorporate them as well. - -**Environment Configuration**: - Runtime environment established by previous tasks (e.g., Java Home, .NET runtime). - Build tool established by previous tasks (e.g., Maven/Gradle, dotnet). - -**App Scope**: - The app folders that this task will operate on - -**Skills**: - - Skill Name: validate-cves-and-fix - - Skill Location: builtin - - Skill Name: [additional skill if needed] - - Skill Location: [Skill location] \ No newline at end of file diff --git a/.github/skills/create-modernization-plan/supported-patterns-dotnet.md b/.github/skills/create-modernization-plan/supported-patterns-dotnet.md deleted file mode 100644 index 61212775b..000000000 --- a/.github/skills/create-modernization-plan/supported-patterns-dotnet.md +++ /dev/null @@ -1,50 +0,0 @@ -## Supported Task Patterns - -The following are the task patterns supported by the modernize CLI. These patterns are used to identify the modernization tasks that need to be performed based on the user's input. - -The patterns are categorized into two groups, and they should be treated differently if picked: - -* Patterns with skill definitions: These patterns have pre-defined skills that can be used to execute the tasks. If a task matches one of these patterns, the corresponding skill should be used in the task plan. -* Patterns without skill definitions: These patterns do not have pre-defined skills. If a task matches one of these patterns, the description should be used to guide the AI in performing the required tasks. - **IMPORTANT**: The pattern name should NEVER be used as the skill name in the generated plan and tasks.json. They are meant to guide the task generation, not to be directly used as skills. - - -### Task Patterns with Skill Definitions -These patterns have pre-defined skills to assist in their execution. When they are selected in a modernization plan, the corresponding skills should be used. -Each of the item is written in the following format: `- **skill-name**: skill-description`. - -- **azcli-aks-deploy**: Generate plan for deploying to existing Azure Resources for Azure Kubernetes Service, using azcli -- **azcli-appservice-deploy**: Deployment steps for Azure App Service under the AzCLI flow -- **azcli-appservicemi-deploy**: Deployment steps for Azure App Service Managed Identity under the AzCLI flow -- **azcli-containerapp-deploy**: Generate plan for deploying to existing Azure Resources for Azure Container Apps, using azcli -- **azcli-functionapp-deploy**: Deployment steps for Azure Function App under the AzCLI flow -- **containerization**: Setup Dockerfiles for the project to run inside of containers for Azure Container Apps or Azure Kubernetes Service. -- **infrastructure-bicep-generation**: Generate Bicep IaC files for Azure infrastructure provisioning -- **infrastructure-terraform-generation**: Generate Terraform IaC files for Azure infrastructure provisioning -- **migration-azure-communication-email**: This knowledge base provides knowledge about how to use Azure Communication Services for sending emails in .NET applications, covering authentication with Managed Identity, configuration, and email operations. -- **migration-azure-confluent-kafka**: This knowledge base provides knowledge about migrating .NET applications using Confluent.Kafka from local Kafka to Confluent Cloud on Azure, using Azure Managed Identity and DefaultAzureCredential. -- **migration-azure-database-postgresql**: This file provides guidance for migrating .NET applications to Azure Database for PostgreSQL with passwordless Managed Identity, covering both Entity Framework Core and non-EF Core applications. -- **migration-azure-eventhubs-kafka**: This knowledge base provides knowledge about migrating .NET applications using Confluent.Kafka from local Kafka to Azure Event Hubs for Kafka, using Azure Managed Identity and DefaultAzureCredential. -- **migration-azure-keyvault-certificate**: This file provides guidance on using Azure Key Vault certificate management in .NET, covering authentication, configuration, and certificate operations. -- **migration-azure-keyvault-secret**: This file provides guidance on using Azure Key Vault secrets in .NET, covering authentication, configuration, and secret operations. -- **migration-azure-redis-cache**: This knowledge base provides guidance for adding distributed caching with Azure Cache for Redis to .NET applications, or migrating existing caching implementations (in-memory cache, Redis, or other providers) to use Azure Cache for Redis with DefaultAzureCredential (Managed Identity) authentication. -- **migration-azure-servicebus**: This knowledge base provides knowledge about migrating .NET applications to use Azure Service Bus with Managed Identity, covering queue and topic operations, message handling, and processor configurations. -- **migration-azure-sql-database**: This knowledge base provides knowledge about migrating .NET applications to use Azure SQL Database and Azure SQL Managed Instance with Managed Identity authentication, including Entity Framework 6 provider configuration. -- **migration-azure-storage-blob**: This knowledge base provides comprehensive knowledge about using Azure Storage Blob SDK in .NET applications, covering Managed Identity authentication, blob operations, container management, and SAS token generation. -- **migration-azure-storage-mount**: This knowledge base provides knowledge about migrating .NET applications from using hard-coded local file paths to Azure mounted storage paths while maintaining the same functionality. -- **migration-console-logging**: This knowledge base provides knowledge about configuring console logging in .NET applications for cloud environments, ensuring proper log output for container and cloud platform log aggregation. -- **migration-dependency-management**: Comprehensive guide for understanding and implementing dependency management in .NET projects, covering both modern SDK-style projects (.NET Core, .NET 5+) and legacy .NET Framework projects. Includes package reference management, project file structure, and migration considerations. -- **migration-managed-identity**: Comprehensive guidance for migrating .NET applications to use Azure Managed Identity for authentication instead of connection strings, client secrets, certificates, or other credential-based authentication methods. Covers Azure SQL, Storage, Key Vault, Service Bus, Event Hubs, Cosmos DB, and more. -- **migration-microsoft-entra-id**: This knowledge base provides knowledge about migrating .NET applications to use Microsoft Entra ID (formerly Azure AD) for authentication, including ASP.NET Core, ASP.NET Web Forms, and Microsoft Graph integration. -- **migration-opentelemetry-azure**: This guide describes how to implement OpenTelemetry in .NET with Azure Monitor for tracing, metrics, and logging migration. - -### Task Patterns without Skill Definitions -These patterns DO NOT have pre-defined skills. The pattern name and description define the modernization scenario, NOT A SKILL. They are in the format of `- **pattern-name**: pattern-description`. - -A pattern should be selected if it matches one of the customer's requirements, and there are no skills supporting this requirement. - -**IMPORTANT**: -- NEVER write the pattern name as skill name in the generated plan. -- Tasks generated from these patterns must have NO skill assigned. Do not reuse any skill from the "Task Patterns with Skill Definitions" section, even if a skill targets a similar technology or appears related. - - diff --git a/.github/skills/create-modernization-plan/supported-patterns-java.md b/.github/skills/create-modernization-plan/supported-patterns-java.md deleted file mode 100644 index 6ae2dee44..000000000 --- a/.github/skills/create-modernization-plan/supported-patterns-java.md +++ /dev/null @@ -1,88 +0,0 @@ -## Supported Task Patterns - -The following are the task patterns supported by the modernize CLI. These patterns are used to identify the modernization tasks that need to be performed based on the user's input. - -The patterns are categorized into two groups, and they should be treated differently if picked: - -* Patterns with skill definitions: These patterns have pre-defined skills that can be used to execute the tasks. If a task matches one of these patterns, the corresponding skill should be used in the task plan. -* Patterns without skill definitions: These patterns do not have pre-defined skills. If a task matches one of these patterns, the description should be used to guide the AI in performing the required tasks. - **IMPORTANT**: The pattern name should NEVER be used as the skill name in the generated plan and tasks.json. They are meant to guide the task generation, not to be directly used as skills. - - -### Task Patterns with Skill Definitions -These patterns have pre-defined skills to assist in their execution. When they are selected in a modernization plan, the corresponding skills should be used. -Each of the item is written in the following format: `- **skill-name**: skill-description`. - -- **azcli-aks-deploy**: Generate plan for deploying to existing Azure Resources for Azure Kubernetes Service, using azcli -- **azcli-appservice-deploy**: Deployment steps for Azure App Service under the AzCLI flow -- **azcli-appservicemi-deploy**: Deployment steps for Azure App Service Managed Identity under the AzCLI flow -- **azcli-containerapp-deploy**: Generate plan for deploying to existing Azure Resources for Azure Container Apps, using azcli -- **azcli-functionapp-deploy**: Deployment steps for Azure Function App under the AzCLI flow -- **containerization**: Setup Dockerfiles for the project to run inside of containers for Azure Container Apps or Azure Kubernetes Service. -- **infrastructure-bicep-generation**: Generate Bicep IaC files for Azure infrastructure provisioning -- **infrastructure-terraform-generation**: Generate Terraform IaC files for Azure infrastructure provisioning -- **migration-AWS-secrets-manager-to-azure-key-vault**: Migrates Java applications from AWS Secrets Manager (SecretsManagerClient, AWSSecretsManager) to Azure Key Vault SecretClient for secrets management. Use when migrating Java projects from AWS to Azure, replacing AWS secret storage with Azure Key Vault, or modernizing cloud secret management. -- **migration-activemq-servicebus**: Migrates Java Spring Boot applications from ActiveMQ JMS messaging to Azure Service Bus JMS. Replaces ActiveMQ dependencies with Spring Cloud Azure Service Bus JMS starter and updates connection configuration. Use when migrating Spring JMS applications from ActiveMQ to Azure Service Bus or modernizing on-premises messaging to Azure. -- **migration-amqp-rabbitmq-servicebus**: Migrates Java Spring applications from RabbitMQ AMQP messaging to Azure Service Bus via Spring Messaging. Replaces Spring AMQP RabbitMQ dependencies, updates connection settings, and migrates message producers and consumers. Use when migrating Spring applications from RabbitMQ to Azure Service Bus or replacing on-premises message brokers with Azure managed messaging. -- **migration-ant-project-to-maven-project**: Migrates Java projects from Ant build system to Maven, converting build.xml to pom.xml and restructuring directories to Maven standard layout. Use when modernizing Java projects that use Ant builds, converting to Maven for dependency management, or standardizing build tooling. -- **migration-auth-by-mi-for-azure-redis-in-micronaut-project**: Secure Azure Cache for Redis with Managed Identity via Micronaut -- **migration-certificate-management-to-azure-key-vault**: Migrates Java TLS/MTLS certificate management from local KeyStore storage to Azure Key Vault JCA (Java Cryptography Architecture). Replaces local certificate handling with Azure Key Vault for centralized certificate management. Use when migrating Java applications that use local KeyStore, SSLContext, or Certificate classes to Azure Key Vault for secure certificate storage. -- **migration-confluent-cloud-kafka**: Migrates Java applications from self-hosted Apache Kafka to Apache Kafka on Confluent Cloud with passwordless authentication via Microsoft Entra ID. Updates Kafka connection configuration and authentication settings. Use when migrating Java Kafka producers or consumers to Confluent Cloud or enabling passwordless Entra ID authentication for Kafka on Confluent Cloud. -- **migration-cryptography-operations-to-azure-key-vault**: Migrates Java cryptographic operations (Cipher, Signature) from local key management to Azure Key Vault for centralized key management and cryptographic operations. Use when migrating Java applications that use javax.crypto.Cipher or java.security.Signature to Azure Key Vault, or centralizing cryptographic key management in Azure. -- **migration-eclipse-project-to-maven-project**: Migrates Java projects from Eclipse IDE project format (.project, .classpath) to Apache Maven project structure with pom.xml. Converts Eclipse build configuration and classpath settings to Maven conventions. Use when modernizing Eclipse-based Java projects to Maven, converting .project/.classpath files, or standardizing build tooling. -- **migration-ibm-db2-to-azure-postgresql**: Migrate IBM Db2 to Azure Database for PostgreSQL -- **migration-ibm-db2-to-azure-sql**: Migrate IBM Db2 to Azure SQL Database -- **migration-informix-to-postgresql**: Migrates Java application database layer from Informix Database to PostgreSQL, including JDBC driver changes, SQL syntax conversion, and Informix-specific feature replacement. Use when migrating Java applications from Informix to PostgreSQL, converting Informix SQL to PostgreSQL syntax, or replacing Informix JDBC drivers. -- **migration-java-ee-amqp-rabbitmq-servicebus**: Migrates Java EE/Jakarta EE applications from RabbitMQ AMQP messaging to Azure Service Bus SDK. Replaces RabbitMQ client dependencies, migrates publishers and consumers, updates connection management, and maps RabbitMQ concepts (exchanges, queues) to Service Bus equivalents (topics, subscriptions). Use when migrating Java EE or Jakarta EE applications from RabbitMQ to Azure Service Bus. -- **migration-javax.email-send-to-azure-communication-service-email**: Migrates Java applications from JavaMail (javax.mail) API to Azure Communication Service Email for sending emails. Replaces JavaMail email sending, message construction, and authentication with Azure Communication Service equivalents. Use when migrating Java applications from JavaMail or SMTP-based email sending to Azure Communication Service Email. -- **migration-jax-rpc-to-jax-ws**: Migrates Java web service implementations from deprecated JAX-RPC to JAX-WS. Updates web service configuration files and JAX-RPC specific code to use JAX-WS equivalents. Use when modernizing Java web services that use JAX-RPC or upgrading deprecated JAX-RPC APIs to the JAX-WS standard. -- **migration-kafka-to-eventhubs**: Migrates Java applications from Kafka to Azure Event Hubs for Kafka with managed identity for secure, passwordless authentication. Updates Spring Cloud Azure dependencies, Kafka connection settings, and authentication configuration. Use when migrating Java Kafka producers or consumers to Azure Event Hubs, or enabling managed identity authentication for event streaming. -- **migration-log-to-console**: Migrates Java application logging from file-based output to console-only output. Removes file appenders from logging configuration (logback, logging.xml) and ensures all log output goes to console. Use when containerizing Java applications, migrating to cloud-native logging, or preparing Java apps for Azure where console logging is preferred. -- **migration-mi-azure-sql**: Migrates Java Spring Boot projects from password-based authentication to Azure Managed Identity for connecting to Azure SQL Database. Updates Spring Cloud Azure dependencies and datasource configuration for passwordless authentication. Use when enabling managed identity for Azure SQL Database connections, removing hardcoded database passwords, or securing Java Spring Boot database authentication. -- **migration-mi-cassandra**: Migrates Java applications to connect to Azure Cosmos DB for Apache Cassandra using managed identity via Service Connector in Azure public cloud. Updates CqlSession configuration and Spring Data Cassandra properties. Use when migrating Java or Spring Boot applications to Azure Cosmos DB Cassandra API, enabling managed identity for Cassandra connections, or replacing Cassandra password authentication. -- **migration-mi-eventhub**: Migrates Java projects from password-based authentication to Azure Managed Identity for connecting to Azure Event Hubs. Adds Spring Cloud Azure dependencies and updates Event Hubs and Kafka configuration for passwordless authentication. Use when enabling managed identity for Azure Event Hubs in Java applications, removing Event Hubs connection string passwords, or securing event streaming authentication. -- **migration-mi-mariadb**: Migrates Java applications from password-based MariaDB authentication to Azure Managed Identity for Azure Database for MariaDB in public cloud using AzureMysqlAuthenticationPlugin. Updates JDBC connection and authentication configuration. Use when enabling managed identity for Azure Database for MariaDB, removing MariaDB passwords, or implementing credential-free MariaDB authentication in Azure. -- **migration-mi-mongodb**: Migrate from password-based authentication to Microsoft Entra ID authentication for Azure DocumentDB (with MongoDB Compatibility) in Java projects -- **migration-mi-mysql**: Migrates Java Spring Boot projects from password-based MySQL authentication to Azure Managed Identity for Azure Database for MySQL. Updates Spring Cloud Azure dependencies and datasource configuration for passwordless authentication. Use when enabling managed identity for Azure MySQL connections in Spring Boot, removing hardcoded MySQL passwords, or securing Spring datasource authentication. -- **migration-mi-postgresql**: Migrates Java Spring Boot projects from password-based PostgreSQL authentication to Azure Managed Identity for Azure Database for PostgreSQL. Updates Spring Cloud Azure dependencies and datasource configuration for passwordless authentication. Use when enabling managed identity for Azure PostgreSQL connections in Spring Boot, removing hardcoded PostgreSQL passwords, or securing Spring datasource authentication. -- **migration-mi-servicebus**: Azure Service Bus Managed Identity via Spring -- **migration-on-premises-user-authentication-to-microsoft-entra-id**: Migrates Java Spring Boot application user authentication from on-premises login to Microsoft Entra ID using spring-cloud-azure-starter-active-directory and spring-boot-starter-oauth2-client. Use when migrating Java web application authentication to Microsoft Entra ID, modernizing on-premises login to cloud identity, or adding Azure Active Directory authentication. -- **migration-oracle-to-postgresql**: Migrates Java application database layer from Oracle Database to PostgreSQL, including JDBC driver changes, SQL syntax conversion, and Oracle-specific feature replacement. Uses project-specific coding_notes.md guidance when available. Use when migrating Java applications from Oracle to PostgreSQL, converting Oracle SQL to PostgreSQL syntax, or replacing Oracle JDBC drivers. -- **migration-other-cache-solutions-to-azure-managed-cache**: Migrate other cache solutions to use Redis, and potentially to Azure Managed Redis / Azure Cache for Redis (retiring) while following best practices. Use this skill when users want to migrate other cache solutions to use Redis, such as Apache Commons JCS, DynaCache, Embedded cache, JCache, OSCache, ShiftOne, Oracle Coherence, etc., or local Redis to Azure Managed Redis / Azure Cache for Redis (retiring) with secure authentication changes. -- **migration-plaintext-credential-to-azure-keyvault**: Migrates hardcoded plaintext credentials (passwords, secrets, API keys, connection strings, tokens) in Java source code to Azure Key Vault for secure storage and retrieval. Use when securing Java applications by removing hardcoded credentials, migrating plaintext secrets to Azure Key Vault, or implementing centralized secret management. -- **migration-s3-to-azure-blob-storage**: Migrates Java applications from Amazon S3 SDK to Azure Blob Storage SDK, including bucket/container operations, object storage, access policies, and SAS token generation. Use when migrating Java applications from AWS S3 to Azure Blob Storage, replacing S3Client with BlobServiceClient, or converting AWS storage APIs to Azure equivalents. -- **migration-spring-jms-rabbitmq-servicebus**: Migrates Java Spring Boot applications from RabbitMQ JMS messaging to Azure Service Bus JMS. Replaces RabbitMQ JMS dependencies with Spring Cloud Azure Service Bus JMS starter and updates connection configuration. Use when migrating Spring JMS applications from RabbitMQ to Azure Service Bus, replacing RMQConnectionFactory, or modernizing JMS messaging to Azure. -- **migration-sqs-to-servicebus**: Migrates Java applications from AWS Simple Queue Service (SQS) to Azure Service Bus for message queuing. Replaces AWS SQS SDK dependencies with Azure Service Bus SDK, updates message sending and receiving code, and migrates queue configuration. Use when migrating Java applications from AWS SQS to Azure Service Bus, replacing SQS client code, or modernizing cloud message queuing to Azure. -- **migration-sybase-ase-to-azure-sql-database**: Migrates Java application database layer from Sybase ASE (Adaptive Server Enterprise) to Azure SQL Database with passwordless managed identity authentication. Use when migrating Java applications from Sybase ASE to Azure SQL. - -### Task Patterns without Skill Definitions -These patterns DO NOT have pre-defined skills. The pattern name and description define the modernization scenario, NOT A SKILL. They are in the format of `- **pattern-name**: pattern-description`. - -A pattern should be selected if it matches one of the customer's requirements, and there are no skills supporting this requirement. - -**IMPORTANT**: -- NEVER write the pattern name as skill name in the generated plan. -- Tasks generated from these patterns must have NO skill assigned. Do not reuse any skill from the "Task Patterns with Skill Definitions" section, even if a skill targets a similar technology or appears related. - -- **amazon-kinesis-to-azure-event-hubs**: Amazon Kinesis to Azure Event Hubs -- **amazon-sns-to-azure-service-bus**: Amazon SNS to Azure Service Bus -- **apache-pulsar-to-azure-event-hubs**: Apache Pulsar to Azure Event Hubs -- **aws-lambda-to-azure-functions**: AWS Lambda to Azure Functions -- **firebird-to-azure-postgresql**: Firebird to Azure PostgreSQL -- **google-cloud-bigtable-to-azure-cosmos-db**: Google Cloud Bigtable to Azure Cosmos DB -- **google-cloud-functions-to-azure-functions**: Google Cloud Functions to Azure Functions -- **google-cloud-pub-sub-to-azure-service-bus**: Google Cloud Pub/Sub to Azure Service Bus -- **google-cloud-spanner-to-azure-postgresql**: Google Cloud Spanner to Azure PostgreSQL -- **google-cloud-storage-to-azure-blob-storage**: Google Cloud Storage to Azure Blob Storage -- **google-firestore-to-azure-cosmos-db**: Google Firestore to Azure Cosmos DB -- **ibm-db2-to-azure-postgresql**: IBM DB2 to Azure PostgreSQL -- **ibm-mq-jms-to-azure-service-bus**: IBM MQ JMS to Azure Service Bus -- **migration-local-certificate-management-to-azure-key-vault**: Local certificate management to Azure Key Vault -- **migration-local-files-to-mounted-azure-storage**: Local files to mounted Azure Storage paths (starts with `${AZURE_MOUNT_PATH:/mnt/azure}`) -- **quartz-scheduler-to-azure-functions**: Quartz Scheduler to Azure Functions -- **solace-pubsub-to-azure-service-bus**: Solace PubSub+ to Azure Service Bus -- **spring-batch-to-azure-durable-functions**: Spring Batch to Azure Durable Functions -- **spring-cloud-config-to-azure-app-configuration**: Spring Cloud Config to Azure App Configuration -- **sqlite-to-azure-postgresql**: SQLite to Azure PostgreSQL -- **sybase-ase-to-azure-postgresql**: Sybase ASE to Azure Database for PostgreSQL -- **tibco-ems-jms-to-azure-service-bus**: TIBCO EMS JMS to Azure Service Bus diff --git a/.github/skills/create-modernization-plan/tasks-schema.json b/.github/skills/create-modernization-plan/tasks-schema.json deleted file mode 100644 index 397678e03..000000000 --- a/.github/skills/create-modernization-plan/tasks-schema.json +++ /dev/null @@ -1,349 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "Modernization Tasks Template", - "description": "Schema for tasks-template.json. Preserve field descriptions because they are used to generate the JSON by LLM.", - "type": "object", - "required": ["$schema", "description", "tasks", "metadata"], - "additionalProperties": false, - "properties": { - "$schema": { - "type": "string", - "description": "JSON Schema reference used by the template." - }, - "description": { - "type": "string", - "description": "Tasks template for modernization plan. Generate this file alongside plan.md to track individual migration tasks." - }, - "tasks": { - "type": "array", - "description": "List of individual migration tasks.", - "items": { - "oneOf": [ - { "$ref": "#/$defs/transformTask" }, - { "$ref": "#/$defs/upgradeTask" }, - { "$ref": "#/$defs/integrationTestTask" }, - { "$ref": "#/$defs/containerizationTask" }, - { "$ref": "#/$defs/deploymentTask" }, - { "$ref": "#/$defs/securityTask" }, - { "$ref": "#/$defs/infrastructureTask" } - ] - } - }, - "metadata": { - "type": "object", - "description": "Metadata for the plan.", - "additionalProperties": false, - "required": ["planName", "projectName", "language", "createdAt", "version"], - "properties": { - "planName": { - "type": "string", - "description": "[Plan name]" - }, - "projectName": { - "type": "string", - "description": "[Application Name]" - }, - "language": { - "type": "string", - "description": "[Programming language]" - }, - "createdAt": { - "type": "string", - "description": "[ISO 8601 timestamp]", - "format": "date-time" - }, - "version": { - "type": "string", - "description": "Version of the template schema.", - "const": "1.0" - } - } - } - }, - "$defs": { - "taskBase": { - "type": "object", - "additionalProperties": false, - "required": ["type", "id", "description", "requirements"], - "properties": { - "type": { - "type": "string", - "description": "Task type identifier." - }, - "id": { - "type": "string", - "description": "[Unique identifier for this task, start with sequence and category name, like '001-transform-migration-rabbitmq-to-servicebus']" - }, - "description": { - "type": "string", - "description": "[Brief description of what this task achieves from the user's perspective. It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" - }, - "reason": { - "type": "string", - "description": "[Explain why this task is needed, e.g., the motivation, business justification, or technical necessity that drives this task]" - }, - "requirements": { - "type": "string", - "description": "[The specific requirements for this task including: what to migrate (features, APIs, patterns), constraints (backward compatibility, modules to avoid), target Azure services, and technical preferences (authentication methods, patterns). It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" - }, - "environmentConfiguration": { - "type": ["string"], - "description": "[Environment configuration from user input (e.g. endpoint, access id). Omit this field if not specified]" - }, - "status": { - "type": ["string"], - "description": "Task execution status. Only has value after task is executed.", - "enum": ["pending", "started", "success", "failed", "skipped"] - }, - "taskSummary": { - "type": "string", - "description": "Summary of task execution result. Only has value after task is executed." - }, - "dependencies": { - "type": "array", - "description": "[List of task IDs that this task depends on. The task will only be executed after all its dependencies have completed successfully.]", - "items": { - "type": "string" - } - } - } - }, - "skill": { - "type": "object", - "additionalProperties": false, - "required": ["name", "location"], - "properties": { - "name": { - "type": "string", - "description": "[The skill name that will be used for this task, e.g., 'migration-rabbitmq-to-servicebus'.]" - }, - "location": { - "type": "string", - "description": "Skill location: project, remote and builtin, builtin is renamed from custom", - "enum": ["project","remote","builtin"] - } - } - }, - "successCriteria": { - "type": "object", - "additionalProperties": false, - "required": [ - "passBuild", - "generateNewUnitTests", - "passUnitTests" - ], - "description": "The task success criteria to validate after task execution.", - "properties": { - "passBuild": { - "type": ["string"], - "default": "true", - "description": "Project must compile successfully after migration, use default value if user does not specify" - }, - "generateNewUnitTests": { - "type": ["string"], - "default": "false", - "description": "Create mock-based unit tests for newly added Azure integration code to ensure test coverage, use default value if user does not specify" - }, - "passUnitTests": { - "type": ["string"], - "default": "true", - "description": "All unit tests must pass; mock dependent Azure resources if not provided, use default value if user does not specify" - } - } - }, - "successCriteriaStatus": { - "type": "object", - "not": { - "type": "null" - }, - "additionalProperties": false, - "description": "Optional validation status for each success criterion. Omit this field until validation is complete. If present, use true/false string values.", - "properties": { - "passBuild": { - "type": ["string"], - "description": "Validation status of passBuild criterion. true means passed, false means failed." - }, - "generateNewUnitTests": { - "type": ["string"], - "description": "Validation status of generateNewUnitTests criterion. true means passed, false means failed." - }, - "passUnitTests": { - "type": ["string"], - "description": "Validation status of passUnitTests criterion. true means passed, false means failed." - } - } - }, - "transformTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "successCriteria"], - "properties": { - "type": { - "const": "transform", - "description": "transform task template" - }, - "skills": { - "type": "array", - "description": "The skills that will be used for this task, it is started with migration and looks like 'migration-rabbitmq-to-servicebus-mi'", - "items": { "$ref": "#/$defs/skill" } - }, - "successCriteria": { "$ref": "#/$defs/successCriteria" }, - "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } - } - } - ] - }, - "upgradeTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "successCriteria"], - "properties": { - "type": { - "const": "upgrade", - "description": "Upgrade task template" - }, - "successCriteria": { "$ref": "#/$defs/successCriteria" }, - "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } - } - } - ] - }, - "containerizationTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "dockerfilePath"], - "properties": { - "type": { - "const": "containerization", - "description": "Containerization task template - Only include if the target deployment requires containerization (e.g., AKS, ACA) or if the user explicitly requested containerization. Skip for non-containerized deployments." - }, - "dockerfilePath": { - "type": "string", - "description": "[Path to Dockerfile, indicate if existing or to be created]" - } - } - } - ] - }, - "deploymentTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "targetAzureService", "resourceStatus", "deploymentTool", "skills"], - "properties": { - "type": { - "const": "deployment", - "description": "Deployment task template - Containerize, provision and deploy the application to Azure. Only include if the user explicitly requested deployment." - }, - "skills": { - "type": "array", - "description": "The deployment skill to use based on targetAzureService: 'azcli-aks-deploy' for Azure Kubernetes Service, 'azcli-containerapp-deploy' for Azure Container Apps, 'azcli-appservice-deploy' for Azure App Service, 'azcli-functionapp-deploy' for Azure Function App, 'azcli-appservicemi-deploy' for Azure App Service with Managed Identity", - "items": { "$ref": "#/$defs/skill" } - }, - "targetAzureService": { - "type": "string", - "description": "[Azure service name, e.g., Azure Container Apps, AKS, App Service]" - }, - "resourceStatus": { - "type": "string", - "description": "[Specify if using existing resource or will create new service]" - }, - "deploymentTool": { - "type": "string", - "description": "Infrastructure as Code tool type. Default to 'terraform' for aks, 'bicep' for other services if not specified.", - "enum": ["bicep", "terraform"] - } - } - } - ] - }, - "integrationTestTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "layers"], - "properties": { - "type": { - "const": "integrationTest", - "description": "Integration test task template - Generate and run integration tests for migrated Azure services. Only include when user explicitly requests integration testing. This task runs after all transform/upgrade tasks but before containerization." - }, - "layers": { - "type": "array", - "description": "[Array of test layers to execute, e.g., [1, 2] for Layer 1 (Local Integration with TestContainers) and Layer 2 (Smoke Tests)]", - "items": { - "type": "number", - "enum": [1, 2] - }, - "minItems": 1 - } - } - } - ] - }, - "securityTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "successCriteria"], - "properties": { - "type": { - "const": "security", - "description": "Security task template - Include when security remediation, vulnerability scanning, or compliance checks are required." - }, - "cveReport": { - "type": ["string"], - "description": "Path to final-cve-report.json. Only has value after CVE checking is complete." - }, - "successCriteria": { "$ref": "#/$defs/successCriteria" }, - "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } - } - } - ] - }, - "infrastructureTask": { - "allOf": [ - { "$ref": "#/$defs/taskBase" }, - { - "type": "object", - "additionalProperties": false, - "required": ["type", "skills", "iacType", "provision"], - "properties": { - "type": { - "const": "infrastructure", - "description": "Infrastructure task template - Generate IaC files (Bicep or Terraform) to provision Azure resources." - }, - "iacType": { - "type": "string", - "description": "Infrastructure as Code tool type.", - "enum": ["bicep", "terraform"] - }, - "provision": { - "type": "boolean", - "description": "Whether to provision Azure resources after generating IaC files." - }, - "skills": { - "type": "array", - "description": "The skill used for this task, e.g., 'infrastructure-bicep-generation' or 'infrastructure-terraform-generation'", - "items": { "$ref": "#/$defs/skill" } - } - } - } - ] - } - } -} diff --git a/.github/skills/cve-known-vulnerabilities/SKILL.md b/.github/skills/cve-known-vulnerabilities/SKILL.md deleted file mode 100644 index 2ab39f825..000000000 --- a/.github/skills/cve-known-vulnerabilities/SKILL.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -name: cve-known-vulnerabilities -description: Detect known CVE vulnerabilities in Java project dependencies using the GitHub Security Advisories API ---- - -# CVE Security Assessment: Known Dependency Vulnerabilities - -## Role - -You are a **dependency security scanner**. Your task is to programmatically collect the project's Java dependencies, query the GitHub Security Advisories API for known CVEs, and report findings in a structured JSON format. - -> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether known CVE vulnerabilities exist in the project's dependencies. You may recommend dependency upgrades to patched versions, but do NOT make code changes or modify build files yourself. - -## Objective - -Identify all known CVE vulnerabilities in the project's direct and transitive dependencies by: -1. Detecting the build tool (Maven or Gradle) -2. Collecting dependency coordinates (`groupId:artifactId:version`) -3. Querying the GitHub Security Advisories API -4. Reporting findings in structured JSON format - -## Instructions - -### Step 1: Detect Build Tool - -Check which build tool the project uses: - -```bash -if [ -f "pom.xml" ]; then - BUILD_TOOL="maven" -elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then - BUILD_TOOL="gradle" -else - echo "No supported Java build tool found" - mkdir -p security - printf '[]\n' > security/cve-assessment-result.json - exit 0 -fi -``` - -### Step 2: Collect Dependencies - -#### Maven Projects - -Try the CLI approach first (produces the most accurate results): - -```bash -# Detect wrapper vs bare command -if [ -f "./mvnw" ]; then MVN_CMD="./mvnw"; elif [ -f "./mvnw.cmd" ]; then MVN_CMD="./mvnw.cmd"; else MVN_CMD="mvn"; fi - -# Collect all dependencies as a tree (direct + transitive with parent chain) -$MVN_CMD dependency:tree -DoutputFile=/tmp/mvn-deps.txt -DappendOutput=true -B -q 2>/dev/null -``` - -Parse the output file. The tree format uses indentation to show the dependency hierarchy: -- The root line is the project itself (depth 0) — skip it. -- Depth-1 entries (prefixed with `+- ` or `\- `) are **direct** dependencies. -- Depth-2+ entries are **transitive** dependencies, nested under the direct dependency that pulls them in. -- Each entry has the format: `groupId:artifactId:packaging:version:scope` (5 parts) or `groupId:artifactId:packaging:classifier:version:scope` (6 parts). Extract `groupId:artifactId:version` from each. - -For transitive dependencies (depth 2+), trace them back to their depth-1 ancestor (the direct dependency that pulls them in), and use that direct dependency's declaration line number in the evidence. - -**Fallback** — if the CLI command fails or is unavailable, parse `pom.xml` files directly (direct dependencies only): -- Find all `pom.xml` files (excluding `target/`, `node_modules/`, `.git/`) -- Extract `<dependency>` elements: `<groupId>`, `<artifactId>`, `<version>` -- Resolve `${property}` references from the `<properties>` section of the same POM -- Skip dependencies where the version cannot be resolved - -#### Gradle Projects - -Try the CLI approach first: - -```bash -# Detect wrapper vs bare command -if [ -f "./gradlew" ]; then GRADLE_CMD="./gradlew"; elif [ -f "./gradlew.bat" ]; then GRADLE_CMD="./gradlew.bat"; else GRADLE_CMD="gradle"; fi - -# In multi-project builds, Gradle automatically runs the task on all subprojects -$GRADLE_CMD dependencies --configuration runtimeClasspath -q 2>/dev/null -``` - -Parse the dependency tree output. The tree format uses indentation to show the dependency hierarchy: -- Depth-1 entries (top-level `+---` or `\---`) are **direct** dependencies. -- Depth-2+ entries (nested under a direct dependency) are **transitive** dependencies. - -For each dependency line: -- Only process lines containing `---` (tree markers like `+---` or `\---`) -- Strip tree formatting characters (`+---`, `\---`, `|`, leading whitespace) -- Handle version conflict resolution: `group:artifact:1.0 -> 2.0` means use version `2.0` -- Skip `project :submodule` entries and entries with `FAILED` versions -- Remove `(*)` duplicate markers and `(c)` constraint markers -- Extract `groupId:artifactId:version` - -For transitive dependencies (depth 2+), trace them back to their depth-1 ancestor (the direct dependency that pulls them in), and use that direct dependency's declaration line number in the evidence. - -**Fallback** — if the CLI command fails, parse `build.gradle` / `build.gradle.kts` files (direct dependencies only): -- Look for dependency declarations: `implementation`, `api`, `compileOnly`, `runtimeOnly`, etc. -- Extract GAV from patterns like `implementation 'group:artifact:version'` or `implementation("group:artifact:version")` -- Skip entries where the version contains `$` (unresolved properties) - -### Step 3: Query GitHub Security Advisories API - -Resolve the GitHub token and query the API: - -```bash -# Resolve token -TOKEN="${GITHUB_TOKEN:-$(gh auth token 2>/dev/null)}" -``` - -**IMPORTANT: Batch dependencies in groups of 30** to avoid URL length limits. - -For each batch, construct the `affects` parameter and query: - -```bash -# Build the affects parameter: groupId:artifactId@version,groupId:artifactId@version,... -# URL-encode the affects value - -# Query using gh api (preferred — avoids firewall issues): -gh api "/advisories?ecosystem=maven&affects=${ENCODED_AFFECTS}&per_page=100" \ - --header "X-GitHub-Api-Version: 2022-11-28" \ - --paginate -``` - -If `gh api` is not available, fall back to `curl`. Only include the `Authorization` header when a token is available; omit it for unauthenticated requests: - -```bash -AUTH_HEADER="" -if [ -n "$TOKEN" ]; then - AUTH_HEADER="-H \"Authorization: Bearer $TOKEN\"" -fi - -eval curl -s -H "Accept: application/vnd.github+json" \ - $AUTH_HEADER \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - "https://api.github.com/advisories?ecosystem=maven&affects=${ENCODED_AFFECTS}&per_page=100" -``` - -**Handle pagination**: If using `curl`, check the `Link` response header for `rel="next"` and follow it until there are no more pages. - -### Step 4: Process API Results - -For each advisory returned: -1. **Skip** advisories where `withdrawn_at` is not null (withdrawn advisories) -2. **Extract** the CVE ID from `cve_id` (fall back to `ghsa_id` if `cve_id` is null) -3. **Extract** severity from the `severity` field -4. **Extract** `summary`, `description`, and `html_url` -5. **Extract** affected package details from `vulnerabilities[]`: `package.name`, `vulnerable_version_range`, `first_patched_version` - -### Step 5: Format and Locate Evidence - -For each CVE found: -1. Identify which build files (`pom.xml`, `build.gradle`, `build.gradle.kts`) declare the affected dependency -2. Find the line number where the dependency is declared (if possible) -3. Build the evidence with file paths (e.g., `pom.xml:42`) and a detailed explanation including: - - Link to the CVE advisory - - Severity level - - List of affected dependencies with their declaration locations - - Recommended fix (upgrade to patched version if available) - -## Output Format - -Write the result as a **flat JSON array** (NOT wrapped in a result envelope) to the output file. - -If **no vulnerabilities are found**, write an empty array: `[]` - -If **vulnerabilities are found**, write an array of finding objects: - -```json -[ - { - "id": "CVE-2024-22233", - "name": "Spring Framework URL parsing vulnerability", - "status": "FOUND", - "category": "CVE", - "severity": "high", - "storyPoint": 1, - "evidence": { - "files": ["pom.xml:42", "module-b/pom.xml:18"], - "explanation": "[CVE-2024-22233](https://github.com/advisories/GHSA-xxxx): Spring Framework URL parsing vulnerability\n\nSeverity: HIGH\n\nAffected dependencies:\n - org.springframework:spring-core:5.3.20 (declared at pom.xml:42)\n - io.netty:netty-codec-http:4.1.86 (transitive, pulled by spring-boot-starter-web at pom.xml:42)\n\nRecommended fix:\n - Upgrade org.springframework:spring-core to 5.3.27 or later" - } - } -] -``` - -### Field Requirements - -- **id**: The CVE identifier (e.g., `CVE-2024-22233`), or GHSA ID if no CVE ID exists -- **name**: The advisory summary text -- **status**: Always `"FOUND"` for reported vulnerabilities -- **category**: Always `"CVE"` -- **severity**: The raw GitHub Advisory severity: `"critical"`, `"high"`, `"medium"`, or `"low"` -- **storyPoint**: Always `1` -- **evidence.files**: Array of workspace-relative file paths where affected dependencies are declared (with optional `:lineNumber` suffix). For transitive dependencies, use the line number of the direct dependency that pulls them in (e.g., if `netty-codec-http` is pulled in by `spring-boot-starter-web` declared at `pom.xml:42`, use `pom.xml:42`) -- **evidence.explanation**: Markdown-formatted description including CVE link, severity, affected dependencies with locations, and recommended fix - -### Important Notes - -- If a single CVE affects multiple dependencies, group them into ONE finding with all affected dependencies listed in the explanation -- If no build tool is detected, write `[]` and skip the assessment -- If the GitHub token is unavailable, proceed anyway (unauthenticated rate limits apply) -- If the API query fails, write `[]` and log the error -- Deduplicate: if the same CVE appears across multiple API batches, merge into a single finding diff --git a/.github/skills/cwe-code-quality/SKILL.md b/.github/skills/cwe-code-quality/SKILL.md deleted file mode 100644 index 9785ba5a3..000000000 --- a/.github/skills/cwe-code-quality/SKILL.md +++ /dev/null @@ -1,153 +0,0 @@ ---- -name: cwe-code-quality -description: Assess codebase for CWE code quality vulnerabilities (CWE-130, CWE-456, CWE-457, CWE-477, CWE-570, CWE-571, CWE-606, CWE-665, CWE-681, CWE-682, CWE-772, CWE-775, CWE-783, CWE-789, CWE-835, CWE-1057) ---- - -# CWE Security Assessment: Code Quality - -## Role - -You are an expert **code security reviewer** specializing in CWE vulnerability detection. - -> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. - -## Objective - -Analyze the application codebase for each of the 16 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. - -## CWE Rules to Assess - -### CWE-130: Improper Handling of Length Parameter Inconsistency -- **Severity:** potential | **Story Points:** 3 -- **Description:** The product parses a formatted message or structure, but it does not handle or incorrectly handles a length field that is inconsistent with the actual length of the associated data. - -### CWE-456: Missing Initialization of a Variable -- **Severity:** potential | **Story Points:** 2 -- **Description:** The product does not initialize critical variables, which causes the execution environment to use unexpected values. - -### CWE-457: Use of Uninitialized Variable -- **Severity:** potential | **Story Points:** 2 -- **Description:** The code uses a variable that has not been initialized, leading to unpredictable or unintended results. - -### CWE-477: Use of Obsolete Function -- **Severity:** optional | **Story Points:** 1 -- **Description:** The code uses deprecated or obsolete functions, which suggests that the code has not been actively reviewed or maintained. - -### CWE-570: Expression is Always False -- **Severity:** optional | **Story Points:** 1 -- **Description:** The product contains an expression that will always evaluate to false. - -### CWE-571: Expression is Always True -- **Severity:** optional | **Story Points:** 1 -- **Description:** The product contains an expression that will always evaluate to true. - -### CWE-606: Unchecked Input for Loop Condition -- **Severity:** potential | **Story Points:** 3 -- **Description:** The product does not properly check inputs that are used for loop conditions, potentially leading to a denial of service or other consequences because of excessive looping. - -### CWE-665: Improper Initialization -- **Severity:** potential | **Story Points:** 3 -- **Description:** The product does not initialize or incorrectly initializes a resource, which might leave the resource in an unexpected state when it is accessed or used. - -### CWE-681: Incorrect Conversion between Numeric Types -- **Severity:** potential | **Story Points:** 3 -- **Description:** When converting from one data type to another, such as long to integer, data can be omitted or translated in a way that produces unexpected values. If the resulting values are used in a sensitive context, then dangerous behaviors may occur. - -### CWE-682: Incorrect Calculation -- **Severity:** potential | **Story Points:** 5 -- **Description:** The product performs a calculation that generates incorrect or unintended results that are later used in security-critical decisions or resource management. - -### CWE-772: Missing Release of Resource after Effective Lifetime -- **Severity:** potential | **Story Points:** 3 -- **Description:** The product does not release a resource after its effective lifetime has ended, i.e., after the resource is no longer needed. - -### CWE-775: Missing Release of File Descriptor or Handle after Effective Lifetime -- **Severity:** potential | **Story Points:** 3 -- **Description:** The product does not release a file descriptor or handle after its effective lifetime has ended, i.e., after the file descriptor/handle is no longer needed. - -### CWE-783: Operator Precedence Logic Error -- **Severity:** optional | **Story Points:** 1 -- **Description:** The product uses an expression in which operator precedence causes incorrect logic to be used. - -### CWE-789: Memory Allocation with Excessive Size Value -- **Severity:** potential | **Story Points:** 5 -- **Description:** The product allocates memory based on an untrusted, large size value, but it does not ensure that the size is within expected limits, allowing arbitrary amounts of memory to be allocated. - -### CWE-835: Loop with Unreachable Exit Condition ('Infinite Loop') -- **Severity:** potential | **Story Points:** 3 -- **Description:** The product contains an iteration or loop with an exit condition that cannot be reached, i.e., an infinite loop. - -### CWE-1057: Data Access Operations Outside of Expected Data Manager Component -- **Severity:** potential | **Story Points:** 5 -- **Description:** The product uses a dedicated, central data manager component as required by design, but it contains code that performs data-access operations that do not use this data manager. - -## Instructions - -1. **Iterate through each CWE rule** listed above -2. **Systematically scan** the application source code for patterns matching each rule -3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match -4. **Continue to the next rule** after finding a match or exhausting the search -5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) - -### Search Strategy - -- Start with common vulnerability patterns: user input handling, external data processing, resource management -- Check configuration files, API endpoints, data access layers, and utility classes -- Consider both direct patterns and indirect/transitive vulnerability paths -- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code - -## Output Format - -Use the `write_assessment_result` tool to save results with the following JSON structure: - -```json -{ - "input_name": "CWE - Code Quality", - "analysis_method": "LLM", - "status": "success", - "result": { - "finding": "Assessed 16 CWE rules in Code Quality: X FOUND, Y NOT_FOUND", - "confidence": "high", - "evidence": ["Scanned application source files for code quality patterns"], - "values": [ - { - "id": "<CWE-XXX>", - "name": "<Rule Name>", - "status": "FOUND", - "category": "Code Quality", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": ["src/path/to/File.java"], - "explanation": "Description of the vulnerability found, including class/method and line reference" - } - }, - { - "id": "<CWE-YYY>", - "name": "<Rule Name>", - "status": "NOT_FOUND", - "category": "Code Quality", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": [], - "explanation": "" - } - } - ] - }, - "execution_time_seconds": 0, - "timestamp": "" -} -``` - -### Evidence Rules - -- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. -- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. -- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. -- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. -- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. -- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/cwe-concurrency-synchronization/SKILL.md b/.github/skills/cwe-concurrency-synchronization/SKILL.md deleted file mode 100644 index 7ff74ae9e..000000000 --- a/.github/skills/cwe-concurrency-synchronization/SKILL.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -name: cwe-concurrency-synchronization -description: Assess codebase for CWE concurrency & synchronization vulnerabilities (CWE-543, CWE-567, CWE-662, CWE-667, CWE-820, CWE-821) ---- - -# CWE Security Assessment: Concurrency & Synchronization - -## Role - -You are an expert **code security reviewer** specializing in CWE vulnerability detection. - -> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. - -## Objective - -Analyze the application codebase for each of the 6 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. - -## CWE Rules to Assess - -### CWE-543: Use of Singleton Pattern Without Synchronization in a Multithreaded Context -- **Severity:** potential | **Story Points:** 5 -- **Description:** The product uses the singleton pattern when creating a resource within a multithreaded environment. - -### CWE-567: Unsynchronized Access to Shared Data in a Multithreaded Context -- **Severity:** potential | **Story Points:** 5 -- **Description:** The product does not properly synchronize shared data, such as static variables across threads, which can lead to undefined behavior and unpredictable data changes. - -### CWE-662: Improper Synchronization -- **Severity:** potential | **Story Points:** 8 -- **Description:** The product utilizes multiple threads or processes to allow temporary access to a shared resource that can only be exclusive to one process at a time, but it does not properly synchronize these actions, which might cause simultaneous accesses of this resource by multiple threads or processes. - -### CWE-667: Improper Locking -- **Severity:** potential | **Story Points:** 8 -- **Description:** The product does not properly acquire or release a lock on a resource, leading to unexpected resource state changes and behaviors. - -### CWE-820: Missing Synchronization -- **Severity:** potential | **Story Points:** 8 -- **Description:** The product utilizes a shared resource in a concurrent manner but does not attempt to synchronize access to the resource. - -### CWE-821: Incorrect Synchronization -- **Severity:** potential | **Story Points:** 8 -- **Description:** The product utilizes a shared resource in a concurrent manner, but it does not correctly synchronize access to the resource. - -## Instructions - -1. **Iterate through each CWE rule** listed above -2. **Systematically scan** the application source code for patterns matching each rule -3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match -4. **Continue to the next rule** after finding a match or exhausting the search -5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) - -### Search Strategy - -- Start with common vulnerability patterns: user input handling, external data processing, resource management -- Check configuration files, API endpoints, data access layers, and utility classes -- Consider both direct patterns and indirect/transitive vulnerability paths -- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code - -## Output Format - -Use the `write_assessment_result` tool to save results with the following JSON structure: - -```json -{ - "input_name": "CWE - Concurrency & Synchronization", - "analysis_method": "LLM", - "status": "success", - "result": { - "finding": "Assessed 6 CWE rules in Concurrency & Synchronization: X FOUND, Y NOT_FOUND", - "confidence": "high", - "evidence": ["Scanned application source files for concurrency & synchronization patterns"], - "values": [ - { - "id": "<CWE-XXX>", - "name": "<Rule Name>", - "status": "FOUND", - "category": "Concurrency & Synchronization", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": ["src/path/to/File.java"], - "explanation": "Description of the vulnerability found, including class/method and line reference" - } - }, - { - "id": "<CWE-YYY>", - "name": "<Rule Name>", - "status": "NOT_FOUND", - "category": "Concurrency & Synchronization", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": [], - "explanation": "" - } - } - ] - }, - "execution_time_seconds": 0, - "timestamp": "" -} -``` - -### Evidence Rules - -- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. -- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. -- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. -- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. -- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. -- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/cwe-credentials-secrets/SKILL.md b/.github/skills/cwe-credentials-secrets/SKILL.md deleted file mode 100644 index fe1e29b6f..000000000 --- a/.github/skills/cwe-credentials-secrets/SKILL.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -name: cwe-credentials-secrets -description: Assess codebase for CWE credentials & secrets vulnerabilities (CWE-259, CWE-321, CWE-732, CWE-778, CWE-798) ---- - -# CWE Security Assessment: Credentials & Secrets - -## Role - -You are an expert **code security reviewer** specializing in CWE vulnerability detection. - -> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. - -## Objective - -Analyze the application codebase for each of the 5 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. - -## CWE Rules to Assess - -### CWE-259: Use of Hard-coded Password -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product contains a hard-coded password, which it uses for its own inbound authentication or for outbound communication to external components. - -### CWE-321: Use of Hard-coded Cryptographic Key -- **Severity:** potential | **Story Points:** 5 -- **Description:** The product uses a hard-coded, unchangeable cryptographic key. - -### CWE-732: Incorrect Permission Assignment for Critical Resource -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product specifies permissions for a security-critical resource in a way that allows that resource to be read or modified by unintended actors. - -### CWE-778: Insufficient Logging -- **Severity:** potential | **Story Points:** 3 -- **Description:** When a security-critical event occurs, the product either does not record the event or omits important details about the event when logging it. - -### CWE-798: Use of Hard-coded Credentials -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product contains hard-coded credentials, such as a password or cryptographic key. - -## Instructions - -1. **Iterate through each CWE rule** listed above -2. **Systematically scan** the application source code for patterns matching each rule -3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match -4. **Continue to the next rule** after finding a match or exhausting the search -5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) - -### Search Strategy - -- Start with common vulnerability patterns: user input handling, external data processing, resource management -- Check configuration files, API endpoints, data access layers, and utility classes -- Consider both direct patterns and indirect/transitive vulnerability paths -- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code - -## Output Format - -Use the `write_assessment_result` tool to save results with the following JSON structure: - -```json -{ - "input_name": "CWE - Credentials & Secrets", - "analysis_method": "LLM", - "status": "success", - "result": { - "finding": "Assessed 5 CWE rules in Credentials & Secrets: X FOUND, Y NOT_FOUND", - "confidence": "high", - "evidence": ["Scanned application source files for credentials & secrets patterns"], - "values": [ - { - "id": "<CWE-XXX>", - "name": "<Rule Name>", - "status": "FOUND", - "category": "Credentials & Secrets", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": ["src/path/to/File.java"], - "explanation": "Description of the vulnerability found, including class/method and line reference" - } - }, - { - "id": "<CWE-YYY>", - "name": "<Rule Name>", - "status": "NOT_FOUND", - "category": "Credentials & Secrets", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": [], - "explanation": "" - } - } - ] - }, - "execution_time_seconds": 0, - "timestamp": "" -} -``` - -### Evidence Rules - -- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. -- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. -- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. -- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. -- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. -- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/cwe-file-path-security/SKILL.md b/.github/skills/cwe-file-path-security/SKILL.md deleted file mode 100644 index 1cac17b05..000000000 --- a/.github/skills/cwe-file-path-security/SKILL.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -name: cwe-file-path-security -description: Assess codebase for CWE file & path security vulnerabilities (CWE-22, CWE-23, CWE-36, CWE-434, CWE-611) ---- - -# CWE Security Assessment: File & Path Security - -## Role - -You are an expert **code security reviewer** specializing in CWE vulnerability detection. - -> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. - -## Objective - -Analyze the application codebase for each of the 5 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. - -## CWE Rules to Assess - -### CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') -- **Severity:** optional | **Story Points:** 8 -- **Description:** The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory. - -### CWE-23: Relative Path Traversal -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product uses external input to construct a pathname that should be within a restricted directory, but it does not properly neutralize sequences such as .. that can resolve to a location that is outside of that directory. - -### CWE-36: Absolute Path Traversal -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product uses external input to construct a pathname that should be within a restricted directory, but it does not properly neutralize absolute path sequences such as /abs/path that can resolve to a location that is outside of that directory. - -### CWE-434: Unrestricted Upload of File with Dangerous Type -- **Severity:** mandatory | **Story Points:** 8 -- **Description:** The product allows the upload or transfer of dangerous file types that are automatically processed within its environment. - -### CWE-611: Improper Restriction of XML External Entity Reference -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product processes an XML document that can contain XML entities with URIs that resolve to documents outside of the intended sphere of control, causing the product to embed incorrect documents into its output. - -## Instructions - -1. **Iterate through each CWE rule** listed above -2. **Systematically scan** the application source code for patterns matching each rule -3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match -4. **Continue to the next rule** after finding a match or exhausting the search -5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) - -### Search Strategy - -- Start with common vulnerability patterns: user input handling, external data processing, resource management -- Check configuration files, API endpoints, data access layers, and utility classes -- Consider both direct patterns and indirect/transitive vulnerability paths -- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code - -## Output Format - -Use the `write_assessment_result` tool to save results with the following JSON structure: - -```json -{ - "input_name": "CWE - File & Path Security", - "analysis_method": "LLM", - "status": "success", - "result": { - "finding": "Assessed 5 CWE rules in File & Path Security: X FOUND, Y NOT_FOUND", - "confidence": "high", - "evidence": ["Scanned application source files for file & path security patterns"], - "values": [ - { - "id": "<CWE-XXX>", - "name": "<Rule Name>", - "status": "FOUND", - "category": "File & Path Security", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": ["src/path/to/File.java"], - "explanation": "Description of the vulnerability found, including class/method and line reference" - } - }, - { - "id": "<CWE-YYY>", - "name": "<Rule Name>", - "status": "NOT_FOUND", - "category": "File & Path Security", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": [], - "explanation": "" - } - } - ] - }, - "execution_time_seconds": 0, - "timestamp": "" -} -``` - -### Evidence Rules - -- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. -- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. -- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. -- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. -- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. -- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/cwe-injection-attacks/SKILL.md b/.github/skills/cwe-injection-attacks/SKILL.md deleted file mode 100644 index 347105abb..000000000 --- a/.github/skills/cwe-injection-attacks/SKILL.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -name: cwe-injection-attacks -description: Assess codebase for CWE injection attacks vulnerabilities (CWE-77, CWE-78, CWE-79, CWE-88, CWE-89, CWE-90, CWE-91, CWE-99, CWE-502, CWE-564, CWE-643, CWE-652) ---- - -# CWE Security Assessment: Injection Attacks - -## Role - -You are an expert **code security reviewer** specializing in CWE vulnerability detection. - -> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. - -## Objective - -Analyze the application codebase for each of the 12 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. - -## CWE Rules to Assess - -### CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection') -- **Severity:** mandatory | **Story Points:** 13 -- **Description:** The product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component. - -### CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') -- **Severity:** mandatory | **Story Points:** 13 -- **Description:** The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component. - -### CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') -- **Severity:** optional | **Story Points:** 8 -- **Description:** The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users. - -### CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product constructs a string for a command to be executed by a separate component in another control sphere, but it does not properly delimit the intended arguments, options, or switches within that command string. - -### CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') -- **Severity:** mandatory | **Story Points:** 13 -- **Description:** The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data. - -### CWE-90: Improper Neutralization of Special Elements used in an LDAP Query ('LDAP Injection') -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product constructs all or part of an LDAP query using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended LDAP query when it is sent to a downstream component. - -### CWE-91: XML Injection (aka Blind XPath Injection) -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product does not properly neutralize special elements that are used in XML, allowing attackers to modify the syntax, content, or commands of the XML before it is processed by an end system. - -### CWE-99: Improper Control of Resource Identifiers ('Resource Injection') -- **Severity:** potential | **Story Points:** 3 -- **Description:** The product receives input from an upstream component, but it does not restrict or incorrectly restricts the input before it is used as an identifier for a resource that may be outside the intended sphere of control. - -### CWE-502: Deserialization of Untrusted Data -- **Severity:** mandatory | **Story Points:** 13 -- **Description:** The product deserializes untrusted data without sufficiently ensuring that the resulting data will be valid. - -### CWE-564: SQL Injection: Hibernate -- **Severity:** mandatory | **Story Points:** 8 -- **Description:** Using Hibernate to execute a dynamic SQL statement built with user-controlled input can allow an attacker to modify the statement's meaning or to execute arbitrary SQL commands. - -### CWE-643: Improper Neutralization of Data within XPath Expressions ('XPath Injection') -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product uses external input to dynamically construct an XPath expression used to retrieve data from an XML database, but it does not neutralize or incorrectly neutralizes that input. This allows an attacker to control the structure of the query. - -### CWE-652: Improper Neutralization of Data within XQuery Expressions ('XQuery Injection') -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product uses external input to dynamically construct an XQuery expression used to retrieve data from an XML database, but it does not neutralize or incorrectly neutralizes that input. This allows an attacker to control the structure of the query. - -## Instructions - -1. **Iterate through each CWE rule** listed above -2. **Systematically scan** the application source code for patterns matching each rule -3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match -4. **Continue to the next rule** after finding a match or exhausting the search -5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) - -### Search Strategy - -- Start with common vulnerability patterns: user input handling, external data processing, resource management -- Check configuration files, API endpoints, data access layers, and utility classes -- Consider both direct patterns and indirect/transitive vulnerability paths -- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code - -## Output Format - -Use the `write_assessment_result` tool to save results with the following JSON structure: - -```json -{ - "input_name": "CWE - Injection Attacks", - "analysis_method": "LLM", - "status": "success", - "result": { - "finding": "Assessed 12 CWE rules in Injection Attacks: X FOUND, Y NOT_FOUND", - "confidence": "high", - "evidence": ["Scanned application source files for injection attacks patterns"], - "values": [ - { - "id": "<CWE-XXX>", - "name": "<Rule Name>", - "status": "FOUND", - "category": "Injection Attacks", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": ["src/path/to/File.java"], - "explanation": "Description of the vulnerability found, including class/method and line reference" - } - }, - { - "id": "<CWE-YYY>", - "name": "<Rule Name>", - "status": "NOT_FOUND", - "category": "Injection Attacks", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": [], - "explanation": "" - } - } - ] - }, - "execution_time_seconds": 0, - "timestamp": "" -} -``` - -### Evidence Rules - -- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. -- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. -- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. -- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. -- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. -- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/cwe-memory-safety/SKILL.md b/.github/skills/cwe-memory-safety/SKILL.md deleted file mode 100644 index be7ffa439..000000000 --- a/.github/skills/cwe-memory-safety/SKILL.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -name: cwe-memory-safety -description: Assess codebase for CWE memory safety vulnerabilities (CWE-119, CWE-120, CWE-123, CWE-125, CWE-415, CWE-416, CWE-672, CWE-786, CWE-787, CWE-788, CWE-805, CWE-822, CWE-823, CWE-824, CWE-825) ---- - -# CWE Security Assessment: Memory Safety - -## Role - -You are an expert **code security reviewer** specializing in CWE vulnerability detection. - -> **Important:** You are an auditor, NOT an implementation developer. Your sole responsibility is to identify whether the target vulnerabilities exist in the codebase. Do NOT suggest fixes or improvements. - -## Objective - -Analyze the application codebase for each of the 15 CWE rules listed below. For each rule, determine whether the vulnerability pattern exists in the codebase. - -## CWE Rules to Assess - -### CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer -- **Severity:** mandatory | **Story Points:** 21 -- **Description:** The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data. - -### CWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow') -- **Severity:** mandatory | **Story Points:** 13 -- **Description:** The product copies an input buffer to an output buffer without verifying that the size of the input buffer is less than the size of the output buffer. - -### CWE-123: Write-what-where Condition -- **Severity:** mandatory | **Story Points:** 13 -- **Description:** Any condition where the attacker has the ability to write an arbitrary value to an arbitrary location, often as the result of a buffer overflow. - -### CWE-125: Out-of-bounds Read -- **Severity:** optional | **Story Points:** 8 -- **Description:** The product reads data past the end, or before the beginning, of the intended buffer. - -### CWE-415: Double Free -- **Severity:** optional | **Story Points:** 8 -- **Description:** The product calls free() twice on the same memory address. - -### CWE-416: Use After Free -- **Severity:** mandatory | **Story Points:** 13 -- **Description:** The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory belongs to the code that operates on the new pointer. - -### CWE-672: Operation on a Resource after Expiration or Release -- **Severity:** potential | **Story Points:** 5 -- **Description:** The product uses, accesses, or otherwise operates on a resource after that resource has been expired, released, or revoked. - -### CWE-786: Access of Memory Location Before Start of Buffer -- **Severity:** optional | **Story Points:** 8 -- **Description:** The product reads or writes to a buffer using an index or pointer that references a memory location prior to the beginning of the buffer. - -### CWE-787: Out-of-bounds Write -- **Severity:** mandatory | **Story Points:** 13 -- **Description:** The product writes data past the end, or before the beginning, of the intended buffer. - -### CWE-788: Access of Memory Location After End of Buffer -- **Severity:** optional | **Story Points:** 8 -- **Description:** The product reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. - -### CWE-805: Buffer Access with Incorrect Length Value -- **Severity:** optional | **Story Points:** 8 -- **Description:** The product uses a sequential operation to read or write a buffer, but it uses an incorrect length value that causes it to access memory that is outside of the bounds of the buffer. - -### CWE-822: Untrusted Pointer Dereference -- **Severity:** optional | **Story Points:** 8 -- **Description:** The product obtains a value from an untrusted source, converts this value to a pointer, and dereferences the resulting pointer. - -### CWE-823: Use of Out-of-range Pointer Offset -- **Severity:** optional | **Story Points:** 8 -- **Description:** The product performs pointer arithmetic on a valid pointer, but it uses an offset that can point outside of the intended range of valid memory locations for the resulting pointer. - -### CWE-824: Access of Uninitialized Pointer -- **Severity:** optional | **Story Points:** 5 -- **Description:** The product accesses or uses a pointer that has not been initialized. - -### CWE-825: Expired Pointer Dereference -- **Severity:** optional | **Story Points:** 8 -- **Description:** The product dereferences a pointer that contains a location for memory that was previously valid, but is no longer valid. - -## Instructions - -1. **Iterate through each CWE rule** listed above -2. **Systematically scan** the application source code for patterns matching each rule -3. **For each rule:** Stop scanning as soon as you find the FIRST confirmed match -4. **Continue to the next rule** after finding a match or exhausting the search -5. **Report findings** for ALL rules (both FOUND and NOT_FOUND) - -### Search Strategy - -- Start with common vulnerability patterns: user input handling, external data processing, resource management -- Check configuration files, API endpoints, data access layers, and utility classes -- Consider both direct patterns and indirect/transitive vulnerability paths -- Focus on source files (e.g., `.java`, `.py`, `.cs`, `.js`, `.ts`) — skip test files and generated code - -## Output Format - -Use the `write_assessment_result` tool to save results with the following JSON structure: - -```json -{ - "input_name": "CWE - Memory Safety", - "analysis_method": "LLM", - "status": "success", - "result": { - "finding": "Assessed 15 CWE rules in Memory Safety: X FOUND, Y NOT_FOUND", - "confidence": "high", - "evidence": ["Scanned application source files for memory safety patterns"], - "values": [ - { - "id": "<CWE-XXX>", - "name": "<Rule Name>", - "status": "FOUND", - "category": "Memory Safety", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": ["src/path/to/File.java"], - "explanation": "Description of the vulnerability found, including class/method and line reference" - } - }, - { - "id": "<CWE-YYY>", - "name": "<Rule Name>", - "status": "NOT_FOUND", - "category": "Memory Safety", - "severity": "<mandatory|optional|potential — copy from the rule definition above>", - "storyPoint": "<N — copy from the rule definition above>", - "description": "<copy the Description from the rule definition above>", - "evidence": { - "files": [], - "explanation": "" - } - } - ] - }, - "execution_time_seconds": 0, - "timestamp": "" -} -``` - -### Evidence Rules - -- **FOUND**: `files` must contain workspace-relative file paths. `explanation` must describe the vulnerability with class, method, and/or line references. -- **NOT_FOUND**: `files` must be an empty array `[]`. `explanation` must be an empty string `""`. -- **Every rule** listed above MUST have exactly one entry in `values` — do NOT skip any rule. -- **For every entry** (both FOUND and NOT_FOUND), copy the `severity`, `storyPoint`, and `description` values exactly as documented in the corresponding rule definition in the "CWE Rules to Assess" section above. -- Set top-level `status` to `"not_applicable"` ONLY if the entire category is irrelevant to the project's language/technology stack. -- Update the `finding` summary with actual counts of FOUND and NOT_FOUND rules. diff --git a/.github/skills/data-architecture/SKILL.md b/.github/skills/data-architecture/SKILL.md deleted file mode 100644 index 4dd3a43d6..000000000 --- a/.github/skills/data-architecture/SKILL.md +++ /dev/null @@ -1,227 +0,0 @@ ---- -name: data-architecture -description: Generate data architecture and persistence layer documentation with data model diagram ---- - -# Data Architecture & Persistence Layer - -Analyze the project to document database configuration, entity models, data ownership boundaries, repository interfaces, and caching strategies. Generate a Mermaid ER diagram showing entity relationships. Save to `.github/modernize/assessment/engines/data-architecture.md`. - -## Input Parameters - -- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) - -## Scope Boundaries — Avoid Redundancy with Other Skills - -This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: - -- **Introduction**: Write a 1-2 sentence intro focused on the data layer (number of entities, database types, ORM). Do NOT restate the application's overall architecture type, web framework, or API surface — those are covered by other skills. -- **Configuration property keys/values** (e.g., `spring.jpa.hibernate.ddl-auto`, `spring.sql.init.*`) are owned by the `configuration-inventory` skill. In the Database Configuration table, describe the *behavior* (e.g., "Hibernate does not manage schema; SQL scripts are authoritative") but do NOT list raw property key-value pairs. Reference `configuration-inventory.md` for the full property inventory. -- **API endpoints and HTTP methods** are owned by the `api-service-contracts` skill. Do NOT list controller endpoints or HTTP paths. Repository methods are in scope for this skill; controller routes are not. -- **Business workflow steps and validation rules** are owned by the `business-workflows` skill. Do NOT describe multi-step business processes or enumerate validation constraints. When documenting entity relationships (cascade, fetch), focus on the persistence/ORM implications, not the business process flow. -- **Deployment configurations** (Docker Compose, K8s, profiles) are owned by the `configuration-inventory` skill. Mention database profiles only in the Database Configuration table to identify which DB is used per profile — do NOT describe Docker Compose services, K8s manifests, or deployment targets in detail. - -## Execution Steps - -### Step 1: Generate Database Configuration Section - -Extract database configuration from project files, **per profile/environment**, and produce the complete `## Database Configuration` section: - -- Database types: HSQLDB, MySQL, PostgreSQL, MongoDB, SQL Server, Oracle, SQLite, CosmosDB, DynamoDB -- **Per-profile configuration**: identify which database is used in each profile (e.g., HSQLDB for `default`/dev in-memory testing, MySQL for `production`/`mysql` profile) -- Database drivers per profile (e.g., `mysql-connector-java` for production, `hsqldb` for development) -- Connection configuration: connection strings, JDBC URLs, pooling settings (HikariCP, connection pool size) -- Migration tools: Flyway, Liquibase, EF Migrations, Alembic, Prisma Migrate, Knex migrations -- Schema management: DDL auto-generation settings (`spring.jpa.hibernate.ddl-auto`), schema versioning, initial schema scripts -- Seed data: `data.sql`, `import.sql`, seed migration files, or programmatic data seeding - -### Step 2: Generate Data Ownership per Service Section - -Determine table/entity ownership across modules/services and produce the complete `## Data Ownership per Service` section. Scope is strictly the per-service ownership table — high-level data boundary discussion belongs in Step 6. - -For each module/service, identify: - -- Which tables/entities it owns (bounded context analysis) -- ORM framework used (e.g., Hibernate, EF Core, MyBatis, Mongoose) -- Caching layer used by this service (if any) -- Brief notes (e.g., outbox table, schema-per-service) - -> Do NOT include shared-vs-isolated data store summary, cross-service data access patterns, or read/write/CQRS observations here — those belong in the `## Data Ownership Boundaries` section (Step 6). - -### Step 3: Generate Entity Model Section - -Scan source code for data access patterns and ORM entities, then produce the complete `## Entity Model` section: - -**Analysis:** -- Java: JPA/Hibernate entities (`@Entity`, `@Table`), Spring Data repositories (`JpaRepository`, `CrudRepository`), MyBatis mappers, JDBC templates -- .NET: EF Core `DbContext`, EF Core entities, Dapper, ADO.NET -- JavaScript/TypeScript: Mongoose models/schemas, Sequelize models, TypeORM entities, Prisma schema, Knex migrations - -Identify: -- Entity/model classes with their fields, types, and constraints — note the source file path for each entity -- Transaction management annotations/configuration (`@Transactional`, `TransactionScope`, etc.) -- Bidirectional vs unidirectional relationship mappings (e.g., `owner.addPet(pet)` establishing parent-child links) - -**Diagram — Mermaid `erDiagram`:** -- Show primary entities with key fields (PK, FK) -- Use standard cardinality notation: `||--o{` (one-to-many), `||--||` (one-to-one), `}o--o{` (many-to-many) -- Group related entities logically -- Include relationship labels -- Annotate which service owns each entity group (use comments or subgraph labels) - -Example: - -~~~mermaid -erDiagram - Owner ||--o{ Pet : "has" - Pet ||--o{ Visit : "has" - Pet }o--|| PetType : "is of" - Vet }o--o{ Specialty : "has" - Owner { - int id PK - string firstName - string lastName - string address - string city - string telephone - } - Pet { - int id PK - string name - date birthDate - int ownerId FK - int typeId FK - } - PetType { - int id PK - string name - } - Visit { - int id PK - int petId FK - date visitDate - string description - } - Vet { - int id PK - string firstName - string lastName - } - Specialty { - int id PK - string name - } -~~~ - -### Step 4: Generate Key Repository Methods Section - -For each service/module, document the key repository interfaces and produce the complete `## Key Repository Methods` section: - -- Repository interface name, entity type, and source file path -- Standard CRUD methods inherited from base interface -- Custom query methods with their signatures and purposes — especially: - - Bulk/batch queries (e.g., `findByPetIdIn(Collection<Integer>)`) used for cross-service aggregation - - Custom finders with derived query methods - - Named queries or `@Query`-annotated methods - - Raw SQL or stored procedure calls -- Query method parameters and return types - -### Step 5: Generate Caching Strategy Section - -Identify caching layers and configuration and produce the complete `## Caching Strategy` section: - -- Cache providers: EhCache, Redis, Caffeine, Spring Cache (`@Cacheable`, `@CacheEvict`), MemoryCache, IDistributedCache -- Cache configuration: TTL, eviction policies, cache regions/names -- Cache-aside, read-through, write-through, write-behind patterns -- Session caching, query result caching, second-level cache (Hibernate) -- Rationale for caching decisions (e.g., "veterinarian data is read frequently but changes rarely") -- JSR-107 (JCache) / `cache-api` usage and provider binding - -### Step 6: Generate Data Ownership Boundaries Section - -Document data-store topology and cross-service access semantics, plus data classification, then produce the complete `## Data Ownership Boundaries` section (including the `### Data Classification & Sensitivity` subsection): - -**Boundaries:** -- Shared vs isolated data stores (shared database, database-per-service, logical separation within shared DB) -- Cross-service data access patterns: how one service queries another service's data (direct DB access vs REST API calls vs batch/bulk query methods such as `findByPetIdIn(...)` that enable gateway-level aggregation) -- Read/write patterns and CQRS observations across services - -**Data Classification & Sensitivity (`### Data Classification & Sensitivity` subsection):** -- Identify whether stored data contains sensitive categories — PII (names, addresses, phone numbers, emails), PHI (health records), PCI (payment card data) -- For each sensitive category found, note whether encryption-at-rest, data masking, or field-level access controls are in place -- If absent, state this explicitly (e.g., "Owner entity stores PII (firstName, lastName, address, telephone); no encryption-at-rest or masking configured") - -### Step 7: Save Output - -Save to `.github/modernize/assessment/engines/data-architecture.md` with this exact structure: - -``` -# Data Architecture & Persistence Layer - -A brief introduction (1-2 sentences) summarizing the data layer. - -## Database Configuration - -[Table: Service/Module | DB Type | Profile | Driver | Connection | Migration Tool] - -## Data Ownership per Service - -[Table: Service | Tables Owned | ORM Framework | Caching | Notes] - -## Entity Model - -< Mermaid erDiagram here > - -## Key Repository Methods - -[Table: Service | Repository | Notable Methods | Purpose] - -## Caching Strategy - -[Table or description of caching layers, providers, TTL, patterns, and rationale] - -## Data Ownership Boundaries - -[Description of shared vs isolated data stores, cross-service data access patterns, and aggregation enablers] - -### Data Classification & Sensitivity - -[Table: Entity | Sensitive Fields | Classification (PII/PHI/PCI/None) | Controls in Place] -[If no sensitive data found: "No PII, PHI, or PCI data detected in entity model."] -``` - -## Scaling Rules - -- If the project has **more than 30 entities**, aggregate minor entities and show only the core domain model (15-20 key entities) -- Keep the ER diagram under **40 entities** to ensure readability and GitHub rendering compatibility -- For multi-module projects, focus on inter-module entity relationships and data boundaries -- Collapse join tables into relationship annotations rather than showing them as separate entities -- In the repository methods table, focus on non-CRUD custom methods; omit standard inherited methods - -## Mermaid Syntax Rules - -- Use `erDiagram` -- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in entity/field names — use plain text -- Use standard cardinality: `||--o{`, `||--||`, `}o--o{`, `|o--o{` -- Use quoted relationship labels: `Owner ||--o{ Pet : "has"` -- Do not use backticks inside entity or field names -- **Never put `{` or `}` inside a quoted attribute description or relationship label.** Mermaid's ER parser treats `{` as the entity-body opener even inside quotes, which crashes the entire diagram with "Syntax error in text". Avoid placeholder syntax like `{userId}`, `{path}`, or `{id}` in attribute comments — write `userId`, `path`, `id` (or describe in plain words: "indexed by user id"). Example: - - ❌ `string Key PK "Redis key /basket/{BuyerId}"` - - ✅ `string Key PK "Redis key /basket/<BuyerId>"` or `"Redis key prefixed with /basket/"` - -## Error Handling - -- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` -- **No data access layer found**: Output: `> ERROR: No recognized data access patterns or entities found at {workspace-path}. Verify the path is correct.` -- **Insufficient info**: Generate a best-effort diagram from available data. Add a note: `> Note: Some entities or relationships could not be fully identified.` - -## Success Criteria - -- Database configuration table lists all discovered databases with type, profile, driver, and migration tools -- Data ownership table maps each service to its owned tables, ORM, and caching layer -- Mermaid ER diagram renders correctly showing entity relationships with cardinality and key fields -- Repository methods table documents custom query methods with purposes, especially cross-service aggregation enablers -- Caching strategy section describes cache providers, patterns, and rationale -- Data ownership boundaries describe shared vs isolated stores and cross-service data access patterns -- Data Classification & Sensitivity table identifies PII/PHI/PCI fields and documents presence or absence of controls -- File saved to `.github/modernize/assessment/engines/data-architecture.md` diff --git a/.github/skills/dependency-map/SKILL.md b/.github/skills/dependency-map/SKILL.md deleted file mode 100644 index 60a929e78..000000000 --- a/.github/skills/dependency-map/SKILL.md +++ /dev/null @@ -1,180 +0,0 @@ ---- -name: dependency-map -description: Generate dependency map diagram from project build files ---- - -# Dependency Map - -Analyze project build and package files to generate a visual map of all external dependencies grouped by functional category. Save to `.github/modernize/assessment/engines/dependency-map.md`. - -This skill focuses exclusively on **declared external dependencies** (libraries, frameworks, packages). For internal application structure and component relationships, see the `architecture-diagram` skill. - -## Input Parameters - -- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) - -## Execution Steps - -### Step 1: Generate Dependencies Section - -Analyze build files and produce the complete `## Dependencies` section in one pass: - -**Analysis — examine only build and package management files** (do NOT scan source code — that is the `architecture-diagram` skill's job): - -- Java: pom.xml, build.gradle, settings.gradle, gradle.properties, gradle lockfiles -- .NET: *.csproj, Directory.Build.props, packages.config, Directory.Packages.props -- JavaScript/TypeScript: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml - -For each dependency extract: -- Group/package name and artifact name -- Declared version (or version range) -- Scope (compile, runtime, test, provided) - -Also detect: -- Parent POM / BOM imports (Java) -- Central package management (.NET Directory.Packages.props) -- Transitive dependencies where visible from lock files or BOM - -**Categorize** dependencies into functional groups: - -| Category | Examples | -|----------|----------| -| Web Frameworks | Spring Web, ASP.NET Core MVC, JAX-RS | -| Database / ORM | Hibernate, Entity Framework, JDBC drivers | -| Messaging | Kafka client, RabbitMQ, Azure Service Bus | -| Caching | Redis, EhCache, MemoryCache | -| Logging | SLF4J, Log4j, Serilog, NLog | -| Security | Spring Security, Microsoft.Identity, OAuth libs | -| Observability | Micrometer, OpenTelemetry, Application Insights | -| Utilities | Guava, Apache Commons, Lombok, AutoMapper | - -Rules: -- Exclude test-scoped dependencies (JUnit, xUnit, Mockito, etc.) from the main diagram and Dependency Summary table — they are not relevant for modernization planning -- If a dependency doesn't fit any category, put it under "Utilities" -- Collect test-scoped dependencies separately for the Test Dependencies section (Step 2) - -**Diagram — Mermaid `flowchart LR`:** -- Application as the central left-side node -- One `subgraph` per functional category -- Each dependency as a node showing name and version: `Lib["Library Name v1.2.3"]` -- Arrows from Application to each category subgraph -- If a BOM/parent POM manages versions, show it as a separate node linked to the dependencies it governs - -Example: - -~~~mermaid -flowchart LR - App["MyApplication"] - - subgraph Web["Web Frameworks"] - SpringMVC["Spring MVC 5.3.x"] - Thymeleaf["Thymeleaf 3.0"] - end - subgraph DB["Database / ORM"] - Hibernate["Hibernate 5.6"] - PgDriver["PostgreSQL Driver 42.6"] - end - subgraph Messaging - Kafka["Kafka Client 3.4"] - end - subgraph Cache["Caching"] - Redis["Jedis 4.3"] - end - subgraph Log["Logging"] - SLF4J["SLF4J 1.7"] - Logback["Logback 1.2"] - end - subgraph Sec["Security"] - SpringSec["Spring Security 5.7"] - end - subgraph Util["Utilities"] - Lombok["Lombok 1.18"] - Jackson["Jackson 2.14"] - end - - App -->|"web"| Web - App -->|"persistence"| DB - App -->|"messaging"| Messaging - App -->|"caching"| Cache - App -->|"logging"| Log - App -->|"security"| Sec - App -->|"utilities"| Util - SLF4J -.->|"implementation"| Logback -~~~ - -**Textual explanations (write immediately after the diagram):** -- **Dependency Summary table**: Category | Count | Key Libraries | Notes (e.g., Web Frameworks | 2 | ASP.NET MVC 5.2.7, Razor 3.2.7 | Legacy MVC stack on .NET Framework) -- **Version & Compatibility Risks**: A short paragraph highlighting dependencies that are outdated, end-of-life, or have known migration concerns (e.g., ".NET Framework 4.7.2 is in maintenance mode; Entity Framework 6 has a migration path to EF Core") -- **Notable Observations**: 2-4 bullet points on anything noteworthy — duplicate functionality across libraries, deprecated packages, security-sensitive dependencies, or unusually large transitive trees - -### Step 2: Generate Test Dependencies Section - -Collect all test-scoped dependencies (excluded from the main diagram) and produce the complete `## Test Dependencies` section: - -- List detected test frameworks and supporting libraries with their versions (e.g., JUnit 5, Mockito, AssertJ, Testcontainers, xUnit, Jest) -- Report the total number of test-scope dependencies -- Note any test infrastructure concerns (e.g., outdated test framework version, missing contract-testing library, no integration test framework detected) - -### Step 3: Save Output - -Save to `.github/modernize/assessment/engines/dependency-map.md` with this exact structure: - -``` -# Dependency Map - -A brief introduction (1-2 sentences) stating project name and total dependency count. - -## Dependencies - -< Mermaid flowchart LR here > - -### Dependency Summary - -[Table: Category | Count | Key Libraries | Notes] - -### Version & Compatibility Risks - -[Short paragraph on outdated or end-of-life dependencies] - -### Notable Observations - -[2-4 bullet points on noteworthy findings] - -## Test Dependencies - -[Table: Framework | Version | Notes] - -Total test-scope dependencies: N -[1-2 sentences on test infrastructure observations, or "No test dependencies detected."] -``` - -## Scaling Rules - -- If the project has **more than 50 declared dependencies**, collapse minor utilities into a single aggregate node (e.g., `Utils["12 utility libraries"]`) and only show individually the top dependencies by importance -- Keep the diagram under **40 nodes** to ensure readability and GitHub rendering compatibility -- For multi-module projects (e.g., multi-module Maven/Gradle, multi-project .sln), show shared dependencies once and module-specific dependencies grouped by module - -## Mermaid Syntax Rules - -- Use `flowchart LR` -- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in node labels — use plain text -- Always quote arrow labels with double quotes: `-->|"label"|` -- Use `subgraph` for grouping, with a display name in quotes if it contains spaces -- Use `-.->` (dotted arrow) for transitive/indirect relationships -- Verify all node IDs are unique across the entire diagram - -## Error Handling - -- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` -- **No build files found**: Output: `> ERROR: No recognized build files found at {workspace-path}. Verify the path is correct.` -- **Incomplete dependency info**: Generate a best-effort diagram from available data. Add a note inside the diagram: `Note["Some dependencies could not be fully resolved"]` - -## Success Criteria - -- Mermaid diagram renders correctly with dependencies grouped by functional category -- Each dependency shows name and version -- Dependency Summary table lists categories with counts and key libraries -- Version & Compatibility Risks paragraph highlights outdated or end-of-life dependencies -- Notable Observations lists 2-4 noteworthy findings -- Test Dependencies section lists detected test frameworks with versions and total count -- File saved to `.github/modernize/assessment/engines/dependency-map.md` diff --git a/.github/skills/execute-java-upgrade-task/SKILL.md b/.github/skills/execute-java-upgrade-task/SKILL.md deleted file mode 100644 index d605768ee..000000000 --- a/.github/skills/execute-java-upgrade-task/SKILL.md +++ /dev/null @@ -1,376 +0,0 @@ ---- -name: execute-java-upgrade-task -description: Execute a Java upgrade task as part of a modernization plan ---- - -You are an expert Java upgrade agent. **Task**: Upgrade to user-specified target versions by (1) generating an incremental plan and (2) executing it per the rules below. - -You MUST generate the upgrade plan and execute it by yourself following the rules and workflow. You are now in the "modernize-java" agent. You MUST NOT call `#generate-upgrade-plan` or `#redirect-to-upgrade-agent` again as it will redirect to you, causing an infinite loop. - -## Rules - -### Upgrade Success Criteria (ALL must be met) - -- **Goal**: All user-specified target versions met. -- **Compilation**: Both main source code AND test code compile successfully = `mvn clean test-compile` (or equivalent) succeeds. This includes compiling production code and all test classes. -- **Test**: **100% test pass rate** = `mvn clean test` succeeds. Minimum acceptable: test pass rate ≥ baseline (pre-upgrade pass rate). Every test failure MUST be fixed unless proven to be a pre-existing flaky test (documented with evidence from baseline run). **Skip if user set "Run tests before and after the upgrade: false" in plan.md Options.** - -### Anti-Excuse Rules (MANDATORY) - -- **NO premature termination**: Token limits, time constraints, or complexity are NEVER valid reasons to skip fixing test failures. -- **NO "close enough" acceptance**: 95% is NOT 100%. Every failing test requires a fix attempt with documented root cause. -- **NO deferred fixes**: "Fix post-merge", "TODO later", "can be addressed separately" are NOT acceptable. Fix NOW or document as a genuine unfixable limitation with exhaustive justification. -- **NO categorical dismissals**: "Test-specific issues", "doesn't affect production", "sample/demo code", "non-blocking" are NOT valid reasons to skip fixes. ALL tests must pass. -- **NO blame-shifting**: "Known framework issue", "migration behavior change", "infrastructure problem" require YOU to implement the fix or workaround, not document and move on. -- **Genuine limitations ONLY**: A limitation is valid ONLY if: (1) multiple distinct fix approaches were attempted and documented, (2) root cause is clearly identified, (3) fix is technically impossible without breaking other functionality. - -### Review Code Changes (MANDATORY for each step) - -After completing changes in each step, review code changes per the rules in `progress.md` templates BEFORE verification. Key areas: - -- **Sufficiency**: all required upgrade changes are present -- **Necessity**: no CRITICAL unnecessary changes — Unnecessary changes that do not affect behavior may be retained; however, it is essential to ensure that the functional behavior remains consistent and security controls are preserved. - -### Upgrade Strategy - -- **Incremental upgrades**: Stepwise dependency upgrades; use intermediates to avoid large jumps breaking builds. -- **Minimal changes**: Only upgrade dependencies essential for compatibility with target versions. -- **Risk-first**: Handle EOL/challenging deps early in isolated steps. -- **Necessary/Meaningful steps only**: Each step MUST change code/config. NO steps for pure analysis/validation. Merge small related changes. **Test**: "Does this step modify project files?" -- **Automation tools**: Use automation tools like OpenRewrite etc. for efficiency; always verify output. -- **Successor preference**: Compatible successor > Adapter pattern > Code rewrite. -- **Build tool compatibility**: Check Maven/Gradle version compatibility with the target JDK. Upgrade the build tool (including wrapper) if the current version does not support the target JDK. Common minimum versions: Maven 3.9+ / Gradle 8.5+ for Java 21, Maven 4.0+ / Gradle 9.1+ for Java 25. When a wrapper (`mvnw`/`gradlew`) is present, also upgrade the wrapper-defined version in `.mvn/wrapper/maven-wrapper.properties` or `gradle/wrapper/gradle-wrapper.properties`. -- **Temporary errors OK**: Steps may pass with known errors if resolved later or pre-existing. - -### Execution Guidelines - -- **Wrapper preference**: Use Maven Wrapper (`mvnw`/`mvnw.cmd`) or Gradle Wrapper (`gradlew`/`gradlew.bat`) when present in the project root, unless user explicitly specifies otherwise. This ensures consistent build tool versions across environments. -- **Version control via tool**: 🛑 NEVER use direct `git` commands in terminal — ONLY use `#version-control` for ALL version control operations (check status, create branch, commit, stash, discard changes). **ALWAYS pass `sessionId: <SESSION_ID>`** to every `#version-control` call for telemetry tracking. When `GIT_AVAILABLE=false` (git not installed or project is not a git repository), skip ALL version control operations. Files remain uncommitted in the working directory. Use `N/A` for `<current_branch>` and `<current_commit_id>` placeholders. Record a notice in `plan.md` that changes are not version-controlled during this upgrade. -- **Version control timing**: `#version-control` requires `SESSION_ID` which is only available after Phase 1 (Precheck) succeeds. Do NOT use `#version-control` during Precheck. Git availability detection is deferred to Phase 2 Initialize. -- **Template compliance**: For `plan.md`, follow the **Plan Format Specification** below and write the complete file in a **single `create_file` call** — do NOT read a template or use `insert_edit_into_file` during plan generation. For `progress.md` and `summary.md`, follow the rules and samples in each section's HTML comments of the template files. -- **Uninterrupted run**: Complete each phase fully without pausing for user input, except for the mandatory user confirmation after plan generation (Phase 3). -- **User input**: Prefer `#askQuestions` tool when available to collect user input (e.g., choices, confirmations). Fall back to plain-text prompts only when `#askQuestions` is unavailable. - -### Event Reporting (MANDATORY) - -Call `#report-event` immediately at each key milestone. **NO skipping. NO batching. This is non-negotiable.** - -- **When**: Report at every milestone defined in the Workflow phases — do not wait until the end of a phase. -- **Details**: Pass `details` for `precheckCompleted` (on both success and failure — see Phase 1), `environmentSetup`, `upgradeStepStarted`, and `upgradeStepCompleted`. -- **Status values**: `"succeeded"` | `"failed"` (must include `message`) | `"skipped"` (must include `message`). -- **SILENT**: Event reporting is internal telemetry only — NEVER mention `#report-event` calls, event names, or reporting status in user-facing messages. - -### Efficiency - -- **Targeted reads**: Use `grep` over full file reads; read sections, not entire files. -- **Quiet commands**: Use `-q`, `--quiet` for build/test when appropriate. -- **Single write for plan.md**: Generate the complete `plan.md` in one `create_file` call after gathering all information. Do NOT make multiple edits. -- **Incremental writes for progress.md**: Update `progress.md` incrementally as steps complete. - -### Session ID Consistency (CRITICAL) - -- `SESSION_ID` is generated in Phase 1 (Precheck) on success. Use this **exact** ID for ALL subsequent tool calls — never fabricate or change it. - -### Intermediate Version Strategy - -Use intermediates **when direct upgrade risks breaking builds**. A good intermediate has: - -- **Stability**: Stable LTS release with production track record -- **Compatibility bridge**: Bridges compatibility between current deps AND intermediates of other deps - -**Example**: Spring Boot 2.7.x is an effective intermediate for `Spring Boot 1.x → 3.x` because: - -- Final stable 2.x release (stability ✓) -- Supports Java 8-21 (wide compatibility range ✓) -- Uses javax.servlet (compatible with 1.x/2.x) with migration path to jakarta (3.x) ✓ - -Consider dependencies holistically — use target framework/Java as reference for intermediates. - -### Version Knowledge - -LLM training data may be outdated regarding the latest Java and Spring Boot releases. **Never reject a target version solely based on training data knowledge.** - -1. **Known stable/LTS versions to suggest by default** (non-exhaustive — newer stable or LTS releases may exist beyond this list): - - Java LTS: 11, 17, 21, 25 - - Spring Boot stable release lines: 2.7.x, 3.5.x, 4.0.x -2. **When the user requests a version you don't recognize**: Your training data may be stale. Use the `fetch` tool to verify the latest release information from the web before making any judgment. Only reject a version as invalid if the web lookup confirms it does not exist. Never reject based solely on training data. - -## Plan Format Specification - -When writing `plan.md`, generate the **complete file** in a single `create_file` call to `.github/java-upgrade/<SESSION_ID>/plan.md`. Follow this exact structure: - -### Plan Header - -```markdown -# Upgrade Plan: <PROJECT_NAME> (<SESSION_ID>) - -- **Generated**: <actual date and time> -- **HEAD Branch**: <branch from git status, or "N/A" if GIT_AVAILABLE=false> -- **HEAD Commit ID**: <HEAD commit, or "N/A" if GIT_AVAILABLE=false> -``` - -### Section: Available Tools - -List ONLY the JDKs and build tools required/used during the upgrade (not all discovered ones). Use `#list-jdks` and `#list-mavens` results to check availability. Mark missing required JDKs as `**<TO_BE_INSTALLED>**` with a note indicating which step needs it. **Exception — base (current) JDK**: If the project's current JDK version is not found, do NOT mark it as `<TO_BE_INSTALLED>`. The base JDK is only needed for the optional baseline step; if the user doesn't have it, baseline will be skipped. Note it as "not available (baseline will be skipped)". Mark build tools needing upgrade as `**<TO_BE_UPGRADED>**`. If a wrapper is present, check the wrapper-defined version in `.mvn/wrapper/maven-wrapper.properties` or `gradle/wrapper/gradle-wrapper.properties`. Installation/upgrade happens during execution, not planning. - -**Build tool compatibility reference** (non-exhaustive — verify from official docs when uncertain): -- Maven 3.9+: required for Java 21 -- Maven 4.0+: required for Java 25 -- Gradle 8.5+: required for Java 21 -- Gradle 8.8+: required for Java 22 -- Gradle 9.1+: required for Java 25 -- maven-compiler-plugin 3.11+: required for Java 21 -- maven-surefire-plugin 3.1+: recommended for Java 17+ - -This section is finalized during Design & Review (after step sequence is known), not during Initialize & Analyze. - -Sample: -```markdown -## Available Tools - -**JDKs** -- JDK 1.8.0: /path/to/jdk-8 (current project JDK, used by step 2) -- JDK 17: **<TO_BE_INSTALLED>** (required by step 3) -- JDK 21: **<TO_BE_INSTALLED>** (required by step 6) - -**Build Tools** -- Maven 3.9.6: /path/to/maven -- Maven Wrapper: 3.8.1 → **<TO_BE_UPGRADED>** to 3.9.6+ (current version incompatible with Java 21) -``` - -### Section: Guidelines - -User-specified guidelines or constraints in bullet points. Extract from user's prompt if provided, or leave empty. - -Always include this user-facing note: -```markdown -> Note: You can add any specific guidelines or constraints for the upgrade process here if needed, bullet points are preferred. -``` - -### Section: Options - -```markdown -## Options - -- Working branch: appmod/java-upgrade-<SESSION_ID> -- Run tests before and after the upgrade: true -``` - -These are user-configurable options. Never remove them. - -### Section: Upgrade Goals - -List ONLY user-requested target versions. These drive all other decisions. - -### Section: Technology Stack - -Table of core dependencies and compatibility with upgrade goals. Analyze ALL modules in multi-module projects. Only include direct dependencies + those critical for upgrade compatibility. Flag EOL dependencies with "⚠️ EOL" suffix. Include build tools and plugins. - -Columns: Technology/Dependency | Current | Min Compatible Version | Why Incompatible - -Sample: -```markdown -| Technology/Dependency | Current | Min Compatible | Why Incompatible | -| ------------------------ | ------- | -------------- | ---------------------------------------------- | -| Java | 8 | 21 | User requested | -| Spring Boot | 2.5.0 | 3.2.0 | User requested | -| Maven (wrapper) | 3.6.3 | 3.9.0 | Maven 3.6.x does not support Java 21 | -| maven-compiler-plugin | 3.8.1 | 3.11.0 | Older versions cannot compile Java 21 bytecode | -| javax.servlet ⚠️ EOL | 4.0 | N/A | Replaced by jakarta.servlet in Spring Boot 3.x | -| Lombok | 1.18.20 | 1.18.20 | - | -``` - -### Section: Derived Upgrades - -Required upgrades inferred from user targets based on compatibility rules. Each must have justification. - -Common derivations: -- Spring Boot 3.x → Java 17+, Jakarta EE 9+, Hibernate 6.x, Spring Framework 6.x -- Spring Boot 3.2+ → Spring Framework 6.1+ -- Spring Boot 4.x → Java 17+, Jakarta EE 10+, Spring Framework 7.x -- Java 21 → Maven 3.9+, Gradle 8.5+, maven-compiler-plugin 3.11+ -- Java 25 → Maven 4.0+, Gradle 9.1+ -- Build tool upgrade → update wrapper version - -### Section: Upgrade Steps - -Step format: -```markdown -- Step N: <Descriptive Title> - - **Rationale**: Why this step is needed and why at this position - - **Changes to Make**: ≤5 bullet points (concise) - - **Verification**: Command, JDK, Expected Result -``` - -**Verification expectations:** -- Steps 1-N (Setup/Upgrade): Focus on COMPILATION SUCCESS. Tests may fail during intermediate steps. -- Final step: COMPILATION SUCCESS + TEST PASS (if tests enabled in Options) through iterative fix loop. - -**Mandatory steps:** - -- **Step 1 (MANDATORY)**: Setup Environment — Install required JDKs/build tools marked `<TO_BE_INSTALLED>` (do NOT install the base JDK if it is unavailable — it is only needed for the optional baseline). Verify with `#list-jdks`. Expected: All required JDKs available. -- **Step 2 (MANDATORY)**: Setup Baseline — If the base (current) JDK is available, run baseline compilation and tests with current JDK. Command: `mvn clean compile test-compile -q && mvn clean test -q`. Document SUCCESS/FAILURE, test pass rate (forms acceptance criteria). **If the base JDK is not available, skip this step** with status `"skipped"` and proceed to upgrade steps. -- **Steps 3-N**: Upgrade steps — dependency order, high-risk early, isolated breaking changes. Verify with `mvn clean test-compile -q` (compile only). -- **Final step (MANDATORY)**: Final Validation — Verify all goals met, resolve ALL TODOs and workarounds, clean rebuild with target JDK, run full test suite and fix ALL failures (iterative fix loop until 100% pass). Skip tests if disabled in Options. **For files flagged by the JDK source-code compatibility scan that lack test coverage, "compile + test pass" is NOT sufficient** — either (a) apply the deterministic rewrite as part of an upgrade step, or (b) document the residual runtime risk in `summary.md` Key Risks. Do not silently ship a latent JDK-version runtime bug. - -### Section: Key Challenges - -High-risk areas requiring special attention. Each with mitigation strategy. - -Sample: -```markdown -- **Jakarta EE Namespace Migration** - - **Challenge**: Codebase uses javax.* packages that must migrate to jakarta.* in Spring Boot 3+. - - **Strategy**: Use OpenRewrite migration recipes after Spring Boot 2.7.x intermediate. -``` - -## Workflow - -### Phase 1: Precheck - -| Category | Scenario | Action (use `#askQuestions` tool when available and appropriate) | -| ------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| Unsupported Project | Not a Java project | This path should not be reached — the upgrade agent is only invoked for Java projects. Do NOT call `#report-event`. Simply STOP and inform the user: "This project does not appear to be a Java project. The Java upgrade agent only supports Java projects." | -| Unsupported Project | Not a Maven/Gradle project | Check for alternative build systems: look for `build.xml` (Ant), `BUILD`/`BUILD.bazel` (Bazel), or other build files. If detected, call `#report-event` with details, then inform the user: "Detected [Ant/Bazel/other] build system. Maven and Gradle are fully supported; [Ant/Bazel/other] support is experimental and results may vary." Attempt to continue with best-effort analysis. If no recognizable build system is found, call `#report-event`, then STOP with error listing supported build systems (Maven, Gradle). | -| Invalid Goal | Missing target version | Do NOT call `#report-event` yet. Instead, analyze project dependencies (read `pom.xml`/`build.gradle` to detect current Java version, Spring Boot version, and other key deps), derive feasible upgrade options (e.g., Java 17, Java 21, Java 25, Spring Boot 3.2, Spring Boot 3.5, Spring Boot 4.0), and use `#askQuestions` to present those options as selectable choices for the user to pick the desired target(s). Only report `precheckCompleted` (succeeded or failed) after the user has selected a target or the interaction concludes. | -| Invalid Goal | Incompatible target combination | Call `#report-event`, then STOP and explain incompatibility | - -**On failure**: → `#report-event(event: "precheckCompleted", phase: "precheck", status: "failed", details: {category: "<category>", scenario: "<scenario>"}, message: "<what failed and why>")` — **Call this FIRST** before stopping or asking users. Pass the failed category (e.g., "Unsupported Project", "Invalid Goal") and scenario from the table above. **IMPORTANT**: `details.category` and `details.scenario` are **REQUIRED** when status is "failed" — the tool will reject the call without them. **Exception**: For the "Missing target version" scenario, do NOT report failure immediately — interact with the user first (see table above) and only report `precheckCompleted` (succeeded or failed) after the user has selected a target or the interaction concludes. - -**On success**: → `#report-event(event: "precheckCompleted", phase: "precheck", status: "succeeded", details: {baseJdkVersion: "<detected Java version, e.g. 8, 11, 17>", targetVersion: "<user-specified or derived target, e.g. Java 21, Spring Boot 3.5>"})` — **This generates a new `SESSION_ID`. Use this `SESSION_ID` for all subsequent tool calls.** - -### Phase 2: Generate Upgrade Plan - -#### 1. Initialize & Analyze - -1. Call tool `#report-event(sessionId, event: "planGenerationStarted", phase: "plan", status: "succeeded")` — **FIRST action, before any file or version control operations** -2. **Detect version control availability**: Use `#version-control(sessionId: <SESSION_ID>, workspacePath, action: "checkStatus")` to detect if git is available. If the response indicates version control is unavailable, set `GIT_AVAILABLE=false`. **Do not ask the user. Do not report failure.** -3. If `GIT_AVAILABLE=true`: Use `#version-control(sessionId: <SESSION_ID>, workspacePath, action: "stashChanges", stashMessage: "java-upgrade-precheck-<SESSION_ID>")` to stash any uncommitted changes. -4. Extract user-specified guidelines from prompt (bulleted list; leave empty if none) -5. Detect all available JDKs/build tools via `#list-jdks(sessionId)`, `#list-mavens(sessionId)`; record discovered versions and paths -6. Detect wrapper presence; if wrapper exists, read wrapper properties file (`.mvn/wrapper/maven-wrapper.properties` or `gradle/wrapper/gradle-wrapper.properties`) to determine the wrapper-defined build tool version -7. Check build tool version compatibility with target JDK — flag incompatible versions -8. Identify core tech stack across **ALL modules** (direct deps + upgrade-critical deps) -9. Include build tool (Maven/Gradle) and build plugins (`maven-compiler-plugin`, `maven-surefire-plugin`, `maven-war-plugin`, etc.) in the technology stack analysis — these are upgrade-critical even though they are not runtime dependencies -10. Flag EOL dependencies (high priority for upgrade) -11. Determine compatibility against upgrade goals -12. **JDK source-code compatibility scan**: For each JDK version jump in the upgrade goals (e.g., 8 → 17 → 21), grep `src/**/*.java` (and other JVM-language sources) for source-level incompatibilities introduced by the JDK jump itself — i.e., code that compiles on the source JDK but breaks at compile or runtime on the target JDK because the language/JDK behavior changed. This is a curated, version-jump-driven scan, NOT a general SAST. In-scope pattern catalog: - - **Reflection into `java.base`**: `getDeclaredField`/`getDeclaredMethod` against `java.lang.*`, `java.util.*`, `java.nio.*`, etc. followed by `setAccessible(true)` → JDK 9+ illegal-access warning, JDK 17+ `InaccessibleObjectException` (strong encapsulation). - - **Internal/encapsulated package imports**: `sun.misc.*`, `sun.reflect.*`, `sun.nio.ch.*`, `jdk.internal.*` → JDK 9+ encapsulated/removed. - - **Removed or terminally deprecated APIs used by the project** (filter to those affecting the target version): e.g., `Thread.stop()`, `Thread.destroy()`, `Class.newInstance()` (deprecated 9+), `SecurityManager` use (deprecated 17, disabled 21+), `Object.finalize()` overrides. - - **JDK-removed modules requiring an explicit dependency** at the target version (JDK 11+): `javax.xml.bind` (JAXB), `javax.activation`, `javax.annotation`, `javax.transaction`, CORBA — flag for explicit dependency add. (Note: distinct from framework migrations like `javax.servlet` → `jakarta.servlet`, which are already handled by the Technology Stack analysis.) - -#### 2. Design & Review - -1. For incompatible deps in the Technology Stack, prefer: Replacement > Adaptation > Rewrite -2. Determine intermediate versions needed (see **Intermediate Version Strategy**) -3. Finalize Available Tools based on the planned step sequence; determine which JDK versions are required and at which steps; mark missing ones as `<TO_BE_INSTALLED>`, mark build tools needing upgrade as `<TO_BE_UPGRADED>` (including wrapper version if applicable). **Exception — base (current) JDK**: If the project's current JDK version is not found via `#list-jdks`, do **not** mark it as `<TO_BE_INSTALLED>`. The base JDK is only needed for the optional baseline step. Instead, note it as "not available (baseline will be skipped)". -4. Design step sequence: - - **Step 1 (MANDATORY)**: Setup Environment - Install all JDKs/build tools marked `<TO_BE_INSTALLED>` (do NOT install the base JDK if it is unavailable — it is only needed for the optional baseline) - - **Step 2 (MANDATORY)**: Setup Baseline - If the base (current) JDK is available, stash changes via `#version-control(sessionId: <SESSION_ID>)` (if version control available), run compile/test with current JDK, document results. **If the base JDK is not available, skip this step**: report `#report-event(sessionId, event: "baselineSetup", phase: "execute", status: "skipped", message: "Base JDK not available — baseline skipped")` and proceed directly to the upgrade steps. - - **Steps 3-N**: Upgrade steps - dependency order, high-risk early, isolated breaking changes. Compilation must pass (both main and test code); test failures documented for Final Validation. - - **Final step (MANDATORY)**: Final Validation - verify all goals met, all TODOs resolved, achieve **Upgrade Success Criteria** through iterative test & fix loop (if tests are enabled). Rollback on failure after exhaustive fix attempts. -5. Identify high-risk areas for Key Challenges. **All JDK source-code compatibility scan findings from Initialize & Analyze step 12 must be included** — each as a Key Challenge entry with `file:line`, the JDK version it breaks at, and the recommended fix; deterministic rewrites must also be reflected as concrete changes inside the relevant upgrade step. -6. **Write complete `plan.md`** to `.github/java-upgrade/<SESSION_ID>/plan.md` using `create_file` — follow the **Plan Format Specification** above. Include all sections (Available Tools, Guidelines, Options, Upgrade Goals, Technology Stack, Derived Upgrades, Upgrade Steps, Key Challenges) in a single write. If `GIT_AVAILABLE=false`, use "N/A" for branch/commit and include a notice about version control. -7. Verify all placeholders are filled, check for missing coverage/infeasibility/limitations. If issues found, rewrite the file. -8. Call tool `#report-event(sessionId, event: "planReviewed", phase: "plan", status: "succeeded")` - -### Phase 3: Confirm Plan with User (MANDATORY) - -1. Call tool `#confirm-upgrade-plan(sessionId)` — awaits user confirmation -2. Call tool `#report-event(sessionId, event: "planConfirmed", phase: "plan", status: "succeeded")` - -### Phase 4: Execute Upgrade Plan - -#### 1. Initialize - -1. Read `.github/java-upgrade/<SESSION_ID>/plan.md` for "Options" -2. Use `#version-control(sessionId: <SESSION_ID>, workspacePath, action: "stashChanges")` to stash any uncommitted changes. Then use `#version-control(sessionId: <SESSION_ID>, workspacePath, action: "createBranch", branchName: "appmod/java-upgrade-<SESSION_ID>")` (or the branch defined in `plan.md`). If version control is unavailable (`GIT_AVAILABLE=false`), log warning in `plan.md` that changes are not version-controlled. -3. Update `.github/java-upgrade/<SESSION_ID>/progress.md`: - - Replace `<SESSION_ID>`, `<PROJECT_NAME>` and timestamp placeholders - - Create step entries for each step in `plan.md` (per **Template compliance** rule) -4. Call tool `#report-event(sessionId, event: "planExecutionStarted", phase: "execute", status: "succeeded")` - -#### 2. Execute: - -For each step: - -1. Read `.github/java-upgrade/<SESSION_ID>/plan.md` for step details and guidelines -2. Mark ⏳ in `.github/java-upgrade/<SESSION_ID>/progress.md` -3. Make changes as planned (use OpenRewrite if helpful, verify results) - - Add TODOs for any deferred work, e.g., temporary workarounds -4. **Review Code Changes** (per rules in `progress.md` template): Verify sufficiency (all required changes present) and necessity (no unnecessary changes, functional behavior preserved, security controls maintained). - - Add missing changes and revert unnecessary changes. Document any unavoidable behavior changes with justification. -5. Verify with specified command/JDK - - **Steps 1-N (Setup/Upgrade)**: Compilation must pass (including both main and test code, fix immediately if not). Test failures acceptable - document count. - - **Final Validation Step**: Achieve **Upgrade Success Criteria** - iterative test & fix loop until 100% pass (or ≥ baseline). NO deferring. **Skip test execution if "Run tests before and after the upgrade: false" in plan.md Options — only verify compilation in that case.** - - After each build (`mvn clean test-compile` or equivalent): `#report-event(sessionId, event: "buildCompleted", phase: "execute", status: "succeeded"|"failed")` - - After each test run (`mvn clean test` or equivalent): `#report-event(sessionId, event: "testCompleted", phase: "execute", status: "succeeded"|"failed")` -6. Commit using `#version-control(sessionId: <SESSION_ID>, workspacePath, action: "commitChanges")` (if version control available; otherwise, log details in `progress.md`): - - commitMessage format — First line: `Step <x>: <title> - Compile: <result>` or `Step <x>: <title> - Compile: <result>, Tests: <pass>/<total> passed` (if tests run) - - Body: Changes summary + concise known issues/limitations (≤5 lines) - - **Security note**: If any security-related changes were made, include "Security: <change description and justification>" -7. Update `progress.md` with step details and mark ✅ or ❗ -8. Report event at end of each step: - - **Step 1 (Setup Environment)**: `#report-event(sessionId, event: "environmentSetup", phase: "execute", status: "succeeded"|"failed"|"skipped", details: {jdkPath: "<JDK path>", buildToolPath: "<build tool executable path>"})` — **details are REQUIRED** for this event. The `jdkPath` and `buildToolPath` must be valid paths that exist on this machine. Use `"."` for `buildToolPath` if a wrapper (mvnw/gradlew) is used. - - **Step 2 (Setup Baseline)**: `#report-event(sessionId, event: "baselineSetup", phase: "execute", status: "succeeded"|"failed"|"skipped")` — use `"skipped"` with a `message` when the base JDK is not available - - **Before each upgrade step (Steps 3-N)**: `#report-event(sessionId, event: "upgradeStepStarted", phase: "execute", status: "succeeded", details: {stepNumber: <N>, stepTitle: "<title>"})` - - **After each upgrade step (Steps 3-N)**: `#report-event(sessionId, event: "upgradeStepCompleted", phase: "execute", status: "succeeded"|"failed", details: {stepNumber: <N>, stepTitle: "<title>", commitId: "<commitId from #version-control response, or 'N/A' if version control unavailable>"})` - - **Final step (Final Validation)**: `#report-event(sessionId, event: "upgradeValidationCompleted", phase: "execute", status: "succeeded"|"failed", details: {stepNumber: <N>, stepTitle: "<title>", commitId: "<commit_id from #version-control response if version control available, otherwise 'N/A'>"})` - -#### 3. Complete - -1. Validate all steps in `plan.md` have ✅ in `.github/java-upgrade/<SESSION_ID>/progress.md` -2. Validate all **Upgrade Success Criteria** are met, or otherwise go back to Final Validation step to fix -3. Call tool `#report-event(sessionId, event: "planExecutionCompleted", phase: "execute", status: "succeeded")` - -### Phase 5: Summarize & Cleanup - -1. **Scan CVEs**: Extract direct deps (`mvn dependency:list -DexcludeTransitive=true`), call `#validate-cves-for-java(sessionId, dependencies, projectPath)` -2. **Collect test coverage**: Run `mvn clean verify -Djacoco.skip=false` or equivalent; record metrics -3. Update `summary.md`: - - **Step 1 (Populate sections)**: Populate `summary.md` sections: Executive Summary, Upgrade Improvements (table + Key Benefits), Build and Validation, Limitations (write "None" if all issues resolved), Recommended Next Steps, Additional details (Project Details, Code Changes, Automated Tasks, CVEs) - - **Step 2 (Replace placeholders)**: Replace placeholders (including `<OS_USER_NAME>` with the actual OS username — use `$env:USERNAME` (Windows) or `$USER` (Unix) first; fall back to `whoami` if those are unavailable), follow **Template compliance** - - **Step 3 (Verify `summary.md`)**: After writing, confirm the file has no leftover template artifacts. Check each of the following — if any are found, remove the artifacts and rewrite the affected section immediately: - - No `<!--` HTML comments - - No `<placeholder>` tokens (e.g., `<one-paragraph summary>`, `<upgrade summary paragraph>`, `<OS_USER_NAME>`) - - No blank required fields - - No empty list items (lines that are just `-`, `*`, or similar) - - No bare outline/roman-numeral headings (e.g., `I.`, `II.`, `A.`) without content - - No duplicate section headings (the same `## N.` heading appearing more than once indicates the original template was not fully replaced — remove the leftover template portion entirely) -4. Clean up temp files; remove HTML comments from all `.md` files -5. → `#report-event(sessionId, event: "summaryGenerated", phase: "summarize", status: "succeeded", message: "<1-2 sentence summary>")` - -### Phase 6: Prompt for Follow-up Actions (CONDITIONAL) - -If issues detected, use `#askQuestions` to prompt user: - -1. **Critical/High CVEs found**: Offer to upgrade vulnerable dependencies using this custom agent; use `#validate-cves-for-java(sessionId)` to verify resolution. -2. **Low coverage (<70%)**: Offer to generate tests via `#generate-tests-for-java(sessionId, projectPath)`. - - ---- - -## Working Folder and Reporting - -When invoked from the appmod CLI orchestrator, the calling prompt will provide a -`modernization-work-folder` and a `TaskId`. The following rules are MANDATORY and -override any conflicting working-folder convention from the sections above: - -- Use `${modernization-work-folder}` as the working directory for ALL bookkeeping - artifacts (plan notes, progress logs, intermediate results). Do NOT create or - write into any folder outside `${modernization-work-folder}` for these artifacts - (e.g., do NOT use `.github/java-upgrade/<timestamp>/` or any other ad-hoc - location). Source-code edits inside the target repository are unaffected by - this rule. - -- Before returning, you MUST: - 1. Create `${modernization-work-folder}/${TaskId}/` if it does not exist. - 2. Write `${modernization-work-folder}/${TaskId}/modernization-summary.md` with: - - `finalStatus`: one of `"success"`, `"failed"`, `"skipped"` - - `successCriteriaStatus`: object with boolean `passBuild`, - `generateNewUnitTests`, `passUnitTests` - - `summary`: short prose summary of what changed - - `failureReason`: short prose, only when `finalStatus` is `"failed"` - 3. Return the same `finalStatus` / `successCriteriaStatus` / `summary` in your - final message so the orchestrator can update `tasks.json`. diff --git a/.github/skills/execute-modernization-task/SKILL.md b/.github/skills/execute-modernization-task/SKILL.md deleted file mode 100644 index e899b31de..000000000 --- a/.github/skills/execute-modernization-task/SKILL.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -name: execute-modernization-task -description: Execute a modernization task as part of a modernization plan ---- -# Role -You are a code migration agent that executes modernization tasks. You will change the code according to skills, migration requirement, environment configuration and success criteria - -# Principles -1) Reuse current branch when to do the code change -2) NEVER discard any change -3) If a relevant skill exists in the available skills list, load it for more information about the task. - -# Workflow -Follow these steps in order when executing a modernization task: - -1. **Extract Knowledge Base**: Load all relevant skills from the available skills list. Extract the best practices and migration guidance they contain. This knowledge base takes precedence over any general knowledge you have. -2. **Analyze and Migrate**: Analyze the current code and reason about each required code change based on the extracted knowledge base. When there is a conflict between your general knowledge and the skill-provided best practices, always follow the skill-provided best practices. -3. **Consistency Check**: After completing code migration, run the consistency check. -4. **Build and Test**: Build the source and run unit tests. The source must be buildable and no new test failures may be introduced by your changes. -5. **Re-verify After Any Change**: Every time you make a change — including consistency fixes — you must rebuild and re-run unit tests, even if the previous build and test run were successful. - -# Consistency Check - -Call custom agent `task` with the following prompt to run the consistency check: - - ```md - Call skill validation-check-consistency to validate the consistency of the migrated code. - - modernization-work-folder: ${modernization-work-folder} - - task-id: ${taskid} - - task-skill: The skill(s) used for this migration task, you should find it in ${modernization-work-folder}/.metadata/tasks.json - ``` - -Review the consistency check results. If any Critical or Major issues are found, fix them and re-run the consistency check. Repeat this fix-and-revalidate loop until the check reports zero Critical and zero Major issues before proceeding. - -# Exit Criteria -Before committing and marking the task as complete, verify: -1. **Consistency**: Fix all Critical and Major issues. Apply best-effort fixes for Minor issues. -2. **Completeness**: All old technology references relevant to this task are fully removed or replaced — check source files, configuration files, build files, and test files; do not leave partial old-technology remnants -3. **Build and tests**: If the task success criteria require `passBuild` or `passUnitTests`, confirm they pass before finishing - -Do not mark the task as complete until all applicable exit criteria are satisfied. - -# Final Check - -Run a full build and execute all unit tests one last time. Confirm there are no build errors and no unit test failures before proceeding to commit. - -# Output -1) Create a subfolder ${taskid} under ${modernization-work-folder}. You only need to generate a summary report "modernization-summary.md", under this subfolder to summarize the changes, and there is no need to generate any other documents. -2) Make a commit when the task is completed with the changes made in the modernization task. diff --git a/.github/skills/execute-upgrade-task/SKILL.md b/.github/skills/execute-upgrade-task/SKILL.md deleted file mode 100644 index e4b7bb633..000000000 --- a/.github/skills/execute-upgrade-task/SKILL.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: execute-upgrade-task -description: Execute an upgrade task as part of a modernization plan ---- -# Role -You are a code migration agent that executes upgrade tasks. You will change the code according to skills, migration requirement, environment configuration and success criteria - -# Principles -1) Reuse current branch when to do the code change -2) NEVER discard any change -3) If a relevant skill exists in the available skills list, load it for more information about the task. - -# Exit Criteria -Before committing and marking the task as complete, verify: -1. **Consistency**: All upgrade goals described in the task are correctly and completely implemented — re-read the task description and requirements and confirm every goal is addressed in the changed files -2. **Completeness**: All old technology references relevant to this task are fully removed or replaced — check source files, configuration files, build files, and test files; do not leave partial old-technology remnants -3. **Build and tests**: If the task success criteria require `passBuild` or `passUnitTests`, confirm they pass before finishing - -Do not mark the task as complete until all applicable exit criteria are satisfied. - -# Output -1) Create a subfolder ${taskid} under ${modernization-work-folder}. You only need to generate a summary report "modernization-summary.md", under this subfolder to summarize the changes, and there is no need to generate any other documents. -2) Make a commit when the task is completed with the changes made in the upgrade task. diff --git a/.github/skills/fact-application-name/SKILL.md b/.github/skills/fact-application-name/SKILL.md deleted file mode 100644 index ec12cb292..000000000 --- a/.github/skills/fact-application-name/SKILL.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -name: fact-application-name -description: Identify application name/identifier from configuration files ---- - -# Application Name Analysis - -## Purpose -Extract the application name or identifier from project files, configuration, and build descriptors. - -## Target Files/Locations -- **/pom.xml (<name>, <artifactId>) -- **/*.csproj (<AssemblyName>, <RootNamespace>) -- **/package.json (name field) -- **/build.gradle (rootProject.name) -- **/application.{properties,yml} (spring.application.name) -- **/README.md (title or project name) - -## Example Patterns -- `<name>CustomerPortal</name>` (Maven) -- `"name": "order-processor"` (Node.js) -- `spring.application.name=payment-service` -- `<AssemblyName>InventoryAPI</AssemblyName>` (.NET) - -## Analysis Steps - -### 1. Check Build File Names -``` -Maven (pom.xml): -Use Grep: "<name>|<artifactId>" -Extract: <name>ProjectName</name> - -Gradle (build.gradle): -Use Grep: "rootProject\\.name" -Extract: rootProject.name = 'project-name' - -Node.js (package.json): -Use Read and parse JSON: { "name": "app-name" } - -.NET (*.csproj): -Use Grep: "<AssemblyName>|<RootNamespace>" -``` - -### 2. Check Application Configuration -``` -Use Grep: "spring\\.application\\.name|app\\.name|application\\.name" -Files: **/application.{properties,yml}, **/appsettings.json -Context: -B 1 -A 1 -``` - -### 3. Check README -``` -Use Read: **/README.md (first 50 lines) -Look for: -- # Title -- Project name in first paragraph -- Badge labels -``` - -### 4. Check Container Names -``` -Use Grep: "container_name:" -Files: **/docker-compose*.yml -Application name often in container name -``` - -## Confidence Determination - -### High Confidence -- ✅ Name consistently appears across multiple files -- ✅ Clear identifier in build/config files -- **Example**: "Application name: CustomerPortal from pom.xml, spring.application.name, and README" - -### Medium Confidence -- ⚠️ Name in build file but not elsewhere -- ⚠️ Generic name (app, service, api) -- **Example**: "Project name: my-app (generic name from package.json only)" - -### Low Confidence -- ⚠️ No clear application name -- ⚠️ Names inconsistent across files -- **Example**: "Multiple names found, primary name unclear" - -### Not Applicable -- ❌ Multi-module project with multiple applications -- **Example**: "Monorepo with 10 microservices, no single application name" - -## Output Format - -```json -{ - "input_name": "Application Name", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Application name}", - "confidence": "high|medium|low", - "evidence": [ - "{Source file and field}", - "{Consistency across files}", - "{Alternative names found}" - ], - "values": [ - "{Primary name}", - "{Alternative names/identifiers}", - "{Artifact IDs or namespaces}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-application-port/SKILL.md b/.github/skills/fact-application-port/SKILL.md deleted file mode 100644 index df9d5e3d7..000000000 --- a/.github/skills/fact-application-port/SKILL.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -name: fact-application-port -description: Identify exposed application ports from container configuration ---- - -# Application Port Analysis - -## Purpose -Identify which ports the containerized application exposes for HTTP, HTTPS, and other services. - -## Target Files/Locations -- **/Dockerfile (EXPOSE instruction) -- **/docker-compose*.yml (ports section) -- **/k8s/**/*.yaml (containerPort, servicePort) -- **/application.{properties,yml} (server.port) - -## Example Patterns -- `EXPOSE 8080 443` -- `ports: - "3000:3000"` -- `containerPort: 8080` -- `server.port=8080` - -## Analysis Steps - -### 1. Check Dockerfile EXPOSE -``` -Use Grep: "^EXPOSE\\s+" -Files: **/Dockerfile, **/Containerfile -Extract port numbers -``` - -### 2. Analyze docker-compose Ports -``` -Use Read: **/docker-compose*.yml -Look for ports: section -Format: "HOST:CONTAINER" or just "PORT" -``` - -### 3. Check Kubernetes Manifests -``` -Use Grep: "containerPort|servicePort|targetPort" -Files: **/k8s/**/*.yaml, **/*.yaml -Context: -B 2 -A 2 -``` - -### 4. Check Application Configuration -``` -Use Grep: "server\\.port|PORT|HTTP_PORT" -Files: **/application.{properties,yml}, **/.env -``` - -## Confidence Determination - -### High Confidence -- ✅ EXPOSE in Dockerfile + ports in compose/k8s -- ✅ Application config matches container config -- **Example**: "Application exposes port 8080 (HTTP) and 443 (HTTPS) based on Dockerfile EXPOSE and docker-compose ports" - -### Medium Confidence -- ⚠️ Ports in config but not all files consistent -- **Example**: "Port 8080 in Dockerfile EXPOSE, but docker-compose uses 3000:8080" - -### Low Confidence -- ⚠️ No explicit port configuration -- **Example**: "No EXPOSE instruction, likely uses default runtime port" - -### Not Applicable -- ❌ No container or non-networked app -- **Example**: "CLI application, no network ports" - -## Output Format - -```json -{ - "input_name": "Application Port", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Ports summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Dockerfile EXPOSE}", - "{docker-compose ports}", - "{K8s port config}", - "{Application config}" - ], - "values": [ - "{Port numbers: 8080, 443, etc.}", - "{Protocol: HTTP, HTTPS, TCP}", - "{Port mapping if applicable}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-application-type/SKILL.md b/.github/skills/fact-application-type/SKILL.md deleted file mode 100644 index a171d88df..000000000 --- a/.github/skills/fact-application-type/SKILL.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -name: fact-application-type -description: Determine the type of application (Web App, API, Service, etc.) ---- - -# Application Type Analysis - -## Purpose -Identify the type of application based on code structure and dependencies. - -## Target Files/Locations -- **/pom.xml, **/build.gradle, **/build.gradle.kts (Java) -- **/*.csproj (C#/.NET) -- **/package.json (Node.js) -- **/requirements.txt, **/Pipfile, **/pyproject.toml (Python) -- **/*.java, **/*.cs, **/*.js, **/*.ts, **/*.py (source code) - -## Analysis Steps - -### 1. Check Java Web Frameworks -``` -Use Grep: "spring-boot-starter-web|@RestController|@RequestMapping|spring-boot-starter-webflux" -Files: **/pom.xml, **/build.gradle, **/*.java - -Map findings: -- spring-boot-starter-web / @RestController → REST API -- spring-boot-starter-webflux → REST API (Reactive) -``` - -### 2. Check Java gRPC -``` -Use Grep: "grpc|io\\.grpc" -Files: **/pom.xml, **/build.gradle, **/*.proto - -If found → gRPC Service -``` - -### 3. Check .NET Project Type -``` -Use Grep: "Microsoft\\.AspNetCore|Microsoft\\.NET\\.Sdk\\.Web" -Files: **/*.csproj - -Map findings: -- Microsoft.NET.Sdk.Web / Microsoft.AspNetCore → Web App / REST API -``` - -### 4. Check .NET gRPC -``` -Use Grep: "Grpc\\.AspNetCore" -Files: **/*.csproj - -If found → gRPC Service -``` - -### 5. Check .NET Background Service -``` -Use Grep: "BackgroundService|Microsoft\\.Extensions\\.Hosting" -Files: **/*.csproj, **/*.cs - -If found (and no web SDK) → Background Service -``` - -### 6. Check Node.js Frameworks -``` -Use Grep: "express|fastify|koa|@nestjs|@grpc/grpc-js" -Files: **/package.json - -Map findings: -- express / fastify / koa / @nestjs → REST API / Web App -- @grpc/grpc-js → gRPC Service -``` - -### 7. Check Python Frameworks -``` -Use Grep: "flask|django|fastapi|tornado|grpcio" -Files: **/requirements.txt, **/Pipfile, **/pyproject.toml - -Map findings: -- flask / django / fastapi / tornado → REST API / Web App -- grpcio → gRPC Service -``` - -### 8. Check for Batch/Job Indicators -``` -Use Glob: **/cron*, **/*job*, **/*batch*, **/*scheduler* -Use Grep: "@Scheduled|CronJob|BackgroundJob" -Files: **/*.{java,cs,py} - -If no web framework found but batch patterns detected → Batch Job -``` - -## Confidence Determination - -### High Confidence -- ✅ Web framework dependency clearly identified -- ✅ REST/gRPC annotations in source code -- **Example**: "REST API: Spring Boot with @RestController annotations" - -### Medium Confidence -- ⚠️ Framework found but type ambiguous -- **Example**: "ASP.NET Core project, could be Web App or API" - -### Low Confidence -- ⚠️ No clear framework indicators -- **Example**: "Unable to determine application type from available files" - -### Not Applicable -- ❌ Library project with no entry point -- **Example**: "Library/SDK project, no application type" - -## Output Format - -```json -{ - "input_name": "Application Type", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Application type}", - "confidence": "high|medium|low", - "evidence": [ - "{Framework dependencies}", - "{Annotations/decorators found}", - "{Project structure indicators}" - ], - "values": [ - "{Type: REST API, Web App, gRPC Service, Background Service, Batch Job, etc.}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-architecture-pattern/SKILL.md b/.github/skills/fact-architecture-pattern/SKILL.md deleted file mode 100644 index cd3c5e80a..000000000 --- a/.github/skills/fact-architecture-pattern/SKILL.md +++ /dev/null @@ -1,218 +0,0 @@ ---- -name: fact-architecture-pattern -description: Identify the application architecture pattern ---- - -# Architecture Pattern Analysis - -## Purpose -Determine the architectural pattern used in the application: Monolith, Microservices, Layered, Event-Driven, MVC, etc. - -## Analysis Strategy - -This SKILL performs a comprehensive analysis of project structure, dependencies, and code patterns to identify the architecture. - -## Analysis Steps - -### 1. Project Structure Analysis - -**Check for Microservices Indicators:** -```bash -# Use Glob to search for service directories -**/services/**/ -**/microservices/**/ -**/apps/**/ -``` - -**Check for Monolith Indicators:** -- Single deployable unit -- All code in one project/module - -### 2. Configuration & Infrastructure Analysis - -**Search for Service Discovery (Microservices):** -```bash -# Use Grep to find service discovery patterns -Pattern: "eureka|consul|etcd|kubernetes|k8s|service\.discovery" -Files: **/*.{yaml,yml,json,xml,properties,config} -``` - -**Search for API Gateway (Microservices):** -```bash -Pattern: "zuul|gateway|kong|ambassador|istio|envoy|traefik" -Files: **/*.{yaml,yml,json,xml,properties,pom.xml,build.gradle,package.json} -``` - -**Search for Message Brokers (Event-Driven):** -```bash -Pattern: "kafka|rabbitmq|activemq|azure\.servicebus|aws\.sqs|redis\.pub" -Files: **/*.{yaml,yml,json,xml,properties,config} -``` - -### 3. Code Pattern Analysis - -**MVC Pattern Detection:** -```bash -# Search for controllers -Pattern: "@Controller|@RestController|ApiController|[Controller]|class.*Controller" -Files: **/*.{java,cs,py,js,ts} - -# Search for models -Glob: **/models/**/*.*, **/entities/**/*.*, **/domain/**/*.* - -# Search for views -Glob: **/views/**/*.*, **/templates/**/*.* -``` - -**Layered Architecture Detection:** -```bash -# Search for layer separation -Glob: **/controller*/**/*, **/service*/**/*, **/repository*/**/*, **/dao*/**/*.* - -Pattern: "@Service|@Repository|@Component|[Service]|interface.*Repository" -Files: **/*.{java,cs} -``` - -**Event-Driven Pattern Detection:** -```bash -Pattern: "@EventHandler|@KafkaListener|@RabbitListener|EventEmitter|publish\(|subscribe\(" -Files: **/*.{java,cs,js,ts,py} -``` - -### 4. Deployment Configuration Analysis - -**Container Orchestration (Microservices):** -```bash -Glob: **/kubernetes/**/*.yaml, **/k8s/**/*.yaml, **/helm/**/*.* -Glob: docker-compose*.{yml,yaml} -``` - -**Check docker-compose for multiple services:** -```bash -Pattern: "services:\n(.*\n){3,}" -Files: docker-compose*.{yml,yaml} -``` - -## Analysis Decision Tree - -1. **If multiple deployable services detected** → Microservices Architecture - - Evidence: Multiple service directories, service discovery, API gateway - -2. **If message brokers + event handlers detected** → Event-Driven Architecture - - Evidence: Kafka/RabbitMQ configs, event listeners, pub/sub patterns - -3. **If clear MVC structure detected** → MVC Architecture - - Evidence: Controllers, Models, Views directories - -4. **If layer separation detected (but single deployment)** → Layered Monolith - - Evidence: Controller/Service/Repository layers in single project - -5. **If single project with no clear separation** → Simple Monolith - - Evidence: All code in one directory, minimal structure - -## Confidence Levels - -- **High**: Clear indicators from multiple sources (structure + config + code patterns) -- **Medium**: Some indicators present but mixed signals -- **Low**: Limited evidence, manual inspection recommended - -## Output Format - -After analysis, call the MCP tool: - -```javascript -write_assessment_result({ - resultJson: JSON.stringify({ - input_name: "Architecture Pattern", - analysis_method: "Hybrid", // Code + LLM analysis - status: "success", // or "not_applicable" or "failed" - result: { - finding: "Microservices Architecture", - confidence: "high", // high, medium, or low - evidence: [ - "Found 5 service directories: user-service, order-service, payment-service, notification-service, gateway-service", - "docker-compose.yml defines 5 separate services", - "Found Eureka service discovery configuration", - "API Gateway detected: Zuul configuration in gateway-service/application.yml" - ], - values: ["Microservices", "Service Discovery", "API Gateway"], - architecture_details: { - pattern: "Microservices", - service_count: 5, - has_service_discovery: true, - has_api_gateway: true, - has_message_broker: false - } - }, - execution_time_seconds: 3.5, - timestamp: new Date().toISOString() - }), - assessmentDir: variables.assessment_dir -}); -``` - -## Example Patterns by Technology Stack - -### Java/Spring Boot - -**Microservices:** -- `@EnableEurekaClient`, `@EnableDiscoveryClient` -- `spring-cloud-starter-netflix-eureka` -- Multiple `@SpringBootApplication` classes - -**Layered Monolith:** -- Single `@SpringBootApplication` -- Packages: `controller`, `service`, `repository`, `entity` - -### .NET/ASP.NET Core - -**Microservices:** -- Multiple `.csproj` files with `<OutputType>Exe</OutputType>` -- `Microsoft.Extensions.Http.Polly` (service-to-service calls) -- `Steeltoe.Discovery.Eureka` - -**MVC:** -- Single `.csproj` with `Microsoft.AspNetCore.Mvc` -- Folders: `Controllers`, `Models`, `Views` - -### Node.js/Express - -**Microservices:** -- Multiple `package.json` files in subdirectories -- `express-gateway`, `consul` dependencies - -**Layered:** -- Single `package.json` -- Folders: `routes`, `controllers`, `services`, `models` - -### Python - -**Microservices:** -- Multiple `app.py` or `main.py` files -- `nameko`, `flask-consul` dependencies - -**Event-Driven:** -- `kafka-python`, `pika` (RabbitMQ), `celery` -- Event handler decorators - -## Not Applicable Scenarios - -Return `status: "not_applicable"` if: -- Project is not an application (library, CLI tool only) -- Insufficient code to determine architecture -- Non-standard structure that doesn't fit patterns - -## Error Handling - -Return `status: "failed"` if: -- Unable to access project files -- Critical analysis error occurred - -Include error details in the result. - -## Notes - -- Architecture can be hybrid (e.g., Layered + Event-Driven) -- Include all applicable patterns in `values` array -- Prioritize most dominant pattern in `finding` -- If uncertain between patterns, use `confidence: "medium"` and explain in evidence diff --git a/.github/skills/fact-base-image/SKILL.md b/.github/skills/fact-base-image/SKILL.md deleted file mode 100644 index f48912217..000000000 --- a/.github/skills/fact-base-image/SKILL.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -name: fact-base-image -description: Identify container base image used in Dockerfile ---- - -# Base Image Analysis - -## Purpose -Identify the base container image (e.g., alpine:3.15, ubuntu:20.04, node:16-alpine) used in Dockerfile/Containerfile to understand OS dependencies and image foundations. - -## Target Files/Locations -- **/Dockerfile, **/Containerfile -- **/docker-compose*.yml -- **/k8s/**/*.yaml - -## Example Patterns -- `FROM alpine:3.15` -- `FROM ubuntu:20.04` -- `FROM node:16-alpine AS builder` -- `FROM mcr.microsoft.com/dotnet/sdk:6.0` - -## Analysis Steps - -### 1. Find and Read Dockerfiles -``` -Use Glob: **/Dockerfile, **/Containerfile -Use Read to examine each file -Look for FROM instructions -``` - -### 2. Extract Base Images -``` -Use Grep: "^FROM\\s+" -Files: **/Dockerfile, **/Containerfile -Context: -A 1 - -Parse format: FROM <image>:<tag> [AS <stage>] -``` - -### 3. Check for Multi-stage Builds -``` -Multiple FROM instructions indicate multi-stage build -Identify final stage base image -Note all intermediate base images -``` - -### 4. Verify Image Registry -``` -Check for: -- Docker Hub (no prefix or docker.io/) -- MCR (mcr.microsoft.com/) -- GCR (gcr.io/) -- ECR (*.amazonaws.com/) -- Custom registry -``` - -## Confidence Determination - -### High Confidence -- ✅ Dockerfile exists with explicit FROM instruction -- ✅ Image name and tag clearly specified -- **Example**: "Base image: alpine:3.15 from Dockerfile line 1" - -### Medium Confidence -- ⚠️ Multiple stages with different base images -- ⚠️ FROM uses build argument (FROM ${BASE_IMAGE}) -- **Example**: "Base image uses variable, likely node:16 based on docker-compose" - -### Low Confidence -- ⚠️ No Dockerfile found -- ⚠️ Base image unclear from manifests -- **Example**: "Kubernetes deployment exists but base image not specified" - -### Not Applicable -- ❌ No containerization -- **Example**: "No container files found" - -## Output Format - -```json -{ - "input_name": "Base Image", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Base image identified}", - "confidence": "high|medium|low", - "evidence": [ - "{Dockerfile location}", - "{FROM instruction(s)}", - "{Multi-stage details if applicable}" - ], - "values": [ - "{Base image name:tag}", - "{OS type (Alpine, Ubuntu, etc.)}", - "{Registry source}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-communication-protocols/SKILL.md b/.github/skills/fact-communication-protocols/SKILL.md deleted file mode 100644 index 6b6a9082f..000000000 --- a/.github/skills/fact-communication-protocols/SKILL.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -name: fact-communication-protocols -description: Identify inter-service communication protocols (HTTP/REST, gRPC, Message Queue, TCP) ---- - -# Communication Protocols Analysis - -## Purpose -Detect communication protocols used for inter-service communication, API exposure, and external integrations. - -## Target Files/Locations -- **/pom.xml, **/build.gradle, **/*.csproj, **/package.json (dependencies) -- **/*.proto (gRPC definitions) -- **/application.{properties,yml} (message queue configs) -- **/*.java, **/*.cs, **/*.js (HTTP clients, gRPC stubs) - -## Example Patterns -- **HTTP/REST**: RestTemplate, HttpClient, axios, fetch, @RestController -- **gRPC**: grpc-*, *.proto files, gRPC stubs -- **Message Queues**: RabbitMQ, Kafka, Redis Pub/Sub, AWS SQS -- **TCP/UDP**: Socket, ServerSocket, TcpClient -- **WebSocket**: ws://, WebSocket, SignalR - -## Analysis Steps - -### 1. Check for HTTP/REST -``` -Use Grep: "@RestController|@RequestMapping|HttpClient|RestTemplate|axios|fetch" -Files: **/*.{java,cs,js,py} -Context: -B 2 -A 2 - -Check Spring: @RestController, @GetMapping -Check .NET: HttpClient, [ApiController] -Check Node: express, axios -``` - -### 2. Check for gRPC -``` -Use Glob: **/*.proto -Count proto files - -Use Grep: "grpc|GrpcClient|GrpcChannel" -Files: **/*.{java,cs,go,py} -Dependencies: grpc-netty, Grpc.Net.Client, @grpc/grpc-js -``` - -### 3. Check for Message Queues -``` -Use Grep: "RabbitTemplate|KafkaTemplate|@JmsListener|IMessageQueue" -Files: **/*.{java,cs} - -Dependencies: -- spring-boot-starter-amqp (RabbitMQ) -- spring-kafka (Kafka) -- MassTransit, NServiceBus (.NET) - -Config: -- spring.rabbitmq.*, spring.kafka.* -``` - -### 4. Check for WebSocket -``` -Use Grep: "WebSocket|ws://|wss://|SignalR|@ServerEndpoint" -Files: **/*.{java,cs,js} -``` - -### 5. Check for TCP/UDP -``` -Use Grep: "ServerSocket|Socket|TcpListener|UdpClient" -Files: **/*.{java,cs,go} -``` - -## Confidence Determination - -### High Confidence -- ✅ Multiple protocol indicators found -- ✅ Dependencies + code usage confirmed -- **Example**: "HTTP/REST via Spring MVC, gRPC for internal services (5 .proto files), Kafka for async messaging" - -### Medium Confidence -- ⚠️ Dependencies present but usage unclear -- **Example**: "HTTP REST API likely, gRPC dependency but no .proto files found" - -### Low Confidence -- ⚠️ Protocol inferred from framework -- **Example**: "Likely HTTP-based (web framework) but protocol not explicit" - -### Not Applicable -- ❌ Standalone application with no communication -- **Example**: "CLI tool with no network communication" - -## Output Format - -```json -{ - "input_name": "Communication Protocols", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Protocols summary}", - "confidence": "high|medium|low", - "evidence": [ - "{HTTP/REST endpoints}", - "{gRPC proto files}", - "{Message queue configs}", - "{Dependencies}" - ], - "values": [ - "{Protocol: HTTP/REST, gRPC, Kafka, RabbitMQ, etc.}", - "{Framework: Spring MVC, ASP.NET Core, Express}", - "{Port numbers}", - "{Count: N endpoints, M proto files}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-compliance-requirements/SKILL.md b/.github/skills/fact-compliance-requirements/SKILL.md deleted file mode 100644 index 4de230ea0..000000000 --- a/.github/skills/fact-compliance-requirements/SKILL.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -name: fact-compliance-requirements -description: Identify regulatory compliance needs (GDPR, HIPAA, PCI-DSS, SOX) ---- - -# Compliance Requirements Analysis - -## Purpose -Identify regulatory compliance requirements the application must meet based on data handling, industry, and security measures. - -## Target Files/Locations -- **/README.md, **/COMPLIANCE.md, **/SECURITY.md, **/privacy-policy.md -- **/docs/**/*.md -- **/*.{java,cs,js,py,ts} (data handling, encryption) -- **/application.{properties,yml} (audit logging) - -## Example Patterns -- GDPR: data protection, right to erasure, consent -- HIPAA: PHI, encryption, audit logs -- PCI-DSS: payment data, encryption at rest/transit -- SOX: financial data, audit trails, access controls - -## Analysis Steps - -### 1. Check Documentation -``` -Use Read: **/README.md, **/COMPLIANCE.md, **/SECURITY.md -Use Grep: "GDPR|HIPAA|PCI-DSS|PCI|SOX|Sarbanes-Oxley|ISO 27001|SOC 2" -Files: **/docs/**/*.md -Context: -B 2 -A 3 - -Look for: -- Compliance statements -- Regulatory requirements -- Data handling policies -``` - -### 2. Check for Data Protection Code -``` -Use Grep: "PersonalData|PII|PHI|PaymentData|encrypt|anonymize|pseudonymize" -Files: **/*.{java,cs,js,py} -Context: -B 2 -A 2 - -Indicators: -- Data encryption implementations -- Anonymization functions -- Consent management -- Data retention policies -``` - -### 3. Check for Audit Logging -``` -Use Grep: "AuditLog|audit|trail|compliance.*log" -Files: **/*.{java,cs}, **/application.{properties,yml} - -Look for: -- Audit event logging -- User action tracking -- Data access logs -``` - -### 4. Check for Data Privacy Features -``` -Search for: -- Data export (GDPR right to portability) -- Data deletion (right to erasure) -- Consent management -- Cookie policies - -Use Grep: "exportData|deleteUser|consent|privacy|GDPR" -``` - -### 5. Check Security Measures -``` -Compliance often requires: -- Encryption at rest and in transit -- Access controls (RBAC) -- Multi-factor authentication -- Regular security audits - -Cross-reference with security-implementation analysis -``` - -## Confidence Determination - -### High Confidence -- ✅ Explicit compliance documentation -- ✅ Compliance-specific code features -- ✅ Regulatory requirements mentioned -- **Example**: "GDPR compliant: data encryption, consent management, right-to-erasure API implemented" - -### Medium Confidence -- ⚠️ Some compliance features but not comprehensive -- **Example**: "Encryption and audit logging present, suggests PCI-DSS consideration but not documented" - -### Low Confidence -- ⚠️ No explicit compliance requirements -- ⚠️ Features that could support compliance -- **Example**: "Standard security features, no specific compliance mentioned" - -### Not Applicable -- ❌ Internal tool with no regulatory requirements -- **Example**: "Development utility, no compliance requirements" - -## Output Format - -```json -{ - "input_name": "Compliance Requirements", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Compliance summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Documentation mentions}", - "{Compliance-specific code}", - "{Security features}", - "{Audit logging}" - ], - "values": [ - "{Regulations: GDPR, HIPAA, PCI-DSS, SOX, etc.}", - "{Features: encryption, audit logs, consent}", - "{Data types: PII, PHI, payment data}", - "{Certifications if mentioned}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-container-engine/SKILL.md b/.github/skills/fact-container-engine/SKILL.md deleted file mode 100644 index 4d30e5ecb..000000000 --- a/.github/skills/fact-container-engine/SKILL.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -name: fact-container-engine -description: Identify container runtime being used (Docker, Podman, containerd) ---- - -# Container Engine Analysis - -## Purpose -Determine which container engine the application uses (Docker, Podman, containerd, etc.) through analysis of configuration files, build scripts, and deployment manifests. - -## Target Files/Locations -- **/Dockerfile, **/Containerfile -- **/docker-compose*.yml -- **/.dockerignore -- **/Makefile, **/*.sh (build scripts) -- **/k8s/**/*.yaml, **/*.yaml (Kubernetes manifests) -- **/README.md, **/docs/**/*.md (documentation) -- **/.github/workflows/*.yml, **/.gitlab-ci.yml (CI/CD) - -## Example Patterns to Search -- **Docker**: `docker build`, `docker-compose`, `FROM`, `ENTRYPOINT`, `.dockerignore` -- **Podman**: `podman build`, `podman-compose`, `podman run` -- **containerd**: `ctr`, `nerdctl` -- **Build tools**: `docker buildx`, `buildah`, `kaniko` - -## Analysis Steps - -### 1. Check for Dockerfile/Containerfile -``` -Use Glob: **/Dockerfile, **/Containerfile -- Dockerfile indicates Docker usage -- Containerfile indicates Podman/Buildah compatibility -``` - -### 2. Search for Docker Compose Files -``` -Use Glob: **/docker-compose*.yml -Indicates Docker Compose usage -``` - -### 3. Analyze Build Scripts -``` -Use Grep: "docker|podman|buildah|nerdctl" -Files: **/*.sh, **/Makefile, **/*.bash -Context: -B 2 -A 2 -``` - -### 4. Check CI/CD Pipelines -``` -Use Grep in CI files: -- Pattern: "docker|podman|container" -- Files: **/.github/workflows/*.yml, **/.gitlab-ci.yml -``` - -### 5. Review Documentation -``` -Use Grep in docs: -- Pattern: "docker|podman|container engine" -- Files: **/README.md, **/docs/**/*.md -``` - -## Confidence Determination - -### High Confidence -- ✅ Dockerfile + docker-compose.yml present -- ✅ Build scripts explicitly use docker commands -- ✅ CI/CD uses specific container engine -- **Example**: "Docker engine with Compose v2 based on docker-compose.yml and Dockerfile" - -### Medium Confidence -- ⚠️ Generic Containerfile (Docker/Podman compatible) -- ⚠️ Build scripts don't specify engine -- **Example**: "Containerfile present, compatible with Docker or Podman" - -### Low Confidence -- ⚠️ No explicit engine indicators -- ⚠️ Only Kubernetes manifests (engine unclear) -- **Example**: "Container usage implied but engine unclear" - -### Not Applicable -- ❌ No containerization -- **Example**: "No container files found - traditional deployment" - -## Output Format - -```json -{ - "input_name": "Container Engine", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Container engine identified}", - "confidence": "high|medium|low", - "evidence": [ - "{Files found}", - "{Commands in scripts}", - "{CI/CD configuration}" - ], - "values": [ - "{Engine name: Docker, Podman, etc.}", - "{Compose version if applicable}", - "{Build tools used}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-container-version/SKILL.md b/.github/skills/fact-container-version/SKILL.md deleted file mode 100644 index b18e4faf5..000000000 --- a/.github/skills/fact-container-version/SKILL.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -name: fact-container-version -description: Identify container runtime version (Docker, Podman version) ---- - -# Container Version Analysis - -## Purpose -Determine the version of the container runtime being used through CI/CD configurations, documentation, or system requirements. - -## Target Files/Locations -- **/.github/workflows/*.yml, **/.gitlab-ci.yml -- **/README.md, **/docs/**/*.md -- **/Makefile, **/*.sh -- **/docker-compose.yml (version field) - -## Example Patterns -- `docker-compose version: '3.8'` -- Docker version: 20.10.17 -- Podman version: 4.1.0 - -## Analysis Steps - -### 1. Check docker-compose Version -``` -Use Glob: **/docker-compose*.yml -Use Read to find: version: '3.x' or version: '2.x' -This indicates required Docker Compose version -``` - -### 2. Search CI/CD for Version Specs -``` -Use Grep: "docker.*version|container.*version" -Files: **/.github/workflows/*.yml, **/.gitlab-ci.yml -Context: -B 2 -A 2 -``` - -### 3. Check Documentation -``` -Use Grep: "docker.*[0-9]+\\.[0-9]+|podman.*[0-9]+\\.[0-9]+" -Files: **/README.md, **/docs/**/*.md -Context: -B 1 -A 1 -``` - -### 4. Look for Version Requirements -``` -Search for: -- "requires Docker 20.10+" -- "tested with Podman 4.x" -- Minimum version specifications -``` - -## Confidence Determination - -### High Confidence -- ✅ docker-compose version explicitly set -- ✅ CI/CD specifies container version -- ✅ Documentation states version requirements -- **Example**: "Docker 20.10.17 specified in CI/CD, docker-compose v3.8" - -### Medium Confidence -- ⚠️ docker-compose version found but engine version unclear -- ⚠️ Version mentioned in docs but not enforced -- **Example**: "docker-compose v3.8 indicates Docker 19.03+ requirement" - -### Low Confidence -- ⚠️ No explicit version information -- ⚠️ Version inferred from features used -- **Example**: "Features used suggest Docker 20.10+ but not specified" - -### Not Applicable -- ❌ No containerization -- **Example**: "No container configuration found" - -## Output Format - -```json -{ - "input_name": "Container Version", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Container version information}", - "confidence": "high|medium|low", - "evidence": [ - "{docker-compose version}", - "{CI/CD specifications}", - "{Documentation references}" - ], - "values": [ - "{Engine: Docker/Podman}", - "{Version number or requirement}", - "{Compose version if applicable}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-data-classification/SKILL.md b/.github/skills/fact-data-classification/SKILL.md deleted file mode 100644 index 4cf84c614..000000000 --- a/.github/skills/fact-data-classification/SKILL.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -name: fact-data-classification -description: Identify data sensitivity classification (Public, Internal, Confidential, PII) ---- - -# Data Classification Analysis - -## Purpose -Determine the sensitivity classification of data handled by the application to understand protection requirements. - -## Target Files/Locations -- **/README.md, **/SECURITY.md, **/DATA_CLASSIFICATION.md -- **/docs/**/*.md (data classification) -- **/*.{java,cs,js,py} (data annotations, comments) -- **/schema.sql, **/migrations/*.sql (database schemas) -- **/*.proto, **/*.graphql (API schemas) - -## Example Patterns -- **Public**: publicly accessible data, no protection needed -- **Internal**: company data, standard access controls -- **Confidential**: sensitive business data, strict access controls -- **PII**: personal identifiable information (names, emails, SSN) -- **PHI**: protected health information -- **PCI**: payment card data -- **Restricted**: highly sensitive, executive/legal only - -## Analysis Steps - -### 1. Check Documentation -``` -Use Read: **/README.md, **/SECURITY.md, **/DATA_CLASSIFICATION.md -Use Grep: "data classification|sensitivity|PII|confidential|restricted" -Files: **/docs/**/*.md -Context: -B 2 -A 3 - -Look for: -- Data classification policy -- Sensitivity levels -- Data types handled -``` - -### 2. Analyze Database Schemas -``` -Use Glob: **/schema.sql, **/migrations/*.sql, **/flyway/**/*.sql -Use Read to examine table definitions - -Look for sensitive data indicators: -- email, phone, address (PII) -- ssn, tax_id, national_id (PII) -- credit_card, account_number (PCI) -- password, secret, token (Credentials) -- medical, diagnosis (PHI) -- salary, financial (Confidential) -``` - -### 3. Check Code for Data Annotations -``` -Use Grep: "@PersonalData|@Confidential|@Restricted|@PII|@Sensitive" -Files: **/*.{java,cs} -Context: -B 1 -A 3 - -.NET: [PersonalData], [ProtectedPersonalData] -Java: Custom annotations or comments -``` - -### 4. Analyze API Schemas -``` -Use Glob: **/*.proto, **/*.graphql, **/openapi.yaml -Read schema definitions - -Identify sensitive fields: -- User personal information -- Authentication credentials -- Financial data -- Health information -``` - -### 5. Check Encryption Usage -``` -Encryption usage indicates sensitive data: - -Use Grep: "encrypt|cipher|AES|RSA|hash" -Files: **/*.{java,cs,js,py} -Context: -B 2 -A 2 - -What's encrypted: -- Passwords → Credentials (Confidential) -- Payment info → PCI Data -- Medical records → PHI -- Personal details → PII -``` - -### 6. Categorize Data Types -``` -Based on findings, classify: -- Public: blog posts, product catalogs -- Internal: employee directory, internal docs -- Confidential: trade secrets, financial reports -- PII: customer names, emails, addresses -- PHI: medical records, diagnoses -- PCI: credit card numbers, CVV -``` - -## Confidence Determination - -### High Confidence -- ✅ Data classification documented -- ✅ Sensitive data fields identified in schema -- ✅ Encryption applied to sensitive data -- **Example**: "Data classification: Confidential and PII - handles customer names, emails, addresses (PII) and financial transactions (Confidential)" - -### Medium Confidence -- ⚠️ Data types identified but no formal classification -- **Example**: "Database contains email and address fields (likely PII) but no classification policy documented" - -### Low Confidence -- ⚠️ Data types unclear from schema -- ⚠️ Generic field names -- **Example**: "Database schema generic, data sensitivity unclear" - -### Not Applicable -- ❌ No data storage (stateless API proxy) -- **Example**: "Stateless authentication proxy, no data stored" - -## Output Format - -```json -{ - "input_name": "Data Classification", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Classification summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Documentation}", - "{Database schema analysis}", - "{Sensitive field identification}", - "{Encryption usage}" - ], - "values": [ - "{Classification levels: Public, Internal, Confidential, PII, etc.}", - "{Sensitive data types handled}", - "{Protection measures per classification}", - "{Data volume estimates if available}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-embedded-language-usage/SKILL.md b/.github/skills/fact-embedded-language-usage/SKILL.md deleted file mode 100644 index 90c68df15..000000000 --- a/.github/skills/fact-embedded-language-usage/SKILL.md +++ /dev/null @@ -1,277 +0,0 @@ ---- -name: fact-embedded-language-usage -description: Identifies whether the Java app executes or embeds code in another language or interpreter at runtime ---- - -# Embedded Language Usage Analysis - -## Purpose -Detect if the application executes external processes, embeds scripting engines, or dynamically evaluates code in other languages at runtime. This includes shell command execution, JavaScript engines, Python interpreters, Groovy shells, and embedded SQL/native code execution. - -## Target Files/Locations -- **Java source files**: **/*.java -- **Script files**: **/*.sh, **/*.bat, **/*.ps1 -- **Configuration files**: **/application.{properties,yml}, **/pom.xml, **/build.gradle -- **Resources**: **/resources/**/*.js, **/resources/**/*.py, **/resources/**/*.groovy - -## Example Patterns to Search -- **Process Execution**: `Runtime.getRuntime().exec()`, `ProcessBuilder`, `ProcessBuilder.command()` -- **Script Engines**: `ScriptEngineManager`, `ScriptEngine.eval()`, `Nashorn`, `GraalVM.Polyglot` -- **Embedded Interpreters**: `GroovyShell`, `PythonInterpreter`, `JRuby`, `Jython` -- **Dynamic Evaluation**: `eval()`, `compile()`, `interpret()` -- **Native Code**: `System.loadLibrary()`, `JNI`, `JNA`, `native` keyword -- **SQL Execution**: `Statement.execute()`, `PreparedStatement`, dynamic SQL construction - -## Analysis Steps - -### 1. Search for Process Execution -``` -Use Grep tool to search for external process execution: -- Pattern: "Runtime\\.getRuntime\\(\\)\\.exec|ProcessBuilder|exec\\(|startProcess" -- Files: **/*.java -- Context: -B 2 -A 2 (2 lines before/after for context) - -Look for: -- Shell command execution -- External program invocation -- Dynamic command construction -``` - -### 2. Search for ScriptEngine APIs -``` -Use Grep tool to find scripting engine usage: -- Pattern: "ScriptEngineManager|ScriptEngine|Nashorn|GraalVM|Polyglot" -- Files: **/*.java -- Context: -B 3 -A 3 - -Check for: -- ScriptEngineManager instantiation -- JavaScript, Python, Groovy engine loading -- eval() or compile() calls -``` - -### 3. Search for Embedded Language Interpreters -``` -Use Grep tool to detect interpreter embedding: -- Pattern: "GroovyShell|PythonInterpreter|JRuby|Jython|LuaJ|BeanShell" -- Files: **/*.java -- Context: -B 3 -A 3 - -Identify: -- Groovy script execution -- Python code embedding -- Ruby/Lua interpreters -``` - -### 4. Check for Native Library Loading -``` -Use Grep tool to find native code usage: -- Pattern: "System\\.loadLibrary|System\\.load|native\\s+\\w+|JNI|JNA" -- Files: **/*.java -- Context: -B 2 -A 2 - -Look for: -- JNI native method declarations -- Dynamic library loading -- JNA interface definitions -``` - -### 5. Analyze Dependencies -``` -Use Glob to find build files: -- **/pom.xml -- **/build.gradle -- **/build.gradle.kts - -Use Read to check for dependencies: -- groovy-all, groovy-core -- jython, jruby -- nashorn-core, graalvm-js -- jna, jna-platform -- rhino (Mozilla JavaScript engine) -``` - -### 6. Check for Dynamic SQL Execution -``` -Use Grep tool to find dynamic SQL: -- Pattern: "Statement\\.execute|executeUpdate|executeQuery|createStatement" -- Files: **/*.java -- Context: -B 3 -A 3 - -Analyze for: -- Dynamic SQL string construction -- Concatenated SQL queries -- PreparedStatement vs Statement usage -``` - -### 7. Scan for Script Files in Resources -``` -Use Glob to find embedded scripts: -- **/resources/**/*.js -- **/resources/**/*.py -- **/resources/**/*.groovy -- **/resources/**/*.lua - -If found, these may be loaded and executed at runtime -``` - -## Confidence Determination - -### High Confidence Criteria -Evidence of actual embedded language execution with clear implementation: -- ✅ ScriptEngineManager or ProcessBuilder instantiated with specific parameters -- ✅ Code shows eval() or execute() calls with script content -- ✅ Dependencies include scripting engines (groovy, jython, nashorn) -- ✅ Script files found in resources directory -- ✅ Multiple instances of embedded language usage across codebase - -**Examples**: -- "ScriptEngineManager found in MainController.java:45 with engine.eval(jsCode)" -- "GroovyShell.evaluate() called in RuleEngine.java with 15 .groovy files in resources/" -- "ProcessBuilder executing bash scripts found in 8 locations" - -### Medium Confidence Criteria -Partial evidence or indirect indicators: -- ⚠️ Dependencies include scripting engines but no direct usage found -- ⚠️ Process execution found but limited to standard system commands -- ⚠️ Native library loading present but unclear purpose -- ⚠️ SQL execution detected but mostly using PreparedStatement -- ⚠️ Comments reference scripting but no implementation found - -**Examples**: -- "Groovy dependency in pom.xml but no GroovyShell usage detected" -- "Runtime.exec() called once in utility class for system info" -- "Native library loaded but JNI methods not clearly identified" - -### Low Confidence Criteria -Weak or ambiguous evidence: -- ⚠️ Only standard JDBC operations (no dynamic SQL) -- ⚠️ No scripting dependencies detected -- ⚠️ Process execution in test code only -- ⚠️ Commented-out embedded language code -- ⚠️ Assumptions based on project type - -**Examples**: -- "Standard PreparedStatement usage only, no dynamic SQL" -- "No scripting engine references found" -- "Process execution only in unit tests for test setup" - -### Not Applicable Criteria -When embedded language analysis doesn't apply: -- ❌ Pure Java application with no external language integration -- ❌ Library project with no executable code -- ❌ Static website or documentation-only repository -- ❌ Different platform (e.g., .NET project being analyzed for Java patterns) - -**Examples**: -- "Pure Java Spring Boot REST API with no scripting requirements" -- "Maven plugin project with no runtime execution" -- "Documentation repository with no code" - -## Output Format - -**CRITICAL**: Use the `write_assessment_result` tool (not just output JSON text). - -```json -{ - "input_name": "Embedded Language Usage", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Clear 1-2 sentence summary of embedded language usage}", - "confidence": "high|medium|low", - "evidence": [ - "{Specific file path + line number where usage detected}", - "{Type of embedded language (Groovy, JavaScript, shell, etc.)}", - "{Dependencies or script files found}", - "{Context of usage (business rules, data processing, etc.)}" - ], - "values": [ - "{Scripting engine name and version}", - "{Number of usage instances}", - "{Types of scripts found}", - "{Native libraries loaded}" - ] - }, - "execution_time_seconds": {elapsed_time}, - "timestamp": "{ISO 8601 timestamp}" -} -``` - -**Finding Examples**: -- ✅ Good: "Application uses GroovyShell to execute business rules with 23 .groovy scripts in resources/rules/ directory" -- ✅ Good: "ScriptEngineManager loads Nashorn JavaScript engine to process data transformations in DataProcessor.java" -- ✅ Good: "ProcessBuilder executes shell scripts for deployment automation in 8 service classes" -- ✅ Good: "No embedded language usage detected - pure Java implementation with standard JDBC" -- ❌ Bad: "Scripting is used" -- ❌ Bad: "Found some code execution" - -**Evidence Examples**: -- ✅ Good: "GroovyShell.evaluate() at src/main/java/com/example/rules/RuleEngine.java:67" -- ✅ Good: "groovy-all-2.5.14 dependency in pom.xml with 23 .groovy files in resources/rules/" -- ✅ Good: "ScriptEngineManager initialized in MainController.java:45 with JavaScript engine type" -- ❌ Bad: "Found scripting code" -- ❌ Bad: "Process execution detected" - -## Error Handling - -### 1. No Evidence Found -- Don't fail - report finding as "No embedded language usage detected" -- Set confidence to high if thorough search performed -- Provide reasoning: "Searched for process execution, script engines, and embedded interpreters - none found" - -### 2. Ambiguous Results -- Report what was found with context -- Set confidence to medium -- Explain uncertainty: "Groovy dependency present but no explicit usage found in code" - -### 3. Tool Failures -- If Grep fails, retry with simpler pattern -- If Grep still fails, try Bash with find/grep combination -- If Read fails on large files, try reading with offset/limit -- After 3 retry attempts, return error status with details - -### 4. Large Codebases -- If initial search returns too many results (>500 matches), refine pattern -- Focus on main source directories (exclude test code initially) -- Prioritize by file path (src/main > src/test) -- Sample representative files for detailed analysis - -## Example Complete Analysis - -**Scenario**: Java Spring Boot application with Groovy rule engine - -**Steps Executed**: -1. Grep for ScriptEngine: Found 3 matches in RuleEngine.java -2. Grep for GroovyShell: Found 15 matches across 5 files -3. Glob for .groovy files: Found 23 files in resources/rules/ -4. Read RuleEngine.java: Confirmed GroovyShell usage with dynamic script loading -5. Read pom.xml: Found groovy-all-2.5.14 dependency - -**Result**: -```json -{ - "input_name": "Embedded Language Usage", - "analysis_method": "LLM", - "status": "success", - "result": { - "finding": "Application uses Groovy as embedded scripting engine for business rules execution with 23 rule scripts loaded dynamically at runtime", - "confidence": "high", - "evidence": [ - "GroovyShell.evaluate() at src/main/java/com/example/rules/RuleEngine.java:67-89", - "groovy-all-2.5.14 dependency in pom.xml line 45", - "23 .groovy script files in src/main/resources/rules/ directory", - "RuleLoader.java:34 loads scripts from classpath using ResourceLoader", - "15 GroovyShell usage instances across 5 files in rules package" - ], - "values": [ - "Groovy 2.5.14 (groovy-all)", - "GroovyShell with CompilerConfiguration", - "23 business rule scripts (.groovy)", - "Dynamic rule evaluation at runtime" - ] - }, - "execution_time_seconds": 38.5, - "timestamp": "2026-02-28T10:15:42Z" -} -``` diff --git a/.github/skills/fact-environment-variables/SKILL.md b/.github/skills/fact-environment-variables/SKILL.md deleted file mode 100644 index 2cef10d2a..000000000 --- a/.github/skills/fact-environment-variables/SKILL.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -name: fact-environment-variables -description: Identify container environment variables and configuration ---- - -# Environment Variables Analysis - -## Purpose -Catalog environment variables used in containerized applications for configuration, secrets, and runtime behavior. - -## Target Files/Locations -- **/Dockerfile (ENV instruction) -- **/docker-compose*.yml (environment section) -- **/k8s/**/*.yaml (env, envFrom) -- **/.env, **/.env.example - -## Example Patterns -- `ENV DATABASE_URL=...` -- `environment: - NODE_ENV=production` -- `env: - name: API_KEY` -- `envFrom: - configMapRef` - -## Analysis Steps - -### 1. Check Dockerfile ENV -``` -Use Grep: "^ENV\\s+" -Files: **/Dockerfile -Extract variable names and default values -``` - -### 2. Analyze docker-compose Environment -``` -Use Read: **/docker-compose*.yml -Look for environment: section -Format: KEY=VALUE or array of strings -``` - -### 3. Check Kubernetes ConfigMaps/Secrets -``` -Use Grep: "env:|envFrom:|configMapRef|secretRef" -Files: **/k8s/**/*.yaml -Context: -B 2 -A 5 -``` - -### 4. Check .env Files -``` -Use Glob: **/.env, **/.env.example, **/.env.template -Use Read to list variable names (mask values) -``` - -### 5. Categorize Variables -``` -Group by type: -- Database: DATABASE_URL, DB_HOST, DB_PASSWORD -- API Keys: API_KEY, SECRET_KEY -- Feature Flags: ENABLE_FEATURE_X -- Runtime: NODE_ENV, LOG_LEVEL, DEBUG -``` - -## Confidence Determination - -### High Confidence -- ✅ Variables explicitly defined in multiple files -- ✅ .env.example provides template -- **Example**: "12 environment variables configured including DATABASE_URL, API_KEY, NODE_ENV" - -### Medium Confidence -- ⚠️ Some variables in code but not all documented -- **Example**: "Environment variables used but no .env.example template" - -### Low Confidence -- ⚠️ Variables referenced but not listed -- **Example**: "Application likely uses env vars but none explicitly configured" - -### Not Applicable -- ❌ No container or hardcoded config -- **Example**: "No environment variable usage detected" - -## Output Format - -```json -{ - "input_name": "Environment Variables", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Variables summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Dockerfile ENV count}", - "{docker-compose environment}", - "{K8s ConfigMap/Secret refs}", - "{.env file presence}" - ], - "values": [ - "{Variable names (masked values)}", - "{Categories: database, api, runtime, etc.}", - "{Count: N variables}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-external-dependencies/SKILL.md b/.github/skills/fact-external-dependencies/SKILL.md deleted file mode 100644 index f62559edb..000000000 --- a/.github/skills/fact-external-dependencies/SKILL.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -name: fact-external-dependencies -description: Identify external system dependencies (SQL Server, Redis, LDAP, File shares) ---- - -# External Dependencies Analysis - -## Purpose -Catalog external systems and services the application depends on including databases, caches, authentication services, and storage. - -## Target Files/Locations -- **/application.{properties,yml} (connection strings) -- **/docker-compose*.yml (external services) -- **/*.env.example (dependency URLs) -- **/README.md (setup instructions) -- **/*.{java,cs,js,py} (connection code) - -## Example Patterns -- **Databases**: SQL Server, PostgreSQL, MySQL, Oracle, MongoDB -- **Caches**: Redis, Memcached, Elasticsearch -- **Auth**: LDAP, Active Directory, OAuth providers -- **Storage**: S3, Azure Blob, NFS, SMB -- **Queues**: RabbitMQ, Kafka, SQS, Azure Service Bus - -## Analysis Steps - -### 1. Check Application Configuration -``` -Use Grep: "datasource|database|jdbc:|connectionString|redis|ldap|s3|blob" -Files: **/application.{properties,yml}, **/appsettings*.json -Context: -B 1 -A 2 - -Extract: -- spring.datasource.url=jdbc:sqlserver://... -- ConnectionStrings:DefaultConnection -- redis.host -- ldap.url -``` - -### 2. Check docker-compose Services -``` -Use Read: **/docker-compose*.yml -Identify services: -- postgres, mysql, sqlserver -- redis, memcached -- rabbitmq, kafka -- elasticsearch - -Note: external vs internal dependencies -``` - -### 3. Check Environment Variables -``` -Use Read: **/.env.example -Look for: -- DATABASE_URL -- REDIS_URL -- LDAP_SERVER -- S3_BUCKET -- API endpoint URLs -``` - -### 4. Check Documentation -``` -Use Read: **/README.md -Look for: -- Prerequisites section -- External services setup -- Configuration instructions -``` - -### 5. Search Code for Connections -``` -Use Grep: "SqlConnection|MongoClient|RedisClient|LdapContext|S3Client" -Files: **/*.{java,cs,js,py} -Context: -B 2 -A 3 -``` - -## Confidence Determination - -### High Confidence -- ✅ Dependencies in config + docker-compose + docs -- ✅ Connection strings present -- **Example**: "External dependencies: SQL Server 2019, Redis 6, LDAP (Active Directory), Azure Blob Storage from config and docs" - -### Medium Confidence -- ⚠️ Dependencies referenced but details incomplete -- **Example**: "Database required (connection string present) but type/version unclear" - -### Low Confidence -- ⚠️ Possible dependencies inferred from code -- **Example**: "May use Redis based on client library dependency" - -### Not Applicable -- ❌ Fully self-contained application -- **Example**: "Standalone application with embedded database, no external dependencies" - -## Output Format - -```json -{ - "input_name": "External Dependencies", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Dependencies summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Configuration entries}", - "{docker-compose services}", - "{Documentation}", - "{Connection code}" - ], - "values": [ - "{Dependency: SQL Server, Redis, etc.}", - "{Versions if known}", - "{Purpose: database, cache, auth, storage}", - "{Count: N external systems}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-external-services/SKILL.md b/.github/skills/fact-external-services/SKILL.md deleted file mode 100644 index 96ec40729..000000000 --- a/.github/skills/fact-external-services/SKILL.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -name: fact-external-services -description: Identify external service dependencies (Database, Redis, Message queues) ---- - -# External Services Analysis - -## Purpose -Detect external service dependencies like databases, caches, message queues, and other backend services the application connects to. - -## Target Files/Locations -- **/docker-compose*.yml (services section) -- **/k8s/**/*.yaml (Service, StatefulSet) -- **/application.{properties,yml} -- **/.env, **/.env.example -- **/*.{java,cs,js,py} (connection strings) - -## Example Patterns -- `postgres:13`, `redis:alpine`, `rabbitmq:3-management` -- `spring.datasource.url`, `REDIS_URL`, `MONGODB_URI` - -## Analysis Steps - -### 1. Check docker-compose Services -``` -Use Read: **/docker-compose*.yml -Look for services: beyond the main app (postgres, redis, mongo, rabbitmq, elasticsearch, etc.) -``` - -### 2. Analyze Application Configuration -``` -Use Grep: "datasource|database|redis|mongo|rabbit|kafka|elasticsearch" -Files: **/application.{properties,yml} -Context: -B 1 -A 2 -``` - -### 3. Check Environment Variables -``` -Use Grep: "DATABASE_URL|REDIS_URL|MONGO|RABBITMQ|KAFKA" -Files: **/.env.example, **/Dockerfile, **/k8s/**/*.yaml -``` - -### 4. Search for Connection Strings in Code -``` -Use Grep: "jdbc:|redis://|mongodb://|amqp://" -Files: **/*.{java,cs,js,py} -Context: -B 2 -A 1 -``` - -## Confidence Determination - -### High Confidence -- ✅ Services in docker-compose + connection config -- ✅ Connection strings in application config -- **Example**: "External services: PostgreSQL 13, Redis 6, RabbitMQ 3 from docker-compose and connection strings" - -### Medium Confidence -- ⚠️ References to services but no explicit config -- **Example**: "Database referenced in code but connection details unclear" - -### Low Confidence -- ⚠️ Possible service usage, not confirmed -- **Example**: "May use database based on ORM dependency" - -### Not Applicable -- ❌ Standalone app with no external services -- **Example**: "Static file server, no external dependencies" - -## Output Format - -```json -{ - "input_name": "External Services", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Services summary}", - "confidence": "high|medium|low", - "evidence": [ - "{docker-compose services}", - "{Connection configs}", - "{Environment variables}" - ], - "values": [ - "{Service types: PostgreSQL, Redis, etc.}", - "{Versions}", - "{Count: N services}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-hardware-requirements/SKILL.md b/.github/skills/fact-hardware-requirements/SKILL.md deleted file mode 100644 index b789d5a66..000000000 --- a/.github/skills/fact-hardware-requirements/SKILL.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -name: fact-hardware-requirements -description: Identify minimum hardware requirements (RAM, CPU, disk) ---- - -# Hardware Requirements Analysis - -## Purpose -Extract minimum hardware requirements from documentation, resource configurations, and deployment files. - -## Target Files/Locations -- **/README.md, **/INSTALL.md, **/REQUIREMENTS.md (system requirements) -- **/docs/**/*.md (hardware mentions) -- **/docker-compose*.yml (resource limits) -- **/k8s/**/*.yaml (resource requests/limits) - -## Example Patterns -- "4GB RAM minimum" -- "2 CPU cores recommended" -- "10GB disk space required" -- `limits: memory: "4Gi", cpu: "2"` - -## Analysis Steps - -### 1. Check Documentation -``` -Use Read: **/README.md, **/INSTALL.md, **/REQUIREMENTS.md -Search for: -- "System Requirements" section -- "Hardware Requirements" section -- RAM/memory mentions (GB, GiB) -- CPU mentions (cores, GHz) -- Disk mentions (GB storage) - -Use Grep: "[0-9]+\\s*(GB|GiB|MB|MiB)|[0-9]+\\s*(cores?|CPU)|disk|storage" -Context: -B 2 -A 2 -``` - -### 2. Check Container Resource Limits -``` -Use Read: **/docker-compose*.yml -Look for deploy.resources.limits/reservations - -Use Grep: "memory:|cpu:" -Files: **/k8s/**/*.yaml -Context: -B 3 -A 1 - -Extract resource specifications: -- Memory: 2Gi, 4Gi, 512Mi -- CPU: 1000m, 2, 500m -``` - -### 3. Analyze Resource Patterns -``` -From K8s/Compose: -- limits = maximum resources -- requests/reservations = minimum required - -Calculate totals for multi-container apps -``` - -### 4. Check Database Requirements -``` -If database used, estimate: -- PostgreSQL: ~1GB RAM minimum -- MySQL: ~512MB RAM minimum -- MongoDB: ~1GB RAM minimum -- Plus storage for data -``` - -## Confidence Determination - -### High Confidence -- ✅ Requirements explicitly documented -- ✅ Resource limits configured match docs -- **Example**: "4GB RAM, 2 CPU cores, 10GB disk from README and matching K8s resource requests" - -### Medium Confidence -- ⚠️ Requirements in one source only -- **Example**: "4GB memory limit in docker-compose, no documentation" - -### Low Confidence -- ⚠️ Requirements estimated from resources used -- **Example**: "Estimated 2GB RAM based on container limits, not documented" - -### Not Applicable -- ❌ Serverless or managed platform -- **Example**: "AWS Lambda deployment, hardware not directly specified" - -## Output Format - -```json -{ - "input_name": "Hardware Requirements", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Hardware summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Documentation sections}", - "{Container resource limits}", - "{Calculations}" - ], - "values": [ - "{RAM: minimum and recommended}", - "{CPU: cores or millicores}", - "{Disk: storage requirements}", - "{Network: if specified}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-health-checks/SKILL.md b/.github/skills/fact-health-checks/SKILL.md deleted file mode 100644 index 4c12bd2bf..000000000 --- a/.github/skills/fact-health-checks/SKILL.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -name: fact-health-checks -description: Identify health check configurations (HTTP checks, command checks) ---- - -# Health Checks Analysis - -## Purpose -Identify health check and readiness probe configurations for monitoring application health. - -## Target Files/Locations -- **/Dockerfile (HEALTHCHECK instruction) -- **/docker-compose*.yml (healthcheck section) -- **/k8s/**/*.yaml (livenessProbe, readinessProbe, startupProbe) -- **/*.{java,cs,js,py,go} (health endpoints) - -## Example Patterns -- `HEALTHCHECK CMD curl -f http://localhost/ || exit 1` -- `healthcheck: test: ["CMD", "curl", "-f", "http://localhost"]` -- `livenessProbe: httpGet: path: /health` - -## Analysis Steps - -### 1. Check Dockerfile HEALTHCHECK -``` -Use Grep: "^HEALTHCHECK" -Files: **/Dockerfile -Parse: CMD, interval, timeout, retries -``` - -### 2. Analyze docker-compose Healthchecks -``` -Use Read: **/docker-compose*.yml -Look for healthcheck: section per service - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost/health"] - interval: 30s - timeout: 10s - retries: 3 -``` - -### 3. Check Kubernetes Probes -``` -Use Grep: "livenessProbe:|readinessProbe:|startupProbe:" -Files: **/k8s/**/*.yaml -Context: -A 10 - -Parse probe types: -- httpGet: path + port -- exec: command -- tcpSocket: port -``` - -### 4. Search for Health Endpoints in Code -``` -Use Grep: "/health|/healthz|/ready|/live|HealthCheck" -Files: **/*.{java,cs,js,py,go} -Context: -B 2 -A 5 - -Common frameworks: -- Spring Boot: /actuator/health -- ASP.NET Core: /health -- Express.js: /health -``` - -## Confidence Determination - -### High Confidence -- ✅ Health checks configured in orchestration files -- ✅ Health endpoint exists in code -- **Example**: "Health checks: HTTP GET /health endpoint with 30s interval, 3 retries" - -### Medium Confidence -- ⚠️ Health check configured but endpoint unclear -- **Example**: "HEALTHCHECK defined using curl but endpoint not verified" - -### Low Confidence -- ⚠️ No explicit health checks configured -- **Example**: "No health checks configured, relies on container exit codes" - -### Not Applicable -- ❌ Simple app with no health monitoring needs -- **Example**: "Batch job, health checks not applicable" - -## Output Format - -```json -{ - "input_name": "Health Checks", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Health checks summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Dockerfile HEALTHCHECK}", - "{docker-compose healthcheck}", - "{K8s probes}", - "{Health endpoint in code}" - ], - "values": [ - "{Check type: HTTP, exec, TCP}", - "{Endpoint: /health, /ready, etc.}", - "{Timing: interval, timeout, retries}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-image-layers/SKILL.md b/.github/skills/fact-image-layers/SKILL.md deleted file mode 100644 index ec7e63aa8..000000000 --- a/.github/skills/fact-image-layers/SKILL.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -name: fact-image-layers -description: Analyze container image layer count and structure ---- - -# Image Layers Analysis - -## Purpose -Analyze Dockerfile instructions to understand image layer structure, count of layers, and optimization opportunities. - -## Target Files/Locations -- **/Dockerfile, **/Containerfile - -## Example Patterns -Layer-creating instructions: RUN, COPY, ADD, FROM -Non-layer instructions: ENV, ARG, LABEL, EXPOSE, CMD, ENTRYPOINT, WORKDIR - -## Analysis Steps - -### 1. Count Layer-Creating Instructions -``` -Use Grep to count RUN/COPY/ADD: -- Pattern: "^(RUN|COPY|ADD)\\s+" -- Files: **/Dockerfile, **/Containerfile -- Mode: count - -Each match creates a layer (except multi-stage FROM) -``` - -### 2. Analyze RUN Instruction Complexity -``` -Use Read Dockerfile and analyze: -- Single-command RUN vs multi-command (&&) -- Layer optimization (combined commands) -- Example: RUN apt-get update && apt-get install (1 layer) - vs: RUN apt-get update \n RUN apt-get install (2 layers) -``` - -### 3. Check for Multi-stage Build -``` -Count FROM instructions: -Each stage adds base layers -Final image only includes layers from last stage + COPY --from -``` - -### 4. Identify Layer Size Contributors -``` -Look for large operations: -- Package installations (apt-get, yum, apk) -- File copies (COPY large directories) -- Downloads (wget, curl in RUN) -``` - -## Confidence Determination - -### High Confidence -- ✅ Dockerfile analyzed completely -- ✅ Clear count of layer instructions -- ✅ Multi-stage structure understood -- **Example**: "Image has 8 layers: 3 from base (alpine), 3 RUN, 2 COPY" - -### Medium Confidence -- ⚠️ Some build-time variables affect layers -- ⚠️ External build process unclear -- **Example**: "Approximately 6-8 layers based on Dockerfile instructions" - -### Low Confidence -- ⚠️ Dockerfile uses complex ARGs affecting structure -- ⚠️ BuildKit features that modify layering -- **Example**: "Layer count unclear due to conditional build steps" - -### Not Applicable -- ❌ No Dockerfile -- **Example**: "No container image definition found" - -## Output Format - -```json -{ - "input_name": "Image Layers", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Layer analysis summary}", - "confidence": "high|medium|low", - "evidence": [ - "{RUN instruction count}", - "{COPY/ADD instruction count}", - "{Multi-stage stages}", - "{Optimization patterns observed}" - ], - "values": [ - "{Estimated layer count}", - "{FROM instructions: N}", - "{RUN instructions: N}", - "{COPY/ADD instructions: N}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-image-size/SKILL.md b/.github/skills/fact-image-size/SKILL.md deleted file mode 100644 index 64771d061..000000000 --- a/.github/skills/fact-image-size/SKILL.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -name: fact-image-size -description: Analyze and estimate container image size ---- - -# Image Size Analysis - -## Purpose -Estimate container image size based on base image, installed packages, and copied files. Identify size optimization opportunities. - -## Target Files/Locations -- **/Dockerfile, **/Containerfile -- Application artifacts to be copied - -## Example Patterns -- Base image (alpine: ~5MB, ubuntu: ~70MB, node:16: ~900MB) -- Package installations (apt, yum, apk) -- Application files (JAR, WAR, binaries) - -## Analysis Steps - -### 1. Identify Base Image Size -``` -Read Dockerfile for FROM instruction -Estimate base sizes: -- scratch: 0MB -- alpine:3.15: ~5MB -- distroless: ~20MB -- ubuntu:20.04: ~70MB -- debian:11: ~120MB -- node:16: ~900MB -- openjdk:11: ~600MB -- mcr.microsoft.com/dotnet/runtime:6.0: ~180MB -``` - -### 2. Analyze Package Installations -``` -Use Grep: "apt-get install|apk add|yum install" -Files: **/Dockerfile -Context: -A 3 - -Estimate: -- Few utilities (curl, wget): +5-10MB -- Build tools (gcc, make): +100-200MB -- Large packages (nginx, postgresql): +50-100MB each -``` - -### 3. Check Application Files Size -``` -For COPY/ADD instructions: -- Look for source paths -- Use Bash to check size: du -sh {source_path} -- Common sizes: - - JAR files: 30-150MB - - Node modules: 100-500MB - - .NET publish: 50-100MB -``` - -### 4. Consider Multi-stage Build Efficiency -``` -If multi-stage: -- Build stage size doesn't matter -- Only final stage COPY --from adds to size -- Final image = base + runtime files only -``` - -### 5. Calculate Estimate -``` -Total = Base + Packages + Application Files + Layer Overhead -Layer overhead: ~10-20% for metadata -``` - -## Confidence Determination - -### High Confidence -- ✅ Base image size known -- ✅ Application files sized via filesystem -- ✅ Package installations enumerated -- **Example**: "Estimated 250MB: alpine (5MB) + Java runtime (150MB) + app JAR (85MB) + dependencies (10MB)" - -### Medium Confidence -- ⚠️ Base image known but packages unclear -- ⚠️ Application size estimated without measurement -- **Example**: "Approximately 200-300MB based on Node.js base and typical app size" - -### Low Confidence -- ⚠️ Complex build process with many layers -- ⚠️ Cannot access application files for sizing -- **Example**: "Likely 100MB-1GB range, difficult to estimate without build" - -### Not Applicable -- ❌ No containerization -- **Example**: "No Dockerfile found" - -## Output Format - -```json -{ - "input_name": "Image Size", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Image size estimate with breakdown}", - "confidence": "high|medium|low", - "evidence": [ - "{Base image and size}", - "{Package installations}", - "{Application files size}", - "{Calculation method}" - ], - "values": [ - "{Estimated total size: XMB or X.XGB}", - "{Base image size}", - "{Application layer size}", - "{Dependencies size}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-language-dependencies/SKILL.md b/.github/skills/fact-language-dependencies/SKILL.md deleted file mode 100644 index eefd957c2..000000000 --- a/.github/skills/fact-language-dependencies/SKILL.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -name: fact-language-dependencies -description: Identify language-specific dependencies in container (package.json, requirements.txt, pom.xml) ---- - -# Language Dependencies Analysis - -## Purpose -Identify application-level dependencies through package manifests copied into the container image. - -## Target Files/Locations -- **/package.json, **/package-lock.json (Node.js) -- **/requirements.txt, **/Pipfile (Python) -- **/pom.xml, **/build.gradle (Java) -- **/*.csproj, **/packages.config (.NET) -- **/go.mod, **/go.sum (Go) -- **/Gemfile, **/Gemfile.lock (Ruby) -- **/composer.json (PHP) - -## Example Patterns -- `COPY package*.json ./` -- `RUN pip install -r requirements.txt` -- `RUN npm install --production` -- `RUN mvn clean install` - -## Analysis Steps - -### 1. Identify Copied Dependency Files -``` -Use Grep: "COPY.*(package\\.json|requirements\\.txt|pom\\.xml|.*\\.csproj|go\\.mod|Gemfile|composer\\.json)" -Files: **/Dockerfile -Context: -B 1 -A 1 -``` - -### 2. Read Dependency Files -``` -Use Glob to find dependency files in project: -- **/package.json (read dependencies section) -- **/requirements.txt (read package list) -- **/pom.xml (read <dependencies>) -- **/*.csproj (read <PackageReference>) -``` - -### 3. Count and Categorize Dependencies -``` -For each runtime: -- Node.js: dependencies vs devDependencies -- Python: required packages -- Java: compile, runtime, test scope -- .NET: PackageReference items -- Go: direct vs indirect -``` - -### 4. Check Install Commands -``` -Use Grep: "npm install|pip install|mvn|gradle|dotnet restore|go mod download" -Files: **/Dockerfile -Verify dependencies are installed in image -``` - -## Confidence Determination - -### High Confidence -- ✅ Dependency files copied and installed in Dockerfile -- ✅ Files readable and parseable -- **Example**: "45 Node.js dependencies from package.json installed via npm install" - -### Medium Confidence -- ⚠️ Dependency files exist but install command unclear -- **Example**: "package.json present, installation method not explicit" - -### Low Confidence -- ⚠️ Can't access dependency files -- **Example**: "Dependency files referenced but not readable" - -### Not Applicable -- ❌ No language dependencies (native binary) -- **Example**: "Compiled Go binary with no external dependencies" - -## Output Format - -```json -{ - "input_name": "Language Dependencies", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Dependencies summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Dependency files found}", - "{COPY/install commands}", - "{Dependency count}" - ], - "values": [ - "{Dependency file: package.json, requirements.txt, etc.}", - "{Dependency count}", - "{Key dependencies list}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-licensing-information/SKILL.md b/.github/skills/fact-licensing-information/SKILL.md deleted file mode 100644 index f41f10ea0..000000000 --- a/.github/skills/fact-licensing-information/SKILL.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -name: fact-licensing-information -description: Identify software licensing details from LICENSE files and dependency analysis ---- - -# Licensing Information Analysis - -## Purpose -Extract licensing information for the application and its dependencies to understand compliance requirements. - -## Target Files/Locations -- **/LICENSE, **/LICENSE.txt, **/LICENSE.md -- **/pom.xml (<licenses>) -- **/package.json (license field) -- **/*.csproj (<PackageLicenseExpression>) -- **/NOTICE, **/COPYING, **/COPYRIGHT - -## Example Patterns -- MIT License -- Apache License 2.0 -- GPL v3, LGPL -- BSD 3-Clause -- Commercial/Proprietary - -## Analysis Steps - -### 1. Check License Files -``` -Use Glob: **/LICENSE*, **/COPYING, **/COPYRIGHT -Use Read to examine content - -Identify license type: -- MIT: "Permission is hereby granted, free of charge" -- Apache 2.0: "Apache License, Version 2.0" -- GPL: "GNU General Public License" -- BSD: "Redistribution and use in source and binary forms" -``` - -### 2. Check Build File Licenses -``` -Maven (pom.xml): -Use Grep: "<licenses>|<license>" -Extract: <name>Apache License 2.0</name> - -Node.js (package.json): -Use Read and parse: { "license": "MIT" } - -.NET (*.csproj): -Use Grep: "<PackageLicenseExpression>" -Extract: <PackageLicenseExpression>MIT</PackageLicenseExpression> -``` - -### 3. Check Dependency Licenses -``` -Look for license reports: -- **/license-report.html -- **/licenses/ directory -- THIRD-PARTY-NOTICES - -Tools that generate these: -- maven-license-plugin -- license-checker (npm) -- dotnet list package --include-transitive -``` - -### 4. Scan for Commercial Licenses -``` -Use Grep: "commercial|proprietary|all rights reserved|confidential" -Files: **/LICENSE*, **/README.md -Context: -B 2 -A 2 -``` - -## Confidence Determination - -### High Confidence -- ✅ LICENSE file present with clear text -- ✅ License in build file matches LICENSE file -- **Example**: "MIT License confirmed in LICENSE file and package.json" - -### Medium Confidence -- ⚠️ License file present but type unclear -- ⚠️ Multiple licenses mentioned -- **Example**: "LICENSE file present, appears to be MIT but not standard format" - -### Low Confidence -- ⚠️ No LICENSE file, inferred from comments -- **Example**: "No LICENSE file, copyright header suggests proprietary" - -### Not Applicable -- ❌ Internal tool with no license requirement -- **Example**: "Internal company tool, no formal licensing" - -## Output Format - -```json -{ - "input_name": "Licensing Information", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{License summary}", - "confidence": "high|medium|low", - "evidence": [ - "{LICENSE file presence and content}", - "{Build file license declaration}", - "{Dependency licenses if available}", - "{Copyright notices}" - ], - "values": [ - "{Primary license: MIT, Apache 2.0, etc.}", - "{Dependency licenses if scanned}", - "{Copyright holder}", - "{License compatibility notes}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-multi-stage-build/SKILL.md b/.github/skills/fact-multi-stage-build/SKILL.md deleted file mode 100644 index dde08a83c..000000000 --- a/.github/skills/fact-multi-stage-build/SKILL.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -name: fact-multi-stage-build -description: Check if Dockerfile uses multi-stage build pattern ---- - -# Multi-stage Build Analysis - -## Purpose -Determine if the project uses Docker multi-stage builds for image optimization. - -## Target Files/Locations -- **/Dockerfile, **/Dockerfile.*, **/*.Dockerfile, **/Containerfile - -## Analysis Steps - -### 1. Find Dockerfile(s) -``` -Use Glob: **/Dockerfile, **/Dockerfile.*, **/*.Dockerfile, **/Containerfile -List all matching files -``` - -### 2. Count FROM Instructions -``` -Use Grep: "^FROM\\s+" -Files: (all Dockerfiles found in step 1) - -Count the number of FROM instructions per file: -- 1 FROM = single-stage build -- 2+ FROM = multi-stage build -``` - -### 3. Extract Named Stages -``` -Use Grep: "^FROM\\s+.*\\s+[Aa][Ss]\\s+" -Files: (all Dockerfiles found in step 1) -Context: full line - -Extract stage names from "FROM ... AS stage_name" patterns -``` - -### 4. Verify Stage Usage -``` -Use Grep: "--from=" -Files: (all Dockerfiles found in step 1) - -Check COPY --from=stage_name instructions to verify multi-stage usage -``` - -## Confidence Determination - -### High Confidence -- ✅ Multiple FROM instructions with named stages -- ✅ COPY --from= instructions present -- **Example**: "Multi-stage build detected in Dockerfile with 3 stages (builder, tester, runtime)" - -### Medium Confidence -- ⚠️ Multiple FROM instructions but no named stages -- **Example**: "Multi-stage build with 2 unnamed stages" - -### Low Confidence -- ⚠️ Single FROM instruction -- **Example**: "Single-stage build, no optimization" - -### Not Applicable -- ❌ No Dockerfile found -- **Example**: "No Dockerfile or Containerfile found in project" - -## Output Format - -```json -{ - "input_name": "Multi-stage Build", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Multi-stage build summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Dockerfile locations}", - "{FROM instruction count}", - "{Named stages}" - ], - "values": [ - "{Build type: Multi-stage or Single-stage}", - "{Stage count}", - "{Stage names if available}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-network-settings/SKILL.md b/.github/skills/fact-network-settings/SKILL.md deleted file mode 100644 index 268fb17de..000000000 --- a/.github/skills/fact-network-settings/SKILL.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -name: fact-network-settings -description: Analyze container network configuration (bridge, host, custom networks) ---- - -# Network Settings Analysis - -## Purpose -Identify container networking configuration including network modes, custom networks, and inter-service communication. - -## Target Files/Locations -- **/docker-compose*.yml (networks section) -- **/k8s/**/*.yaml (Service, NetworkPolicy) -- **/Dockerfile (EXPOSE) - -## Example Patterns -- `networks: - frontend - backend` -- `network_mode: bridge|host|none` -- `kind: NetworkPolicy` - -## Analysis Steps - -### 1. Check docker-compose Networks -``` -Use Read: **/docker-compose*.yml -Look for: -- networks: top-level definitions -- service-level network assignments -- network_mode: bridge, host, none, container:name -``` - -### 2. Analyze Kubernetes Networking -``` -Use Grep: "kind: Service|kind: NetworkPolicy|clusterIP|nodePort" -Files: **/k8s/**/*.yaml -Context: -B 1 -A 10 -``` - -### 3. Check for Custom Network Drivers -``` -In docker-compose: -- driver: bridge, overlay, macvlan -- ipam: configuration -- external: true/false -``` - -## Confidence Determination - -### High Confidence -- ✅ Networks explicitly configured -- ✅ Network mode and drivers specified -- **Example**: "Custom bridge network 'app-network' with frontend and backend subnets" - -### Medium Confidence -- ⚠️ Default networking, no custom config -- **Example**: "Uses default bridge network, no custom configuration" - -### Low Confidence -- ⚠️ Networking inferred from service definitions -- **Example**: "Networking likely default, no explicit configuration" - -### Not Applicable -- ❌ Non-networked application -- **Example**: "CLI tool, no network requirements" - -## Output Format - -```json -{ - "input_name": "Network Settings", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Networking summary}", - "confidence": "high|medium|low", - "evidence": [ - "{docker-compose networks}", - "{K8s Services/Policies}", - "{Network mode}" - ], - "values": [ - "{Network names}", - "{Network mode: bridge, host, overlay}", - "{Driver: bridge, overlay, etc.}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-operating-system/SKILL.md b/.github/skills/fact-operating-system/SKILL.md deleted file mode 100644 index 57a37dc44..000000000 --- a/.github/skills/fact-operating-system/SKILL.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -name: fact-operating-system -description: Identify target/current operating system for deployment ---- - -# Operating System Analysis - -## Purpose -Determine the target or current operating system the application runs on, especially for containerized or cloud-native applications. - -## Target Files/Locations -- **/Dockerfile (FROM base image OS) -- **/README.md, **/docs/**/*.md (system requirements) -- **/k8s/**/*.yaml (nodeSelector, node affinity) -- **/pom.xml, **/*.csproj (target runtime identifiers) - -## Example Patterns -- **Container base**: FROM alpine:3.15, FROM ubuntu:20.04, FROM mcr.microsoft.com/windows/servercore:ltsc2019 -- **.NET RID**: linux-x64, win-x64, osx-x64 -- **Node selector**: kubernetes.io/os: linux - -## Analysis Steps - -### 1. Check Container Base Image OS -``` -Use Grep: "^FROM\\s+" -Files: **/Dockerfile -Extract base image name - -Map to OS: -- alpine → Alpine Linux -- ubuntu → Ubuntu Linux -- debian → Debian Linux -- centos/rocky → CentOS/Rocky Linux -- windows/servercore → Windows Server -- mcr.microsoft.com/windows → Windows -``` - -### 2. Check .NET Runtime Identifiers -``` -Use Grep: "RuntimeIdentifier|<RuntimeIdentifiers>" -Files: **/*.csproj - -RIDs: -- linux-x64 → Linux 64-bit -- linux-arm64 → Linux ARM 64-bit -- win-x64 → Windows 64-bit -- win-arm64 → Windows ARM 64-bit -- osx-x64 → macOS Intel -- osx-arm64 → macOS Apple Silicon -``` - -### 3. Check Kubernetes Node Selectors -``` -Use Grep: "nodeSelector:|kubernetes\\.io/os:" -Files: **/k8s/**/*.yaml -Context: -A 3 - -Values: -- linux → Linux nodes -- windows → Windows nodes -``` - -### 4. Check Documentation -``` -Use Read: **/README.md (first 100 lines) -Look for: -- System Requirements section -- OS mentions (Linux, Windows, macOS) -- Installation instructions per OS -``` - -### 5. Check Platform-Specific Scripts -``` -Use Glob: -- **/*.sh → Linux/macOS -- **/*.ps1, **/*.bat → Windows - -Presence indicates OS support -``` - -## Confidence Determination - -### High Confidence -- ✅ OS explicitly defined in container base or RID -- ✅ Documentation confirms OS -- **Example**: "Target OS: Alpine Linux 3.15 from Dockerfile base image" - -### Medium Confidence -- ⚠️ OS inferred from framework or scripts -- **Example**: "Likely Linux (shell scripts present, typical Java deployment)" - -### Low Confidence -- ⚠️ OS unclear, multiple possibilities -- **Example**: "Cross-platform framework, specific OS deployment unclear" - -### Not Applicable -- ❌ Pure Java/JVM with no OS-specific features -- **Example**: "Platform-independent Java library" - -## Output Format - -```json -{ - "input_name": "Operating System", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{OS summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Container base image}", - "{Runtime identifier}", - "{Documentation}", - "{Scripts}" - ], - "values": [ - "{OS: Alpine Linux, Ubuntu, Windows Server, etc.}", - "{Version: 3.15, 20.04, 2019, etc.}", - "{Architecture: x64, arm64}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-orchestration-tool/SKILL.md b/.github/skills/fact-orchestration-tool/SKILL.md deleted file mode 100644 index 00fabf2a4..000000000 --- a/.github/skills/fact-orchestration-tool/SKILL.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -name: fact-orchestration-tool -description: Identify container orchestration platform (Docker Compose, Kubernetes, Docker Swarm) ---- - -# Orchestration Tool Analysis - -## Purpose -Determine which container orchestration tool manages the application deployment. - -## Target Files/Locations -- **/docker-compose*.yml (Docker Compose) -- **/k8s/**/*.yaml, **/*.yaml (Kubernetes) -- **/swarm/ (Docker Swarm) -- **/.github/workflows/, **/.gitlab-ci.yml (CI/CD hints) - -## Example Patterns -- Docker Compose: `docker-compose.yml`, `version: '3.8'` -- Kubernetes: `kind: Deployment`, `apiVersion: apps/v1` -- Docker Swarm: `deploy: mode: replicated` - -## Analysis Steps - -### 1. Check for Docker Compose -``` -Use Glob: **/docker-compose*.yml -If found: Docker Compose is used -Check version: '2.x' or '3.x' -``` - -### 2. Check for Kubernetes Manifests -``` -Use Glob: **/k8s/**/*.yaml, **/manifests/**/*.yaml -Use Grep: "apiVersion:.*apps/v1|kind: Deployment|kind: Service" -Files: **/*.yaml -If Kubernetes resources found: K8s is used -``` - -### 3. Check for Docker Swarm Config -``` -Use Grep: "deploy:|mode: replicated|placement:" -Files: **/docker-compose*.yml -Swarm uses Compose format with deploy: section -``` - -### 4. Check CI/CD for Deployment Hints -``` -Use Grep: "kubectl|helm|docker-compose|docker stack" -Files: **/.github/workflows/*.yml, **/.gitlab-ci.yml -Context: -B 2 -A 2 -``` - -## Confidence Determination - -### High Confidence -- ✅ Clear orchestration files present -- ✅ CI/CD deploys using specific tool -- **Example**: "Kubernetes orchestration with 15 manifests in k8s/ directory and kubectl in CI/CD" - -### Medium Confidence -- ⚠️ Files present but usage unclear -- **Example**: "docker-compose.yml for local dev, K8s for production (multiple tools)" - -### Low Confidence -- ⚠️ No clear orchestration indicators -- **Example**: "Single Dockerfile, orchestration unclear" - -### Not Applicable -- ❌ No container orchestration -- **Example**: "Direct Docker run, no orchestration" - -## Output Format - -```json -{ - "input_name": "Orchestration Tool", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Orchestration summary}", - "confidence": "high|medium|low", - "evidence": [ - "{docker-compose.yml presence}", - "{K8s manifest count and location}", - "{CI/CD deployment commands}" - ], - "values": [ - "{Tool: Docker Compose, Kubernetes, Docker Swarm}", - "{Version: Compose 3.8, K8s 1.25, etc.}", - "{Manifest count}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-profile-settings/SKILL.md b/.github/skills/fact-profile-settings/SKILL.md deleted file mode 100644 index 9112a6b57..000000000 --- a/.github/skills/fact-profile-settings/SKILL.md +++ /dev/null @@ -1,332 +0,0 @@ ---- -name: fact-profile-settings -description: Analyze environment-specific profiles and configuration ---- - -# Profile Settings Analysis - -## Purpose -Identify how the application manages environment-specific configurations (Development, Test, Staging, Production) through profiles, property files, or environment-based settings. This helps understand configuration management complexity and deployment requirements. - -## Target Files/Locations -- **Spring profiles**: **/application-{profile}.{properties,yml}, **/application.{properties,yml} -- **Maven profiles**: **/pom.xml (`<profiles>` section) -- **Gradle profiles**: **/build.gradle, **/build.gradle.kts (buildTypes, productFlavors) -- **Environment configs**: **/config/**, **/environments/**, **/profiles/ -- **Java properties**: **/{env}/*.properties, **/*-{env}.properties -- **.NET configs**: **/appsettings.{Environment}.json, **/web.{config}.config -- **Docker/K8s**: **/docker-compose.{env}.yml, **/k8s/**/*-{env}.yaml -- **CI/CD**: **/.github/workflows/, **/.gitlab-ci.yml, **/Jenkinsfile - -## Example Patterns to Search -- **Spring profiles**: `spring.profiles.active`, `@Profile("dev")`, `application-dev.properties` -- **Maven profiles**: `<profile><id>development</id>`, `<activeByDefault>`, `<activation>` -- **Environment variables**: `${ENV:prod}`, `#{environment}`, `process.env.NODE_ENV` -- **Profile-specific beans**: `@Profile("production")`, `@ConditionalOnProfile` -- **Config file names**: dev, test, staging, uat, prod, production, development - -## Analysis Steps - -### 1. Search for Spring Profile Configuration Files -``` -Use Glob to find Spring profile-specific configs: -- **/application-dev.{properties,yml,yaml} -- **/application-test.{properties,yml,yaml} -- **/application-staging.{properties,yml,yaml} -- **/application-prod.{properties,yml,yaml} -- **/application-production.{properties,yml,yaml} -- **/application-uat.{properties,yml,yaml} -- **/application-local.{properties,yml,yaml} - -Use Read to examine application.properties/yml: -- Check for spring.profiles.active setting -- Look for profile-specific property groups (--- separator in YAML) -- Identify default profile configuration - -Count and categorize profiles found -``` - -### 2. Search for @Profile Annotations in Java Code -``` -Use Grep to find profile usage in code: -Pattern: "@Profile\\(|@ConditionalOnProfile|spring\\.profiles\\." -Files: **/*.java -Context: -B 1 -A 2 - -Analyze: -- Which beans/components are profile-specific -- Profile names used in annotations -- Conditional logic based on profiles -``` - -### 3. Analyze Maven Profile Configuration -``` -Use Glob to find Maven build file: -- **/pom.xml - -Use Read or Grep to search for: -- <profiles> section -- <profile><id> elements (dev, test, prod, etc.) -- <activeByDefault> settings -- <activation> conditions (property, JDK, OS) -- Profile-specific properties, dependencies, plugins - -Example patterns to search: -<profile> - <id>development</id> - <activation> - <activeByDefault>true</activeByDefault> - </activation> -</profile> -``` - -### 4. Check Gradle Build Profiles -``` -Use Glob to find Gradle files: -- **/build.gradle -- **/build.gradle.kts - -Use Read to check for: -- buildTypes { debug, release } -- productFlavors { dev, staging, prod } -- Environment-specific configurations -- ext { profile = project.hasProperty('env') ? env : 'dev' } -``` - -### 5. Search for .NET Environment Configurations -``` -Use Glob to find .NET configs: -- **/appsettings.Development.json -- **/appsettings.Staging.json -- **/appsettings.Production.json -- **/web.Development.config -- **/web.Release.config - -Use Grep in .csproj files: -Pattern: "<Environments>|ASPNETCORE_ENVIRONMENT|IHostEnvironment" -``` - -### 6. Check for Environment-Specific Directories -``` -Use Glob to find environment directories: -- **/config/dev/** -- **/config/prod/** -- **/environments/development/** -- **/profiles/** - -Use Bash to list directory structure: -find . -type d -name "dev" -o -name "test" -o -name "prod" -o -name "staging" | head -20 -``` - -### 7. Analyze Docker/K8s Environment Configurations -``` -Use Glob to find container configs: -- **/docker-compose.dev.yml -- **/docker-compose.prod.yml -- **/k8s/dev/**/*.yaml -- **/k8s/production/**/*.yaml -- **/Dockerfile.dev, **/Dockerfile.prod - -Use Grep to find environment variables: -Pattern: "ENV|ENVIRONMENT|PROFILE" -Files: **/Dockerfile, **/docker-compose*.yml -``` - -### 8. Search for CI/CD Environment Configurations -``` -Use Glob to find CI/CD files: -- **/.github/workflows/**/*.yml -- **/.gitlab-ci.yml -- **/Jenkinsfile -- **/azure-pipelines.yml - -Use Read to check for: -- Environment-based job definitions -- Deployment stages (dev, test, prod) -- Environment-specific variables -``` - -### 9. Count and Categorize Profiles -``` -Aggregate all findings: -- List all profile names found -- Count config files per profile -- Identify primary profiles (dev, test, prod) -- Note any custom or unusual profile names -- Check for profile activation logic -``` - -## Confidence Determination - -### High Confidence Criteria -Clear and comprehensive profile configuration: -- ✅ Multiple profile-specific config files found (dev, test, prod) -- ✅ Profile activation mechanism clearly defined -- ✅ Profile-specific beans or components in code -- ✅ Build tool profiles configured (Maven/Gradle) -- ✅ Consistent naming across different config types -- ✅ Environment-specific properties well documented - -**Examples**: -- "Application uses 4 Spring profiles (dev, test, staging, prod) with separate application-{profile}.yml files and @Profile annotations in 12 configuration classes" -- "Maven build configured with 3 profiles (development, testing, production) using different database connections and feature flags per environment" -- ".NET application with appsettings.{Environment}.json for Development, Staging, and Production with ASPNETCORE_ENVIRONMENT detection" - -### Medium Confidence Criteria -Partial profile configuration or unclear structure: -- ⚠️ Some profile files found but incomplete coverage -- ⚠️ Profiles defined but no clear activation mechanism -- ⚠️ Mixed approaches (some Spring, some environment variables) -- ⚠️ Profile names inconsistent across config types -- ⚠️ Only build profiles without runtime profiles (or vice versa) - -**Examples**: -- "Spring profiles for dev and prod found, but test/staging configs missing" -- "Maven profiles defined but no corresponding Spring profile configs" -- "Environment-based configuration exists but profile names vary (dev vs development, prod vs production)" - -### Low Confidence Criteria -Weak or minimal profile evidence: -- ⚠️ Only default configuration, no environment variants -- ⚠️ Profile files exist but appear unused or outdated -- ⚠️ Single-environment application (dev only) -- ⚠️ Hardcoded values instead of profile-based configs -- ⚠️ Profile references in comments but no implementation - -**Examples**: -- "Only application.properties found, no profile-specific configs" -- "Profile files exist but timestamps suggest not used in 2+ years" -- "Comments mention dev/prod configs but actual implementation uses hardcoded values" - -### Not Applicable Criteria -When profile analysis doesn't apply: -- ❌ Simple utility/library with no environment differences -- ❌ Single-purpose tool with no configuration needs -- ❌ Prototype or demo application -- ❌ Different platform with different config approach -- ❌ Configuration managed entirely external (ConfigMap, external config server) - -**Examples**: -- "Command-line utility with no environment-specific behavior" -- "Demo application with hardcoded sample data" -- "Library project with no deployment configuration" - -## Output Format - -**CRITICAL**: Use the `write_assessment_result` tool (not just output JSON text). - -```json -{ - "input_name": "Profile Settings", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Clear 1-2 sentence summary of profile configuration}", - "confidence": "high|medium|low", - "evidence": [ - "{Number and names of profiles identified}", - "{Profile activation mechanism}", - "{Config files per profile}", - "{Code using profile-specific logic}", - "{Build tool profile configuration}" - ], - "values": [ - "{Profile names: dev, test, staging, prod, etc.}", - "{Config file types: properties, yml, json}", - "{Activation method: spring.profiles.active, Maven, env vars}", - "{Number of profile-specific files}", - "{Profile-annotated components count}" - ] - }, - "execution_time_seconds": {elapsed_time}, - "timestamp": "{ISO 8601 timestamp}" -} -``` - -**Finding Examples**: -- ✅ Good: "Application uses comprehensive Spring profile system with 4 environments (dev, test, staging, prod) managed through application-{profile}.yml files and 15 @Profile-annotated configuration classes" -- ✅ Good: ".NET Core application with environment-based configuration using appsettings.{Environment}.json for Development, Staging, and Production environments activated via ASPNETCORE_ENVIRONMENT" -- ✅ Good: "Maven multi-profile build with 3 profiles (development, testing, production) controlling database connections, logging levels, and feature toggles" -- ✅ Good: "No environment profiles detected - single configuration approach suitable for utility application" -- ❌ Bad: "Profiles exist" -- ❌ Bad: "Environment configuration found" - -**Evidence Examples**: -- ✅ Good: "application-dev.yml, application-test.yml, application-staging.yml, application-prod.yml in src/main/resources/" -- ✅ Good: "15 configuration classes with @Profile annotations: @Profile('dev') in DevDatabaseConfig.java, @Profile('prod') in ProdSecurityConfig.java" -- ✅ Good: "Maven pom.xml defines 3 profiles with <id>development</id>, <id>testing</id>, <id>production</id> at lines 120-185" -- ✅ Good: "spring.profiles.active=dev in application.properties, overridable via SPRING_PROFILES_ACTIVE environment variable" -- ❌ Bad: "Configuration files found" -- ❌ Bad: "Profiles detected in code" - -## Error Handling - -### 1. No Profiles Found -- Verify it's not a single-environment application by design -- Check for alternative configuration mechanisms (external config, env vars only) -- Report finding: "No profile-based configuration detected - single configuration model" -- Set confidence to high if thorough search confirms absence - -### 2. Inconsistent Profile Names -- Report all variations found (dev vs development, prod vs production) -- Note potential misconfiguration risks -- Set confidence to medium -- Recommend standardization in evidence notes - -### 3. Partial Profile Implementation -- List which profiles are complete vs incomplete -- Note missing files (e.g., dev and prod exist but no test) -- Set confidence to medium with caveats - -### 4. Mixed Configuration Approaches -- Document each approach found (Spring profiles, Maven profiles, Docker configs) -- Clarify how they interact or if they're independent -- This is common and valid - report comprehensively - -### 5. Tool Failures -- If Glob returns too many results, refine patterns -- If Read fails on large files, use Grep for specific patterns -- After 3 retries, report partial results with notes - -## Example Complete Analysis - -**Scenario**: Spring Boot microservice with comprehensive profile setup - -**Steps Executed**: -1. Glob for Spring configs: Found application-{dev,test,staging,prod}.yml (4 files) -2. Read application.yml: Found spring.profiles.active: dev -3. Grep for @Profile: Found 18 matches in 15 configuration classes -4. Read pom.xml: No Maven profiles (uses Spring profiles only) -5. Checked Docker: Found docker-compose.dev.yml and docker-compose.prod.yml -6. Glob for K8s: Found k8s/dev/ and k8s/prod/ directories with manifests - -**Result**: -```json -{ - "input_name": "Profile Settings", - "analysis_method": "LLM", - "status": "success", - "result": { - "finding": "Application implements comprehensive 4-environment profile system (dev, test, staging, prod) using Spring profiles with separate YAML configs, 15 profile-annotated configuration classes, and environment-specific Docker/Kubernetes manifests", - "confidence": "high", - "evidence": [ - "4 Spring profile configs: application-dev.yml, application-test.yml, application-staging.yml, application-prod.yml in src/main/resources/", - "application.yml sets spring.profiles.active: dev as default, overridable via SPRING_PROFILES_ACTIVE env var", - "15 configuration classes use @Profile annotations: DevDatabaseConfig, ProdSecurityConfig, TestEmailConfig, etc.", - "docker-compose.dev.yml and docker-compose.prod.yml set different SPRING_PROFILES_ACTIVE values", - "Kubernetes manifests in k8s/dev/ and k8s/prod/ directories with environment-specific ConfigMaps", - "Profile-specific settings: database URLs, Redis hosts, feature flags, logging levels" - ], - "values": [ - "4 environments: dev, test, staging, prod", - "Spring profile activation via application.yml and environment variables", - "15 @Profile-annotated configuration classes", - "4 profile-specific YAML files (150-200 lines each)", - "Docker Compose configs for dev and prod", - "Kubernetes ConfigMaps per environment" - ] - }, - "execution_time_seconds": 35.2, - "timestamp": "2026-02-28T10:26:14Z" -} -``` diff --git a/.github/skills/fact-resource-limits/SKILL.md b/.github/skills/fact-resource-limits/SKILL.md deleted file mode 100644 index ec0d4b3b8..000000000 --- a/.github/skills/fact-resource-limits/SKILL.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -name: fact-resource-limits -description: Identify CPU/Memory resource limits for containers ---- - -# Resource Limits Analysis - -## Purpose -Identify CPU and memory resource constraints configured for containers through compose files or Kubernetes manifests. - -## Target Files/Locations -- **/docker-compose*.yml (deploy.resources) -- **/k8s/**/*.yaml (resources.requests, resources.limits) -- **/Dockerfile (no resource limits, but checked for context) - -## Example Patterns -- `memory: 2g`, `cpus: '1.5'` -- `limits: memory: "2Gi", cpu: "1000m"` -- `requests: memory: "512Mi", cpu: "250m"` - -## Analysis Steps - -### 1. Check docker-compose Resources -``` -Use Read: **/docker-compose*.yml -Look for deploy.resources section: - deploy: - resources: - limits: - cpus: '2.0' - memory: 2G - reservations: - cpus: '0.5' - memory: 512M -``` - -### 2. Analyze Kubernetes Resources -``` -Use Grep: "resources:|limits:|requests:|memory:|cpu:" -Files: **/k8s/**/*.yaml -Context: -B 3 -A 3 - -Parse format: - resources: - limits: - memory: "2Gi" - cpu: "1000m" - requests: - memory: "512Mi" - cpu: "250m" -``` - -### 3. Check for Resource Quotas -``` -Use Grep: "kind: ResourceQuota" -Files: **/k8s/**/*.yaml -Namespace-level resource constraints -``` - -## Confidence Determination - -### High Confidence -- ✅ Resource limits explicitly configured -- ✅ Both limits and requests defined -- **Example**: "Container limits: 2Gi memory, 1000m CPU; requests: 512Mi memory, 250m CPU" - -### Medium Confidence -- ⚠️ Only limits or only requests defined -- **Example**: "Memory limit 2GB configured, CPU unspecified" - -### Low Confidence -- ⚠️ No explicit resource configuration -- **Example**: "No resource limits configured, uses node defaults" - -### Not Applicable -- ❌ No container orchestration -- **Example**: "Direct Docker run, no resource management" - -## Output Format - -```json -{ - "input_name": "Resource Limits", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Resources summary}", - "confidence": "high|medium|low", - "evidence": [ - "{docker-compose deploy.resources}", - "{K8s limits/requests}", - "{ResourceQuota if present}" - ], - "values": [ - "{Memory limits and requests}", - "{CPU limits and requests}", - "{Units: Gi, Mi, millicores}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-runtime-environment/SKILL.md b/.github/skills/fact-runtime-environment/SKILL.md deleted file mode 100644 index 70d33be50..000000000 --- a/.github/skills/fact-runtime-environment/SKILL.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -name: fact-runtime-environment -description: Identify application runtime (Node.js, Python, Java, Go, .NET) in container ---- - -# Runtime Environment Analysis - -## Purpose -Detect the application runtime/platform used in containerized applications (Node.js, Python, Java, Go, .NET, Ruby, PHP, etc.). - -## Target Files/Locations -- **/Dockerfile, **/Containerfile (FROM base image) -- **/package.json, **/package-lock.json (Node.js) -- **/pom.xml, **/build.gradle (Java) -- **/*.csproj, **/*.sln (.NET) -- **/requirements.txt, **/Pipfile, **/pyproject.toml (Python) -- **/go.mod (Go) -- **/Gemfile (Ruby) -- **/composer.json (PHP) - -## Example Patterns -- `FROM node:16`, `FROM python:3.9`, `FROM openjdk:11`, `FROM mcr.microsoft.com/dotnet/runtime:6.0` -- `RUN npm install`, `RUN pip install`, `RUN go build`, `RUN dotnet publish` - -## Analysis Steps - -### 1. Analyze Base Image -``` -Use Grep: "FROM\\s+(node|python|openjdk|golang|mcr.microsoft.com/dotnet|ruby|php)" -Files: **/Dockerfile -Extract runtime from base image name -``` - -### 2. Check Build/Install Commands -``` -Use Grep: "npm|pip|maven|gradle|dotnet|go build|bundle|composer" -Files: **/Dockerfile -Context: -B 1 -A 2 -``` - -### 3. Identify Dependency Files -``` -Use Glob to find: -- package.json, package-lock.json (Node.js) -- requirements.txt, Pipfile (Python) -- pom.xml, build.gradle (Java) -- *.csproj, *.sln (.NET) -- go.mod, go.sum (Go) -- Gemfile (Ruby) -- composer.json (PHP) -``` - -### 4. Check Version from Base Image -``` -Parse FROM instruction: -- node:16-alpine → Node.js 16 -- python:3.9-slim → Python 3.9 -- openjdk:11-jre → Java 11 -- mcr.microsoft.com/dotnet/runtime:6.0 → .NET 6 -``` - -## Confidence Determination - -### High Confidence -- ✅ Runtime base image clearly specified -- ✅ Build commands match runtime -- ✅ Dependency files present -- **Example**: "Node.js 16 runtime based on FROM node:16-alpine and package.json" - -### Medium Confidence -- ⚠️ Generic base with runtime installed -- ⚠️ Multi-language project -- **Example**: "Java application, version unclear (uses maven but base is Ubuntu)" - -### Low Confidence -- ⚠️ No clear runtime indicators -- **Example**: "Compiled binary, runtime unclear" - -### Not Applicable -- ❌ No container -- **Example**: "No Dockerfile found" - -## Output Format - -```json -{ - "input_name": "Runtime Environment", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Runtime identified}", - "confidence": "high|medium|low", - "evidence": [ - "{Base image}", - "{Build commands}", - "{Dependency files}" - ], - "values": [ - "{Runtime: Node.js, Python, Java, .NET, Go, etc.}", - "{Version}", - "{Variant: alpine, slim, etc.}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-security-implementation/SKILL.md b/.github/skills/fact-security-implementation/SKILL.md deleted file mode 100644 index 7f118bd52..000000000 --- a/.github/skills/fact-security-implementation/SKILL.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -name: fact-security-implementation -description: Analyze security measures (HTTPS, Encryption, Token-based auth) ---- - -# Security Implementation Analysis - -## Purpose -Identify security measures implemented in the application including HTTPS, authentication, authorization, encryption, and security headers. - -## Target Files/Locations -- **/application.{properties,yml} (SSL, security configs) -- **/*.java, **/*.cs (security filters, auth) -- **/pom.xml, **/build.gradle, **/*.csproj (security dependencies) -- **/Dockerfile (SSL certificates) -- **/k8s/**/*.yaml (TLS secrets) - -## Example Patterns -- **HTTPS/TLS**: server.ssl.*, SSLContext, TLS certificates -- **Authentication**: JWT, OAuth2, Basic Auth, API keys -- **Authorization**: @PreAuthorize, [Authorize], RBAC -- **Encryption**: AES, RSA, EncryptionService -- **Security Headers**: CORS, CSP, HSTS, X-Frame-Options - -## Analysis Steps - -### 1. Check for HTTPS/TLS Configuration -``` -Use Grep: "server\\.ssl|https://|TLS|SSLContext|keystore" -Files: **/application.{properties,yml}, **/*.java, **/*.cs -Context: -B 2 -A 2 - -Check for: -- server.ssl.key-store -- SSLContext.getInstance("TLS") -- HTTPS redirect configurations -``` - -### 2. Check Authentication Mechanisms -``` -Use Grep: "JWT|OAuth2|@EnableWebSecurity|JwtToken|Bearer|Basic Auth" -Files: **/*.{java,cs,js} -Context: -B 3 -A 3 - -Dependencies: -- spring-boot-starter-security -- Microsoft.AspNetCore.Authentication.JwtBearer -- passport (Node.js) - -Look for: -- @EnableWebSecurity, @PreAuthorize (Spring) -- [Authorize], UseAuthentication() (.NET) -- JWT token generation/validation -``` - -### 3. Check for Authorization -``` -Use Grep: "@PreAuthorize|@Secured|\\[Authorize\\]|hasRole|hasAuthority" -Files: **/*.{java,cs} - -RBAC indicators: -- Role definitions -- Permission checks -- Access control lists -``` - -### 4. Check for Encryption -``` -Use Grep: "AES|RSA|encrypt|decrypt|Cipher|CryptoService" -Files: **/*.{java,cs,py,js} - -Look for: -- Data encryption at rest -- Encryption services -- Key management (KMS, KeyVault) -``` - -### 5. Check for Security Headers -``` -Use Grep: "CORS|Content-Security-Policy|X-Frame-Options|HSTS|Strict-Transport-Security" -Files: **/*.{java,cs,js}, **/application.{properties,yml} - -Spring: WebMvcConfigurer.addCorsMappings -.NET: app.UseCors(), app.UseHsts() -``` - -### 6. Check Dependency Scanning -``` -Look for security scanning: -- Dependabot config -- Snyk, OWASP Dependency Check -- npm audit, dotnet list package --vulnerable -``` - -## Confidence Determination - -### High Confidence -- ✅ Multiple security measures implemented -- ✅ HTTPS + authentication + authorization configured -- **Example**: "HTTPS with TLS 1.3, JWT authentication, role-based authorization, AES encryption for sensitive data" - -### Medium Confidence -- ⚠️ Some security features but incomplete -- **Example**: "Basic authentication configured, HTTPS unclear" - -### Low Confidence -- ⚠️ Security dependencies present but implementation unclear -- **Example**: "Security framework dependency but no explicit configuration found" - -### Not Applicable -- ❌ Internal tool with no security requirements -- **Example**: "Development utility, no security implementation needed" - -## Output Format - -```json -{ - "input_name": "Security Implementation", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Security summary}", - "confidence": "high|medium|low", - "evidence": [ - "{HTTPS/TLS configuration}", - "{Authentication mechanism}", - "{Authorization approach}", - "{Encryption usage}", - "{Security headers}" - ], - "values": [ - "{Transport: HTTPS, TLS 1.2/1.3}", - "{Auth: JWT, OAuth2, Basic}", - "{Authorization: RBAC, attribute-based}", - "{Encryption: AES-256, RSA}", - "{Headers: CORS, CSP, HSTS}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-service-definition/SKILL.md b/.github/skills/fact-service-definition/SKILL.md deleted file mode 100644 index ac3287c5c..000000000 --- a/.github/skills/fact-service-definition/SKILL.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -name: fact-service-definition -description: Analyze service definition files (docker-compose.yml, K8s manifests) ---- - -# Service Definition Analysis - -## Purpose -Catalog and analyze service definition files that describe how the application is deployed and orchestrated. - -## Target Files/Locations -- **/docker-compose*.yml, **/docker-compose.*.yml -- **/k8s/**/*.yaml, **/manifests/**/*.yaml -- **/helm/**/templates/*.yaml - -## Example Patterns -- Docker Compose services with image, ports, volumes, environment -- Kubernetes Deployments, Services, ConfigMaps, Secrets -- Helm charts with templated manifests - -## Analysis Steps - -### 1. Catalog Docker Compose Files -``` -Use Glob: **/docker-compose*.yml -For each file: -- Count services defined -- Check for extends or depends_on -- Note environment variants (dev, prod) -``` - -### 2. Catalog Kubernetes Manifests -``` -Use Glob: **/k8s/**/*.yaml, **/manifests/**/*.yaml -Use Grep: "kind: Deployment|kind: Service|kind: ConfigMap|kind: Secret" -Files: **/*.yaml -Count by kind - -Group by resource type: -- Workloads: Deployment, StatefulSet, DaemonSet, Job -- Services: Service, Ingress -- Config: ConfigMap, Secret -- Storage: PersistentVolumeClaim -``` - -### 3. Check for Helm Charts -``` -Use Glob: **/Chart.yaml, **/values.yaml -If found: Helm is used -Count template files -``` - -### 4. Analyze Service Complexity -``` -For Compose: -- Single service vs multi-service -- Service dependencies (depends_on) - -For K8s: -- Microservices count -- Service mesh indicators -- Namespace organization -``` - -## Confidence Determination - -### High Confidence -- ✅ Service files present and parseable -- ✅ Clear service structure -- **Example**: "3-service docker-compose with web, api, database services fully configured" - -### Medium Confidence -- ⚠️ Some service files found but structure unclear -- **Example**: "K8s manifests present but relationships between services unclear" - -### Low Confidence -- ⚠️ Service definitions incomplete -- **Example**: "Partial service definitions, missing critical resources" - -### Not Applicable -- ❌ No service definitions -- **Example**: "Single container, no orchestration files" - -## Output Format - -```json -{ - "input_name": "Service Definition", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Service definitions summary}", - "confidence": "high|medium|low", - "evidence": [ - "{File types and counts}", - "{Service/resource counts}", - "{Orchestration approach}" - ], - "values": [ - "{Tool: Compose, K8s, Helm}", - "{Service count}", - "{Resource types and counts}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-servlet-container/SKILL.md b/.github/skills/fact-servlet-container/SKILL.md deleted file mode 100644 index cf206f209..000000000 --- a/.github/skills/fact-servlet-container/SKILL.md +++ /dev/null @@ -1,310 +0,0 @@ ---- -name: fact-servlet-container -description: Identify servlet container requirements and version ---- - -# Servlet Container Analysis - -## Purpose -Identify the servlet container (application server) requirements for the application, including Servlet API version, container-specific features, and deployment model. This helps determine migration compatibility and modernization path. - -## Target Files/Locations -- **Deployment descriptors**: **/WEB-INF/web.xml, **/META-INF/weblogic.xml, **/META-INF/jboss-web.xml -- **Build files**: **/pom.xml, **/build.gradle, **/build.gradle.kts -- **Configuration**: **/application.properties, **/application.yml -- **Server configs**: **/server.xml, **/context.xml (Tomcat), **/standalone.xml (JBoss/WildFly) -- **Java source**: **/*Servlet.java, **/*Filter.java, **/*Listener.java - -## Example Patterns to Search -- **Servlet API**: `javax.servlet`, `jakarta.servlet`, `ServletContext`, `HttpServlet` -- **Servlet version**: `<web-app version="3.1"`, `version="4.0"`, `version="5.0"` -- **Container-specific**: `weblogic`, `jboss`, `wildfly`, `tomcat`, `websphere`, `glassfish` -- **Server dependencies**: `provided` scope for servlet-api, tomcat-embed, wildfly-swarm -- **Annotations**: `@WebServlet`, `@WebFilter`, `@WebListener`, `@MultipartConfig` - -## Analysis Steps - -### 1. Analyze web.xml Deployment Descriptor -``` -Use Glob to find web.xml: -- **/WEB-INF/web.xml -- **/META-INF/web.xml - -If found, use Read to examine: -- <web-app> version attribute (2.3, 2.4, 2.5, 3.0, 3.1, 4.0, 5.0, 6.0) -- XSD/DTD namespace for Servlet version - - Java EE 5 (Servlet 2.5): java.sun.com/xml/ns/javaee - - Java EE 6-7 (Servlet 3.0-3.1): xmlns.jcp.org/xml/ns/javaee - - Jakarta EE 8+ (Servlet 4.0+): jakarta.ee/xml/ns/jakartaee -- Servlet definitions and mappings -- Filter configurations -- Container-specific elements -``` - -### 2. Check Build Dependencies for Servlet API -``` -Use Glob to find build files: -- **/pom.xml -- **/build.gradle -- **/build.gradle.kts - -Use Read or Grep to search for: -Maven (pom.xml): -- <artifactId>servlet-api</artifactId> -- <artifactId>javax.servlet-api</artifactId> -- <artifactId>jakarta.servlet-api</artifactId> -- <version>3.1.0</version>, <version>4.0.0</version>, <version>5.0.0</version> -- <scope>provided</scope> (indicates external container) - -Gradle (build.gradle): -- providedCompile 'javax.servlet:javax.servlet-api:3.1.0' -- compileOnly 'jakarta.servlet:jakarta.servlet-api:5.0.0' - -Check for embedded container dependencies: -- spring-boot-starter-web (embedded Tomcat) -- tomcat-embed-core -- jetty-server -- undertow-core -``` - -### 3. Search for Container-Specific Configuration -``` -Use Glob to find container configs: -- **/META-INF/weblogic.xml (Oracle WebLogic) -- **/META-INF/jboss-web.xml (JBoss/WildFly) -- **/META-INF/glassfish-web.xml (GlassFish) -- **/META-INF/geronimo-web.xml (Apache Geronimo) -- **/WEB-INF/ibm-web-ext.xml (IBM WebSphere) - -If found, this indicates container-specific features/requirements -``` - -### 4. Search for Servlet/Filter Implementations -``` -Use Grep to find servlet code: -Pattern: "extends\\s+HttpServlet|implements\\s+Servlet|implements\\s+Filter" -Files: **/*.java -Context: -B 2 -A 5 - -Use Grep to find servlet annotations: -Pattern: "@WebServlet|@WebFilter|@WebListener|@MultipartConfig" -Files: **/*.java -Context: -B 1 -A 3 - -Analyze: -- Count of servlets/filters -- Use of Servlet 3.0+ annotations vs web.xml -- Async servlet support (@WebServlet(asyncSupported=true)) -``` - -### 5. Check for Spring Boot Embedded Container -``` -Use Grep in pom.xml or build.gradle: -Pattern: "spring-boot-starter-web|spring-boot-starter-tomcat|spring-boot-starter-jetty|spring-boot-starter-undertow" - -If found: -- This is embedded container (not external) -- Check application.properties for server configuration - - server.port - - server.servlet.context-path - - server.tomcat.* (if Tomcat) - -Use Glob for Spring Boot config: -- **/application.properties -- **/application.yml -``` - -### 6. Identify Container Version from Dependencies -``` -Parse Maven/Gradle files for exact versions: -- javax.servlet-api: 2.5, 3.0, 3.1 (Java EE) -- jakarta.servlet-api: 4.0 (Jakarta EE 8), 5.0 (Jakarta EE 9), 6.0 (Jakarta EE 10) - -Match to Servlet API specifications: -- Servlet 2.5 = Java EE 5 (Tomcat 6, JBoss 5) -- Servlet 3.0 = Java EE 6 (Tomcat 7, JBoss 7, GlassFish 3) -- Servlet 3.1 = Java EE 7 (Tomcat 8, WildFly 8-10, WebLogic 12c) -- Servlet 4.0 = Java EE 8 / Jakarta EE 8 (Tomcat 9, WildFly 14+) -- Servlet 5.0 = Jakarta EE 9 (Tomcat 10, WildFly 22+) -- Servlet 6.0 = Jakarta EE 10 (Tomcat 10.1+, WildFly 27+) -``` - -### 7. Check for Container-Specific Features -``` -Use Grep to search for container-specific APIs: -- WebLogic: "weblogic\\..*|WorkManager|JMS" -- JBoss/WildFly: "org\\.jboss|org\\.wildfly|EJB" -- WebSphere: "com\\.ibm\\.websphere" -- Tomcat: "org\\.apache\\.catalina|org\\.apache\\.tomcat" - -These indicate tight coupling to specific containers -``` - -## Confidence Determination - -### High Confidence Criteria -Clear and definitive evidence of servlet container requirements: -- ✅ web.xml present with explicit version attribute -- ✅ Servlet API dependency with specific version in build file -- ✅ Container-specific configuration files found -- ✅ Servlet/Filter implementations found in code -- ✅ Clear deployment model (embedded vs external container) - -**Examples**: -- "Web application requires Servlet 3.1 API (Java EE 7) based on web.xml version='3.1' and javax.servlet-api:3.1.0 dependency" -- "Spring Boot application with embedded Tomcat 9.0.65 (Servlet 4.0) from spring-boot-starter-web:2.7.3" -- "WebLogic-specific deployment with weblogic.xml and WorkManager configuration - requires Oracle WebLogic 12c+" - -### Medium Confidence Criteria -Partial evidence or inferred information: -- ⚠️ Servlet API dependency present but no web.xml (annotation-based config) -- ⚠️ Container type inferred from Spring Boot starter but version unclear -- ⚠️ Servlet code found but no explicit version indicators -- ⚠️ Legacy web.xml without version attribute -- ⚠️ Mixed signals (multiple container dependencies) - -**Examples**: -- "Servlet 3.0+ usage inferred from @WebServlet annotations, but no explicit version in dependencies" -- "Spring Boot with default embedded container (likely Tomcat) but version not specified" -- "Servlet implementations found but build file doesn't declare servlet-api dependency explicitly" - -### Low Confidence Criteria -Weak or ambiguous evidence: -- ⚠️ No web.xml or servlet annotations found -- ⚠️ Servlet API in transitive dependencies only -- ⚠️ Container type unclear or multiple possibilities -- ⚠️ Test code has servlet dependencies but main code doesn't -- ⚠️ Comments reference servlets but no actual implementation - -**Examples**: -- "Servlet API appears in dependency tree but no servlet code found" -- "No clear servlet container indicators - may be non-web application" -- "Test dependencies include servlet-api but unclear if production code uses it" - -### Not Applicable Criteria -When servlet container analysis doesn't apply: -- ❌ Non-web application (standalone, batch, CLI tool) -- ❌ REST API using JAX-RS without servlets (Jersey, RESTEasy standalone) -- ❌ Pure reactive application (Spring WebFlux on Netty) -- ❌ Different platform (.NET, Node.js, Python) -- ❌ Library/framework project (no executable component) - -**Examples**: -- "Spring Boot application using WebFlux and Netty - no servlet container required" -- "Standalone Java application with no web components" -- "Node.js Express application - servlet analysis not applicable" - -## Output Format - -**CRITICAL**: Use the `write_assessment_result` tool (not just output JSON text). - -```json -{ - "input_name": "Servlet Container", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Clear 1-2 sentence summary of servlet container requirements}", - "confidence": "high|medium|low", - "evidence": [ - "{web.xml version or absence}", - "{Servlet API dependency with version}", - "{Container-specific files or features}", - "{Deployment model (embedded/external)}", - "{Container type identified}" - ], - "values": [ - "{Servlet API version (e.g., 3.1, 4.0, 5.0)}", - "{Java EE / Jakarta EE version}", - "{Container type and version (if known)}", - "{Number of servlets/filters}", - "{Container-specific features used}" - ] - }, - "execution_time_seconds": {elapsed_time}, - "timestamp": "{ISO 8601 timestamp}" -} -``` - -**Finding Examples**: -- ✅ Good: "Application requires Servlet 3.1 container (Java EE 7) deployed to external WebLogic 12c server with WebLogic-specific WorkManager configuration" -- ✅ Good: "Spring Boot application with embedded Tomcat 9.0.65 (Servlet 4.0 / Jakarta EE 8) managed by spring-boot-starter-web" -- ✅ Good: "Modern Jakarta EE 9 application requiring Servlet 5.0 container (WildFly 22+, Tomcat 10+) with 8 servlets and 5 filters" -- ✅ Good: "Non-web application - no servlet container required (standalone Spring Boot with WebFlux)" -- ❌ Bad: "Uses servlets" -- ❌ Bad: "Container required" - -**Evidence Examples**: -- ✅ Good: "web.xml at WEB-INF/web.xml declares version='3.1' with Java EE 7 namespace" -- ✅ Good: "javax.servlet-api:3.1.0 with <scope>provided</scope> in pom.xml" -- ✅ Good: "weblogic.xml found with WorkManager 'default' configuration" -- ✅ Good: "spring-boot-starter-web:2.7.3 includes tomcat-embed-core:9.0.65" -- ✅ Good: "5 servlets using @WebServlet annotations (Servlet 3.0+ feature)" -- ❌ Bad: "web.xml exists" -- ❌ Bad: "Container dependency found" - -## Error Handling - -### 1. No Servlet Evidence Found -- Check if this is a web application at all -- Search for alternative web frameworks (JAX-RS, Spring WebFlux) -- Report as "not_applicable" if truly not a web app -- If web app with no servlet evidence: low confidence "Unable to determine container requirements" - -### 2. Mixed Servlet API Versions -- Report all versions found with locations -- Set confidence to medium -- Note potential migration status: "Project in transition from javax.servlet to jakarta.servlet" - -### 3. Embedded vs External Container Confusion -- Check for spring-boot packaging (jar vs war) -- Spring Boot jar = embedded, war = external -- Report both possibilities if unclear - -### 4. Tool Failures -- If Grep fails on large pom.xml, use Read with offset/limit -- If XML parsing issues, try grep for version patterns -- After 3 retries, report with caveats - -## Example Complete Analysis - -**Scenario**: Traditional Java EE web application on WebLogic - -**Steps Executed**: -1. Glob for web.xml: Found WEB-INF/web.xml -2. Read web.xml: version="3.1", Java EE 7 namespace -3. Read pom.xml: javax.servlet-api:3.1.0 with provided scope -4. Glob for container configs: Found META-INF/weblogic.xml -5. Grep for servlets: Found 8 servlet classes, 5 filters -6. Grep for container features: Found WorkManager references - -**Result**: -```json -{ - "input_name": "Servlet Container", - "analysis_method": "LLM", - "status": "success", - "result": { - "finding": "Application requires Servlet 3.1 (Java EE 7) container, specifically Oracle WebLogic 12c, with WebLogic-specific features including WorkManager and JMS integration", - "confidence": "high", - "evidence": [ - "web.xml at WEB-INF/web.xml with version='3.1' and Java EE 7 namespace (xmlns.jcp.org/xml/ns/javaee)", - "javax.servlet-api:3.1.0 dependency with <scope>provided</scope> in pom.xml", - "weblogic.xml at META-INF/weblogic.xml with WorkManager configuration", - "8 servlet implementations: AuthServlet, MainServlet, UploadServlet, etc.", - "5 filter implementations including CharacterEncodingFilter and AuthenticationFilter", - "WebLogic-specific API usage: weblogic.jms.* and weblogic.servlet.*" - ], - "values": [ - "Servlet API 3.1", - "Java EE 7", - "Oracle WebLogic 12c (minimum)", - "8 servlets, 5 filters", - "WebLogic WorkManager 'default-workmanager'", - "WAR packaging for external deployment" - ] - }, - "execution_time_seconds": 28.4, - "timestamp": "2026-02-28T10:22:38Z" -} -``` diff --git a/.github/skills/fact-startup-instrumentation/SKILL.md b/.github/skills/fact-startup-instrumentation/SKILL.md deleted file mode 100644 index 044800ba3..000000000 --- a/.github/skills/fact-startup-instrumentation/SKILL.md +++ /dev/null @@ -1,371 +0,0 @@ ---- -name: fact-startup-instrumentation -description: Analyze startup instrumentation (logging, telemetry, AOP) ---- - -# Startup Instrumentation Analysis - -## Purpose -Detect and analyze logging frameworks, telemetry/APM tools, and aspect-oriented programming (AOP) components initialized at application startup. - -## Analysis Strategy - -This SKILL searches for configuration files, startup code, and dependency declarations to identify instrumentation frameworks. - -## Analysis Steps - -### 1. Logging Framework Detection - -**Search for Logging Configuration Files:** -```bash -# Use Glob to find config files -Glob patterns: -- **/logback.xml, **/logback-spring.xml -- **/log4j2.xml, **/log4j2.yml, **/log4j.properties -- **/appsettings*.json (for Serilog/NLog in .NET) -- **/logging.conf, **/logging.yaml (Python) -- **/winston.config.js (Node.js) -``` - -**Search for Logging Dependencies:** -```bash -# Use Grep to find logging libraries -Pattern: "logback|log4j2|slf4j|serilog|nlog|ilogger|winston|bunyan|pino|logging\.getLogger" -Files: **/pom.xml, **/build.gradle, **/*.csproj, **/package.json, **/requirements.txt, **/Gemfile -``` - -**Search for Logger Initialization in Code:** -```bash -Pattern: "LoggerFactory|ILogger|getLogger|Logger\.getLogger|createLogger|logging\.basicConfig" -Files: **/Program.cs, **/Startup.cs, **/Main.java, **/*Application.java, **/app.py, **/main.py, **/server.js, **/app.js -``` - -### 2. Telemetry & APM Detection - -**Application Insights (.NET/Java):** -```bash -Pattern: "applicationinsights|Microsoft\.ApplicationInsights|TelemetryClient" -Files: **/*.csproj, **/pom.xml, **/appsettings.json, **/ApplicationInsights.config -``` - -**OpenTelemetry (Cross-platform):** -```bash -Pattern: "opentelemetry|otel|TracerProvider|MeterProvider" -Files: **/pom.xml, **/build.gradle, **/*.csproj, **/package.json, **/requirements.txt -``` - -**New Relic:** -```bash -Pattern: "newrelic|New Relic" -Files: **/newrelic.yml, **/newrelic.config, **/newrelic.js -``` - -**Datadog:** -```bash -Pattern: "datadog|dd-trace|ddtrace" -Files: **/pom.xml, **/package.json, **/requirements.txt, **/Gemfile -``` - -**Dynatrace:** -```bash -Pattern: "dynatrace|oneagent" -Files: **/*.config, **/dockerfile, **/deployment.yaml -``` - -**Elastic APM:** -```bash -Pattern: "elastic-apm|ElasticApm" -Files: **/pom.xml, **/*.csproj, **/package.json, **/requirements.txt -``` - -### 3. Aspect-Oriented Programming (AOP) Detection - -**Spring AOP (Java):** -```bash -Pattern: "@Aspect|@Before|@After|@Around|spring-aop|aspectjweaver" -Files: **/*.java, **/pom.xml, **/build.gradle -``` - -**PostSharp (.NET):** -```bash -Pattern: "PostSharp|[MethodInterception]|[OnMethodBoundary]" -Files: **/*.cs, **/*.csproj -``` - -**AspectJ:** -```bash -Pattern: "aspectj|@Pointcut|@Aspect" -Files: **/*.java, **/aop.xml, **/pom.xml -``` - -### 4. Startup Code Analysis - -**Check Main Entry Points:** -```bash -# Use Glob to find entry points -Patterns: -- **/Program.cs (ASP.NET Core) -- **/Startup.cs (ASP.NET Core) -- **/Main.java, **/*Application.java (Spring Boot) -- **/app.py, **/main.py, **/__init__.py (Python) -- **/server.js, **/app.js, **/index.js (Node.js) -``` - -**Analyze Startup Configuration:** -```bash -# Read entry point files and check for: -- Logger configuration: builder.Logging.Add*, LogManager.Setup() -- Telemetry setup: services.AddApplicationInsightsTelemetry() -- AOP configuration: services.EnableAspectOrientedProgramming() -``` - -## Framework-Specific Patterns - -### Java/Spring Boot - -**Logback:** -```xml -<!-- logback-spring.xml --> -<configuration> - <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> - ... -``` -```java -// Code pattern -private static final Logger logger = LoggerFactory.getLogger(Application.class); -``` - -**Log4j2:** -```xml -<!-- log4j2.xml --> -<Configuration status="WARN"> - <Appenders> -``` -```java -private static final Logger logger = LogManager.getLogger(Application.class); -``` - -### .NET/ASP.NET Core - -**Serilog:** -```csharp -// Program.cs -Log.Logger = new LoggerConfiguration() - .WriteTo.Console() - .WriteTo.File("logs/log.txt") - .CreateLogger(); -``` -```json -// appsettings.json -"Serilog": { - "Using": ["Serilog.Sinks.Console", "Serilog.Sinks.File"] -} -``` - -**NLog:** -```csharp -// Program.cs -builder.Logging.ClearProviders(); -builder.Host.UseNLog(); -``` -```xml -<!-- nlog.config --> -<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"> -``` - -**ILogger (Built-in):** -```csharp -builder.Logging.AddConsole(); -builder.Logging.AddDebug(); -builder.Logging.AddApplicationInsights(); -``` - -### Python - -**Logging Module:** -```python -import logging -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) -``` - -**Loguru:** -```python -from loguru import logger -logger.add("file.log", rotation="500 MB") -``` - -### Node.js - -**Winston:** -```javascript -const winston = require('winston'); -const logger = winston.createLogger({ - transports: [ - new winston.transports.Console(), - new winston.transports.File({ filename: 'combined.log' }) - ] -}); -``` - -**Pino:** -```javascript -const pino = require('pino'); -const logger = pino(); -``` - -## Analysis Decision Logic - -1. **Check for configuration files** → High confidence if config exists -2. **Check for dependencies** → Medium confidence -3. **Check for code usage** → Confirms framework is actively used -4. **Check for multiple frameworks** → List all detected - -## Confidence Levels - -- **High**: Configuration file + dependency + code usage detected -- **Medium**: Dependency + code usage (no explicit config) -- **Low**: Only dependency found (may not be actively used) - -## Output Format - -After analysis, call the MCP tool: - -```javascript -write_assessment_result({ - resultJson: JSON.stringify({ - input_name: "Startup Instrumentation", - analysis_method: "Hybrid", // Code + LLM analysis - status: "success", // or "not_applicable" or "failed" - result: { - finding: "Serilog with Application Insights and custom AOP interceptors", - confidence: "high", // high, medium, or low - evidence: [ - "Found appsettings.json with Serilog configuration (Console, File, Application Insights sinks)", - "Program.cs configures Serilog at line 12: Log.Logger = new LoggerConfiguration()...", - "ApplicationInsights.config found with instrumentation key", - "Custom AOP: Found 3 MethodInterceptionAspect classes for logging, caching, and validation" - ], - values: [ - "Serilog 3.1.1", - "Application Insights", - "Custom AOP (MethodInterception)" - ], - instrumentation_details: { - logging_framework: "Serilog", - logging_version: "3.1.1", - log_sinks: ["Console", "File", "ApplicationInsights"], - telemetry_provider: "Application Insights", - aop_framework: "Custom (MethodInterception)", - startup_file: "Program.cs" - } - }, - execution_time_seconds: 2.8, - timestamp: new Date().toISOString() - }), - assessmentDir: variables.assessment_dir -}); -``` - -## Multiple Framework Examples - -### Example 1: Spring Boot with Logback + Elastic APM + Spring AOP -```json -{ - "finding": "Logback with Elastic APM and Spring AOP", - "confidence": "high", - "evidence": [ - "logback-spring.xml found with RollingFileAppender", - "pom.xml includes elastic-apm-agent 1.39.0", - "Found 8 @Aspect classes for cross-cutting concerns", - "Application.java initializes APM agent at startup" - ], - "values": ["Logback", "Elastic APM 1.39.0", "Spring AOP", "AspectJ"] -} -``` - -### Example 2: Python with Loguru + OpenTelemetry -```json -{ - "finding": "Loguru with OpenTelemetry", - "confidence": "medium", - "evidence": [ - "requirements.txt includes loguru==0.7.0", - "app.py configures loguru with rotation and retention", - "Found opentelemetry-api in requirements.txt", - "No explicit OpenTelemetry initialization code found" - ], - "values": ["Loguru 0.7.0", "OpenTelemetry (partial)"] -} -``` - -### Example 3: Node.js with Winston + Datadog -```json -{ - "finding": "Winston with Datadog APM", - "confidence": "high", - "evidence": [ - "winston.config.js configures Console, File, and HTTP transports", - "package.json includes winston@3.11.0 and dd-trace@4.23.0", - "server.js imports and initializes dd-trace at line 1", - "Found custom Winston format for JSON structured logging" - ], - "values": ["Winston 3.11.0", "Datadog APM 4.23.0"] -} -``` - -## Not Applicable Scenarios - -Return `status: "not_applicable"` if: -- No logging framework detected (using only print/console.log) -- Project is a library without startup entry point -- CLI tool with minimal logging requirements - -Example: -```json -{ - "input_name": "Startup Instrumentation", - "analysis_method": "Code", - "status": "not_applicable", - "result": { - "finding": "No structured logging framework detected", - "confidence": "high", - "evidence": [ - "No logging configuration files found", - "No logging dependencies in package.json", - "Only console.log statements found in code" - ], - "values": [] - }, - "execution_time_seconds": 1.2, - "timestamp": "2026-03-01T01:00:00Z" -} -``` - -## Error Handling - -Return `status: "failed"` if: -- Unable to access project files -- Critical analysis error occurred -- Timeout during file search - -Include error details: -```json -{ - "status": "failed", - "result": { - "finding": "Analysis failed", - "confidence": "low", - "evidence": ["Error: Permission denied reading configuration files"], - "values": [] - } -} -``` - -## Notes - -- Applications often use multiple logging/telemetry tools (e.g., Serilog + Application Insights) -- List all detected frameworks in `values` array -- Prioritize most prominent framework in `finding` -- AOP frameworks are often used for logging interception - include in analysis -- Check both code and configuration for complete picture diff --git a/.github/skills/fact-system-packages/SKILL.md b/.github/skills/fact-system-packages/SKILL.md deleted file mode 100644 index c315120b6..000000000 --- a/.github/skills/fact-system-packages/SKILL.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -name: fact-system-packages -description: Identify system packages installed in container (nginx, curl, git, etc.) ---- - -# System Packages Analysis - -## Purpose -Identify OS-level system packages installed in the container image through package manager commands. - -## Target Files/Locations -- **/Dockerfile, **/Containerfile - -## Example Patterns -- `RUN apt-get install nginx curl git` -- `RUN apk add --no-cache ca-certificates tzdata` -- `RUN yum install -y postgresql-client` - -## Analysis Steps - -### 1. Find Package Installation Commands -``` -Use Grep: "apt-get install|apt install|apk add|yum install|dnf install" -Files: **/Dockerfile -Context: -A 5 (capture multi-line installs) -``` - -### 2. Extract Package Names -``` -Parse package manager commands: -- apt: after "install" keyword -- apk: after "add" keyword -- yum/dnf: after "install" keyword - -Handle flags: --no-cache, -y, --no-install-recommends -Handle line continuations with \ -``` - -### 3. Categorize Packages -``` -Group by purpose: -- Web servers: nginx, apache2 -- SSL/Certificates: ca-certificates, openssl -- Development tools: git, curl, wget, vim -- Database clients: postgresql-client, mysql-client -- Build tools: gcc, make, build-essential -- Utilities: tzdata, bash, coreutils -``` - -### 4. Count Total Packages -``` -Sum all packages across all RUN commands -Note if cleanup commands present (apt-get clean, rm -rf /var/lib/apt/lists/*) -``` - -## Confidence Determination - -### High Confidence -- ✅ Package install commands clearly visible -- ✅ Package names explicitly listed -- **Example**: "15 system packages installed: nginx, curl, git, ca-certificates, tzdata, etc." - -### Medium Confidence -- ⚠️ Some packages via install scripts -- **Example**: "Packages installed via apt but list partially in script files" - -### Low Confidence -- ⚠️ Base image includes packages, additions unclear -- **Example**: "Base image may include packages, specific additions unclear" - -### Not Applicable -- ❌ No container or minimal base (scratch, distroless) -- **Example**: "Uses scratch base image with no package manager" - -## Output Format - -```json -{ - "input_name": "System Packages", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Packages summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Package manager commands}", - "{Package count}", - "{Installation patterns}" - ], - "values": [ - "{Package names list}", - "{Categories: web, ssl, dev tools, etc.}", - "{Package manager: apt, apk, yum}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-testing-framework/SKILL.md b/.github/skills/fact-testing-framework/SKILL.md deleted file mode 100644 index 97d5e5b9d..000000000 --- a/.github/skills/fact-testing-framework/SKILL.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -name: fact-testing-framework -description: Analyze testing tools and frameworks used in the project ---- - -# Testing Framework Analysis - -## Purpose -Detect testing frameworks and tools used in the codebase. - -## Target Files/Locations -- **/pom.xml, **/build.gradle, **/build.gradle.kts (Java) -- **/*.csproj (C#/.NET) -- **/package.json (Node.js) -- **/requirements.txt, **/requirements-dev.txt, **/setup.py, **/pyproject.toml (Python) -- **/go.mod (Go) -- **/test/**/*.{java,cs,py,js,ts}, **/*Test.{java,cs}, **/*Tests.cs, **/*.test.{js,ts}, **/*.spec.{js,ts}, **/test_*.py, **/*_test.go - -## Analysis Steps - -### 1. Check Java Testing Frameworks (Maven/Gradle) -``` -Use Grep: "junit-jupiter|<artifactId>junit</artifactId>|testng|mockito" -Files: **/pom.xml, **/build.gradle, **/build.gradle.kts - -Map findings: -- junit-jupiter → JUnit 5 -- <artifactId>junit</artifactId> → JUnit 4 -- testng → TestNG -- mockito → Mockito -``` - -### 2. Check .NET Testing Frameworks -``` -Use Grep: "xunit|nunit|MSTest" -Files: **/*.csproj - -Map findings: -- xunit → xUnit -- nunit → NUnit -- MSTest → MSTest -``` - -### 3. Check Node.js Testing Frameworks -``` -Use Grep: "\"jest\"|\"@types/jest\"|\"mocha\"|\"@types/mocha\"|\"chai\"|\"jasmine\"|\"vitest\"|\"@vitest\"" -Files: **/package.json - -Map findings: -- jest / @types/jest → Jest -- mocha / @types/mocha → Mocha -- chai / @types/chai → Chai -- jasmine / @types/jasmine → Jasmine -- vitest / @vitest → Vitest -``` - -### 4. Check Python Testing Frameworks -``` -Use Grep: "pytest|unittest|nose" -Files: **/requirements.txt, **/requirements-dev.txt, **/setup.py, **/pyproject.toml - -Map findings: -- pytest → pytest -- unittest → unittest -- nose → nose -``` - -### 5. Check Go Testing Frameworks -``` -Use Grep: "testify|ginkgo" -Files: **/go.mod - -Map findings: -- testify → testify -- ginkgo → Ginkgo -``` - -### 6. Count Test Files -``` -Use Glob to find test files: -- **/*Test.java, **/*Test.cs, **/*Tests.cs -- **/*.test.js, **/*.test.ts, **/*.spec.js, **/*.spec.ts -- **/test_*.py, **/*_test.go - -Count matching files for evidence -``` - -### 7. Analyze Test Patterns in Source -``` -Use Grep: "@Test|@TestMethod|\\[Fact\\]|\\[Theory\\]|describe\\(|it\\(|test\\(" -Files: **/*.{java,cs,js,ts,py} -Context: -B 1 -A 2 - -Check for common test annotations/decorators -``` - -## Confidence Determination - -### High Confidence -- ✅ Testing framework dependencies found in build files -- ✅ Test files present with matching annotations -- **Example**: "JUnit 5, Mockito detected in pom.xml; Found 23 test files" - -### Medium Confidence -- ⚠️ Test files found but no explicit framework dependency -- **Example**: "Test files found, framework inferred from annotations" - -### Low Confidence -- ⚠️ Few test files, no framework dependencies -- **Example**: "2 test-like files found, no framework detected" - -### Not Applicable -- ❌ No test files or testing dependencies -- **Example**: "No testing frameworks detected" - -## Output Format - -```json -{ - "input_name": "Testing Framework", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Frameworks summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Build file framework references}", - "{Test file counts}", - "{Test annotation patterns}" - ], - "values": [ - "{Detected frameworks: JUnit 5, Mockito, xUnit, Jest, etc.}", - "{Test file count}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-version-information/SKILL.md b/.github/skills/fact-version-information/SKILL.md deleted file mode 100644 index ee5894325..000000000 --- a/.github/skills/fact-version-information/SKILL.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -name: fact-version-information -description: Extract application version from build files and configuration ---- - -# Version Information Analysis - -## Purpose -Identify the application version number from build descriptors, manifests, and configuration files. - -## Target Files/Locations -- **/pom.xml (<version>) -- **/*.csproj (<Version>) -- **/package.json (version field) -- **/build.gradle (version property) -- **/application.{properties,yml} (info.app.version) -- **/AssemblyInfo.cs ([assembly: AssemblyVersion]) - -## Example Patterns -- `<version>1.2.3</version>` (Maven) -- `"version": "2.0.0-beta"` (Node.js) -- `<Version>1.5.0</Version>` (.NET) -- `version = "3.1.4"` (Gradle) - -## Analysis Steps - -### 1. Check Build File Versions -``` -Maven (pom.xml): -Use Grep: "<version>" -Extract first non-parent version - -Gradle (build.gradle): -Use Grep: "^version\\s*=" -Extract: version = '1.2.3' - -Node.js (package.json): -Use Read and parse: { "version": "1.2.3" } - -.NET (*.csproj): -Use Grep: "<Version>" -Extract: <Version>1.2.3</Version> -``` - -### 2. Check Assembly Info -``` -.NET: -Use Grep: "AssemblyVersion|AssemblyFileVersion" -Files: **/AssemblyInfo.cs -Extract: [assembly: AssemblyVersion("1.2.3.4")] -``` - -### 3. Check Application Configuration -``` -Use Grep: "version:|app\\.version|info\\.app\\.version" -Files: **/application.{properties,yml}, **/appsettings.json -``` - -### 4. Check Git Tags -``` -Use Bash: git describe --tags --abbrev=0 -Latest tag often represents version -``` - -## Confidence Determination - -### High Confidence -- ✅ Version explicitly in build file -- ✅ Semantic versioning format (X.Y.Z) -- **Example**: "Application version: 1.2.3 from pom.xml and package.json" - -### Medium Confidence -- ⚠️ Version found but format unusual -- ⚠️ Snapshot/development version -- **Example**: "Version: 2.0.0-SNAPSHOT (development version)" - -### Low Confidence -- ⚠️ No version in files, inferred from git -- **Example**: "Version unclear, git tag suggests 1.0.0" - -### Not Applicable -- ❌ Versioning not used -- **Example**: "No version information found in project" - -## Output Format - -```json -{ - "input_name": "Version Information", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Version summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Source file and location}", - "{Version format}", - "{Git tag if applicable}" - ], - "values": [ - "{Version number: X.Y.Z}", - "{Version type: release, snapshot, beta}", - "{Build/patch number if applicable}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-volume-mounts/SKILL.md b/.github/skills/fact-volume-mounts/SKILL.md deleted file mode 100644 index 65d8a57dd..000000000 --- a/.github/skills/fact-volume-mounts/SKILL.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -name: fact-volume-mounts -description: Identify persistent volume configurations for data storage ---- - -# Volume Mounts Analysis - -## Purpose -Identify persistent storage volumes configured for data persistence, configuration, and logs. - -## Target Files/Locations -- **/Dockerfile** (VOLUME instruction) -- **/docker-compose*.yml** (volumes section) -- **/k8s/**/*.yaml** (volumeMounts, volumes, PersistentVolumeClaim) - -## Example Patterns -- `VOLUME /data /logs` -- `volumes: - ./data:/app/data` -- `mountPath: /var/lib/postgresql/data` - -## Analysis Steps - -### 1. Check Dockerfile VOLUME -``` -Use Grep: "^VOLUME\\s+" -Files: **/Dockerfile -Extract volume paths -``` - -### 2. Analyze docker-compose Volumes -``` -Use Read: **/docker-compose*.yml -Look for volumes: section (both top-level and per-service) -Types: bind mounts, named volumes, tmpfs -``` - -### 3. Check Kubernetes Volumes -``` -Use Grep: "volumeMounts:|volumes:|persistentVolumeClaim" -Files: **/k8s/**/*.yaml -Context: -B 1 -A 5 -``` - -### 4. Categorize Volume Purposes -``` -Group by type: -- Data: /data, /var/lib/postgresql, /var/lib/mysql -- Logs: /logs, /var/log -- Config: /etc/config, /app/config -- Temp: /tmp, /var/tmp -``` - -## Confidence Determination - -### High Confidence -- ✅ Volumes explicitly configured -- ✅ Mount paths and purposes clear -- **Example**: "3 volumes: /data for database, /logs for application logs, /config for runtime config" - -### Medium Confidence -- ⚠️ VOLUME declared but mount points unclear -- **Example**: "Dockerfile declares VOLUME /data but docker-compose doesn't mount it" - -### Low Confidence -- ⚠️ No explicit volumes but app may use storage -- **Example**: "No volumes configured, data likely ephemeral" - -### Not Applicable -- ❌ Stateless application -- **Example**: "Stateless API with no persistent storage" - -## Output Format - -```json -{ - "input_name": "Volume Mounts", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Volumes summary}", - "confidence": "high|medium|low", - "evidence": [ - "{Dockerfile VOLUME}", - "{docker-compose volumes}", - "{K8s PVC/volumes}" - ], - "values": [ - "{Volume paths}", - "{Purposes: data, logs, config}", - "{Volume types: bind, named, PVC}" - ] - }, - "execution_time_seconds": {elapsed}, - "timestamp": "{ISO 8601}" -} -``` diff --git a/.github/skills/fact-xml-configs/SKILL.md b/.github/skills/fact-xml-configs/SKILL.md deleted file mode 100644 index e49ea6bcf..000000000 --- a/.github/skills/fact-xml-configs/SKILL.md +++ /dev/null @@ -1,298 +0,0 @@ ---- -name: fact-xml-configs -description: Analyze XML configuration files usage in the application ---- - -# XML Configuration Files Analysis - -## Purpose -Identify and catalog XML configuration files used by the application, including Spring context files, Hibernate configurations, web.xml, and other framework-specific XML files. This helps understand configuration management approach and migration requirements. - -## Target Files/Locations -- **Spring Framework**: **/applicationContext*.xml, **/spring-*.xml, **/*-context.xml, **/beans.xml -- **Hibernate ORM**: **/hibernate.cfg.xml, **/*.hbm.xml -- **Java EE/Jakarta EE**: **/web.xml, **/ejb-jar.xml, **/persistence.xml -- **MyBatis**: **/mybatis-config.xml, **/*-mapper.xml -- **Log4j**: **/log4j.xml, **/log4j2.xml -- **Maven**: **/pom.xml -- **Build configs**: **/build.xml (Ant), **/ivy.xml -- **Application configs**: **/config/**/*.xml, **/conf/**/*.xml - -## Example Patterns to Search -- Spring XML config with bean definitions -- Hibernate mapping files (.hbm.xml) -- MyBatis SQL mapper files -- web.xml servlet configurations -- persistence.xml JPA configurations -- log4j.xml or log4j2.xml logging configurations - -## Analysis Steps - -### 1. Search for Spring XML Configuration Files -``` -Use Glob tool to find Spring config files: -- **/applicationContext*.xml -- **/spring-*.xml -- **/*-context.xml -- **/beans.xml -- **/META-INF/spring/**/*.xml - -For each file found: -- Use Read tool to examine first 50 lines -- Check for <beans> root element -- Identify bean definitions, imports, property placeholders -- Note component-scan or annotation-config presence -``` - -### 2. Search for Hibernate Configuration Files -``` -Use Glob tool to find Hibernate files: -- **/hibernate.cfg.xml -- **/*.hbm.xml - -For each file: -- Read to identify database dialect -- Check for entity mappings -- Note session factory configuration -- Identify connection pool settings -``` - -### 3. Search for Java EE/Jakarta EE Deployment Descriptors -``` -Use Glob tool to find Java EE files: -- **/WEB-INF/web.xml -- **/META-INF/ejb-jar.xml -- **/META-INF/persistence.xml -- **/META-INF/application.xml - -Analyze each: -- Servlet/filter configurations (web.xml) -- JPA entity configurations (persistence.xml) -- EJB declarations (ejb-jar.xml) -``` - -### 4. Search for MyBatis Configuration Files -``` -Use Glob tool: -- **/mybatis-config.xml -- **/*-mapper.xml -- **/sqlmap/**/*.xml - -Check for: -- SQL mapper namespaces -- Select/insert/update/delete statements -- Result maps and parameter maps -``` - -### 5. Search for Logging XML Configurations -``` -Use Glob tool: -- **/log4j.xml -- **/log4j2.xml -- **/logback.xml - -Analyze: -- Appender configurations -- Logger level settings -- Output patterns -``` - -### 6. Count and Categorize All XML Files -``` -Use Bash tool to count XML files: -find . -type f -name "*.xml" -not -path "*/target/*" -not -path "*/.git/*" | wc -l - -Use Grep to identify XML configuration files (vs data files): -- Pattern: "<beans|<configuration|<hibernate-configuration|<web-app|<persistence" -- Files: **/*.xml -- Output mode: files_with_matches - -Categorize by framework: -- Spring: beans, context namespaces -- Hibernate: hibernate-configuration, hibernate-mapping -- Java EE: web-app, ejb-jar, persistence-unit -- MyBatis: mapper namespace -- Logging: log4j:configuration, configuration (logback) -``` - -### 7. Analyze XML Complexity and Size -``` -For each significant XML file: -- Use Read to get line count -- Check for external entity references -- Identify property placeholders (${...}) -- Note XSD/DTD schema references -- Check for profiles or conditional configurations -``` - -## Confidence Determination - -### High Confidence Criteria -Clear evidence of XML configuration usage with detailed findings: -- ✅ Multiple XML configuration files identified with specific purposes -- ✅ Framework-specific XML files present (Spring, Hibernate, etc.) -- ✅ Valid XML structure confirmed with proper root elements -- ✅ Bean/entity/mapper definitions clearly visible -- ✅ Relationship between files understood (imports, includes) - -**Examples**: -- "Found 23 Spring XML config files with 450+ bean definitions across applicationContext.xml and imported files" -- "Hibernate configuration with 15 .hbm.xml entity mapping files and hibernate.cfg.xml" -- "Web application with web.xml (Servlet 3.1) and 8 Spring context XML files" - -### Medium Confidence Criteria -Partial evidence or incomplete information: -- ⚠️ XML files found but unclear purpose or usage -- ⚠️ Config files present but may be legacy/unused -- ⚠️ XML files exist alongside annotation-based config (hybrid approach) -- ⚠️ Limited XML usage (only logging or build configs) -- ⚠️ XML files in resources but no clear loading mechanism - -**Examples**: -- "Spring XML files found but @Configuration classes also present (hybrid setup)" -- "Hibernate .hbm.xml files exist but JPA annotations also used" -- "XML files present but timestamps suggest not recently modified" - -### Low Confidence Criteria -Weak or ambiguous evidence: -- ⚠️ Only build tool XML files (pom.xml, build.xml) -- ⚠️ No framework-specific XML configurations -- ⚠️ XML files are data files, not configuration -- ⚠️ Test resources only, no production configs -- ⚠️ Commented-out or example XML files - -**Examples**: -- "Only pom.xml found, no application XML configs" -- "XML files in test resources only, production uses properties/YAML" -- "Sample XML files in documentation directory, not active configs" - -### Not Applicable Criteria -When XML configuration analysis doesn't apply: -- ❌ Pure annotation-based configuration (Spring Boot @Configuration) -- ❌ Configuration via properties/YAML files only -- ❌ Non-Java application (.NET, Node.js, Python) -- ❌ Library project with no configuration requirements -- ❌ Modern application using Java Config exclusively - -**Examples**: -- "Spring Boot application using only @Configuration classes and application.yml" -- ".NET Core application, XML config analysis not applicable" -- "Node.js application with JSON configuration only" - -## Output Format - -**CRITICAL**: Use the `write_assessment_result` tool (not just output JSON text). - -```json -{ - "input_name": "XML Configs", - "analysis_method": "LLM", - "status": "success|not_applicable", - "result": { - "finding": "{Clear 1-2 sentence summary of XML configuration usage}", - "confidence": "high|medium|low", - "evidence": [ - "{Number and types of XML files found}", - "{Specific file paths for major configs}", - "{Framework identifications from XML content}", - "{Configuration patterns observed}" - ], - "values": [ - "{Framework: Spring, Hibernate, MyBatis, etc.}", - "{File count by type}", - "{Key configuration file names}", - "{Schema versions or namespaces}" - ] - }, - "execution_time_seconds": {elapsed_time}, - "timestamp": "{ISO 8601 timestamp}" -} -``` - -**Finding Examples**: -- ✅ Good: "Application uses Spring XML configuration with 18 context files defining 250+ beans, including applicationContext.xml as root config" -- ✅ Good: "Hibernate-based persistence with hibernate.cfg.xml and 12 .hbm.xml entity mapping files for database layer" -- ✅ Good: "Web application with web.xml (Servlet 3.0), 5 Spring XML contexts, and MyBatis mapper files for SQL" -- ✅ Good: "No XML configuration detected - application uses Spring Boot with annotation-based @Configuration classes" -- ❌ Bad: "XML files found" -- ❌ Bad: "Configuration exists" - -**Evidence Examples**: -- ✅ Good: "applicationContext.xml at src/main/resources/ with 45 bean definitions and 3 imported context files" -- ✅ Good: "15 Hibernate mapping files (*.hbm.xml) in src/main/resources/mappings/ for entity persistence" -- ✅ Good: "web.xml at WEB-INF/ defines 8 servlets and 12 filters with Spring DispatcherServlet" -- ✅ Good: "23 MyBatis mapper XML files in resources/mappers/ with SQL definitions" -- ❌ Bad: "Found XML files in project" -- ❌ Bad: "Spring configuration present" - -## Error Handling - -### 1. No XML Configuration Found -- Report finding as "No XML configuration files detected" -- Set confidence to high if thorough search confirmed absence -- Note alternative config approaches if detected (annotations, properties, YAML) - -### 2. Mixed Configuration Approaches -- Report both XML and alternative approaches found -- Set confidence to medium -- List what's configured via XML vs annotations/properties -- Example: "Hybrid approach: Spring XML for legacy beans, @Configuration for new services" - -### 3. Too Many XML Files -- If >100 XML files found, categorize and sample -- Provide statistics by category -- Focus detailed analysis on framework config files -- Note if many are data files vs configuration files - -### 4. Tool Failures -- If Glob returns too many results, refine with more specific patterns -- If Read fails on corrupted XML, note the file but continue -- After 3 retries on critical operations, report partial results with caveats - -### 5. Invalid/Malformed XML -- Note files that appear to be XML but fail parsing -- Don't let malformed files block analysis -- Report count of valid vs invalid XML files found - -## Example Complete Analysis - -**Scenario**: Java Spring MVC application with XML-based configuration - -**Steps Executed**: -1. Glob for Spring XML: Found 18 files (applicationContext.xml + 17 imported) -2. Read applicationContext.xml: Confirmed Spring 4.3 with bean definitions -3. Glob for Hibernate: Found hibernate.cfg.xml and 12 .hbm.xml files -4. Glob for Java EE: Found web.xml in WEB-INF/ -5. Count total XML: 45 XML files in project (excluding target/) -6. Categorized: 18 Spring, 13 Hibernate, 1 Java EE, 8 MyBatis, 2 logging, 3 Maven - -**Result**: -```json -{ - "input_name": "XML Configs", - "analysis_method": "LLM", - "status": "success", - "result": { - "finding": "Application heavily uses XML configuration with 18 Spring context files, 13 Hibernate mappings, and Java EE web.xml for a traditional XML-based architecture", - "confidence": "high", - "evidence": [ - "applicationContext.xml at src/main/resources/ with <beans> root and 45 bean definitions", - "18 Spring XML files with imports: data-context.xml, security-context.xml, service-context.xml, etc.", - "hibernate.cfg.xml and 12 entity mapping files (*.hbm.xml) in resources/mappings/", - "web.xml at WEB-INF/web.xml defines DispatcherServlet and 8 filters (Servlet API 3.0)", - "8 MyBatis mapper XML files in resources/mappers/ with SQL queries", - "log4j.xml configuration for logging with 5 appenders" - ], - "values": [ - "Spring Framework (XML-based config, Spring 4.3 schema)", - "Hibernate ORM (12 .hbm.xml entity mappings)", - "Java EE Servlet 3.0 (web.xml)", - "MyBatis (8 mapper files)", - "45 total XML configuration files", - "Log4j XML configuration" - ] - }, - "execution_time_seconds": 32.8, - "timestamp": "2026-02-28T10:18:15Z" -} -``` diff --git a/.github/skills/integration-tests/SKILL.md b/.github/skills/integration-tests/SKILL.md deleted file mode 100644 index c8e01f131..000000000 --- a/.github/skills/integration-tests/SKILL.md +++ /dev/null @@ -1,324 +0,0 @@ ---- -name: integration-tests -description: Run multi-layer integration tests for modernized Java applications. Supports 4 layers - Layer 1 (TestContainers), Layer 2 (Smoke Tests), Layer 3 (Azure Integration), Layer 4 (Behavioral Comparison). **Java projects only** - skip if source code is not Java. ---- - -## Language Support - -**This skill supports Java projects only.** If the source code is not Java (e.g., .NET, Python, Node.js), skip test generation and report that integration tests are not supported for this language. - -## User Input -- **layer** (Optional): Which layer to test (1, 2, 3, or 4). Default: 1 -- **azure-config** (Optional, Layer 3 only): Azure environment configuration -- **modernization-work-folder** (Optional): Directory path for generating plan and summary files. Default: `.github` -- **test-root** (Optional): The root directory for integration tests. Default: current working directory. All application modules found in the directory are included in integration tests. - -## Available references - -### Layer 1: Local Integration Tests -**Read [references/layer1-local-integration.md](references/layer1-local-integration.md) first**, then create TestContainers-based integration test classes. - -### Layer 2: Smoke Tests -**Read [references/layer2-smoke-tests.md](references/layer2-smoke-tests.md) first.** Layer 2 uses shell-based smoke tests with docker-compose, NOT JUnit test classes. Follow the exact multi-commit workflow (artifacts → auth → restore) documented in the reference file. - -### Layer 3: Azure Integration Tests -**Read [references/layer3-azure-integration.md](references/layer3-azure-integration.md) first**, then create integration test classes that connect to real Azure services. - -### Layer 4: Behavioral Comparison -**Read [references/layer4-behavioral-comparison.md](references/layer4-behavioral-comparison.md) first**, then create comparison tests that validate behavior matches between old and new implementations. - -### TestContainers Coding References -- **Azure Service Bus with TestContainers Coding Reference**, see [references/layer1-servicebus-integration.md](references/azure-servicebus-testcontainers.md) -- **Azure Storage with TestContainers Coding Reference**, see [references/layer1-blobstorage-integration.md](references/azure-storage-testcontainers.md) - -## Workflow - -1. Analyze the project to identify modules that need to be tested and any existing integration tests. If git history is available, analyze past commits to understand which components were modified during modernization and prioritize testing those areas. -2. Create an integration test plan file at `{modernization-work-folder}/integration-tests/integration-test-plan.md` that outlines: - - Testing strategy and approach for the detected app modules - - Testing strategy and approach for each layer - - Identified components requiring integration testing - - Dependencies and test setup requirements - - Expected test scenarios and validation criteria -3. Implement new integration tests following the principles outlined below -4. Execute the tests -5. If issues found: - - Analyze failures using the Test vs Source Code Decision Framework to determine whether to fix test code or source code - - Fix source code if the failure indicates a real problem in the application logic. - - Fix test code if the failure is due to unrealistic test scenarios, incorrect test setup. - - Execute tests again after fixes -6. **Only proceed when all tests run and pass**, or exit after 20 attempts -7. Create an integration test summary file at `{modernization-work-folder}/integration-tests/integration-test-summary.md` that documents: - - All integration tests added (with file paths and descriptions) - - Test coverage improvements achieved - - Final test execution results -8. Commit all code changes with brief and meaningful commit messages - -## Integration Tests Writing Principles - -**CRITICAL - Read Reference Docs First:** -- **Before starting ANY layer**, read the corresponding reference file in [references/](./references/) directory - -Analyze the project if integration tests have covered all components, if not **DO ADD** new integration tests by the following principles: - -- **Purpose:** Ensures combined components function as a whole, focusing on "in-between" logic rather than individual module functionality. -- **DO use** top-down approach to add integration tests. For example, if an application has controller layer, service layer, and database layer. The integration tests should set up real connections to the database, and then test against the controller layer, to validate all functionalities. -- **DO focus on:** Validates interactions between modules, databases, messaging services, and file systems. -- **DO NOT** change the technical stack, architure selection, libary using in the source code. The goal is to validate the existing application code, not change it to pass tests. -- **DO fix issues** in the appropriate place (test or source code) based on the analysis. -- **DO write** comprehensive integration covering **ALL** components. -- **DO test through the application's own classes.** Every test must instantiate and invoke the project's own classes/methods. Never call third-party SDK APIs directly as a substitute for testing application code. Tests that only exercise Azure/Redis/PostgreSQL SDK operations without going through the application's handler/service/manager classes will score very low on functional coverage. -- **DO use** the layer-specific class name suffix from the Test Isolation Convention (e.g., `L1Test` for Layer 1, `L3Test` for Layer 3, `L4Test` for Layer 4). **Layer 2 does not use test classes.** -- **DO annotate** every test class with the layer-specific tag/category from the Test Isolation Convention. -- **DO verify** that `mvn verify` (or equivalent build command) discovers and runs all tests without extra flags. If tests require `-Dtest=...` to be found, the build configuration is wrong. -- **DO NOT** leave commented-out tests or dead test code. Every `@Test` annotation must be on a working test method. -- **DO NOT** add extra modules for integration tests, write integration tests in the existing modules. -- **DO commit** changes separately for each layer with meaningful commit messages. Do not combine changes from different layers into a single commit. - - **Layer 1, 3, 4**: Single commit per layer (e.g., `Add Layer 1 local integration tests`). Generate runner scripts and include them in the same commit. - - **Layer 2**: Multi-commit sequence as defined in [layer2-smoke-tests.md](./references/layer2-smoke-tests.md) (artifacts → auth → restore). **CRITICAL: Layer 2 does NOT create test classes - it uses shell-based smoke tests with docker-compose.** Runner scripts are part of the artifacts commit. - - -### Test Isolation Convention - -When multiple layers coexist in the same project, tests must be distinguishable. **Every layer MUST use a distinct class name suffix AND tag/category** so tests from different layers never interfere with each other. - -#### Naming Convention - -| Layer | Class Name Suffix | Example Class Name | -|-------|-------------------|--------------------| -| 1 | `L1Test` | `BlobStorageL1Test`, `OrderServiceL1Test` | -| 2 | N/A - No test classes | Layer 2 uses shell-based smoke tests, not test classes. See [layer2-smoke-tests.md](./references/layer2-smoke-tests.md) | -| 3 | `L3Test` | `AzureSqlL3Test`, `BlobStorageL3Test` | -| 4 | `L4Test` | `OrderApiL4Test`, `UserServiceL4Test` | - -#### Tagging / Category Convention - -Test classes for Layers 1, 3, 4 **MUST** be annotated with a layer-specific tag so the runner script can filter precisely. **Layer 2 does not use test classes** (see [layer2-smoke-tests.md](./references/layer2-smoke-tests.md)). - -| Layer | JUnit 5 | JUnit 4 | -|-------|---------|---------| -| 1 | `@Tag("Layer1")` | `@Category(Layer1.class)` | -| 2 | N/A - Shell-based | N/A - Shell-based | -| 3 | `@Tag("Layer3")` | `@Category(Layer3.class)` | -| 4 | `@Tag("Layer4")` | `@Category(Layer4.class)` | - -> **Rule**: Never rely solely on class name patterns for filtering. Always use tags/categories as the primary filter mechanism. - -### NEVER Mock the Migrated Service - -**This is the most important rule in this entire skill — it applies to ALL layers.** - -Integration tests MUST use real TestContainers for layer 1 and 2 and real cloud services for Layer 3 for every migrated dependency. Do NOT mock or `@MockBean` the SDK client that the migrated code uses (e.g., `ServiceBusTemplate`, `ServiceBusSenderClient`, `BlobServiceClient`, `RedisTemplate`, `DataSource`). Instead, spin up a real container and wire the application's own service to it. - -#### The Anti-Pattern You MUST Avoid - -```java -// ❌ WRONG — mocks the migrated service and SDK clients, tests unchanged code instead -@SpringBootTest -@ActiveProfiles("test") -class MyAppL1Test { - @MockBean private MessageService messageService; // THE MIGRATED CLASS — never tested! - @MockBean private ServiceBusSenderClient senderClient; // should be from real emulator - @MockBean private TokenCredential tokenCredential; // should be from emulator config - @Autowired private UserRepository userRepo; // unchanged code - - @Test void testUserCrud() { - userRepo.save(new User("test")); // tests unchanged code, NOT the migration - } -} -``` - -```java -// ✅ RIGHT — uses real Service Bus emulator, ALL beans wired from containers, tests through migrated service -@SpringBootTest -@ActiveProfiles("test") -@Testcontainers -class MyAppL1Test { - @Container static final GenericContainer<?> SERVICE_BUS = ...; // real emulator - // No @MockBean at all — all beans come from containers + @DynamicPropertySource - @Autowired private MessageService messageService; // THE MIGRATED CLASS — tested for real! - - @DynamicPropertySource - static void props(DynamicPropertyRegistry registry) { - registry.add("spring.cloud.azure.servicebus.connection-string", () -> getConnectionString()); - // ... other container-derived properties - } - - @Test void testSendMessage() { - messageService.sendMessage("queue", "Hello"); // exercises the actual migrated code - } -} -``` - -## Handling Test Failures - -When integration tests fail during execution, use this framework to determine whether to fix the test code or the source code: - -### Fix Source Code When: - -**Business Logic Violations** -- Error indicates source code violates business rules (e.g., negative inventory allowed) -- Multiple similar tests fail with same pattern -**Specification Compliance** -- Source code doesn't implement required functionality properly -- Error messages show missing or incorrect behavior -**Cross-Component Integration Issues** -- Test setup is correct and realistic -- Source code fails to properly communicate between modules -- Data transformation or mapping errors between layers -**Resource Management Problems** -- Test uses proper connection/resource patterns -- Source code has leaks, deadlocks, or improper disposal -- Timing issues in source code (not test race conditions) - -### Fix Test Code When: - -**Test Implementation Issues** -- Unrealistic test data or scenarios -- Incorrect test setup (wrong mocks, invalid configurations) -- Testing implementation details rather than behavior -- Race conditions or timing issues in test logic -**Environmental Problems** -- Wrong container configurations or versions -- Test dependencies not properly isolated -- Hard-coded values that should be configurable -- Test cleanup issues affecting subsequent tests -**Test Design Flaws** -- Tests making too many assumptions about internal state -- Over-mocking leading to false confidence -- Testing edge cases that don't reflect real usage -- Assertions on wrong data or wrong timing - -### Analysis Steps: - -1. **Review Test Quality**: Does the test follow established patterns and realistic scenarios? -2. **Check Business Logic**: Does the failure indicate business rule violations in source code? -3. **Verify Setup**: Are test dependencies and configurations realistic and correct? -4. **Assess Error Type**: Is it a logic error, integration error, or test infrastructure issue? -5. **Consider Impact**: Would fixing source code improve real application behavior? - -### Decision Process: - -``` -Test Failure - │ - ├─ Does test model realistic business scenario? - │ ├─ No → Fix Test Code - │ └─ Yes ↓ - │ - ├─ Does source code violate business rules? - │ ├─ Yes → Fix Source Code - │ └─ No ↓ - │ - ├─ Is test setup and environment correct? - │ ├─ No → Fix Test Code - │ └─ Yes ↓ - │ - └─ Does error show integration/logic problem? - ├─ Yes → Fix Source Code - └─ No → Fix Test Code -``` - -## Standardized Runner Scripts - -After all tests are written, executed, and fixed to pass, generate a fixed runner script so users can re-run integration tests with a single command regardless of project type. - -| Layer | Script Path | Command (Unix) | Command (Windows) | -|-------|-------------|----------------|--------------------|| -| 1 | `{modernization-work-folder}/integration-tests/run-layer1-tests.sh` / `.ps1` | `bash {modernization-work-folder}/integration-tests/run-layer1-tests.sh` | `powershell {modernization-work-folder}/integration-tests/run-layer1-tests.ps1` | -| 2 | `{modernization-work-folder}/integration-tests/run-layer2-tests.sh` / `.ps1` | `bash {modernization-work-folder}/integration-tests/run-layer2-tests.sh` | `powershell {modernization-work-folder}/integration-tests/run-layer2-tests.ps1` | -| 3 | `{modernization-work-folder}/integration-tests/run-layer3-tests.sh` / `.ps1` | `bash {modernization-work-folder}/integration-tests/run-layer3-tests.sh` | `powershell {modernization-work-folder}/integration-tests/run-layer3-tests.ps1` | -| 4 | `{modernization-work-folder}/integration-tests/run-layer4-tests.sh` / `.ps1` | `bash {modernization-work-folder}/integration-tests/run-layer4-tests.sh` | `powershell {modernization-work-folder}/integration-tests/run-layer4-tests.ps1` | - -### Runner Script Requirements - -1. **Always generate both `.sh` and `.ps1` variants** for cross-platform support. -2. The script **MUST** encapsulate all project-specific details (build tool, test runner, filters, working directory, container setup/teardown). -3. The script **MUST** be self-contained — users should not need to know the build system or test framework to run it. -4. The script **MUST** exit with code 0 on success and non-zero on failure. -5. The script **MUST** print a human-readable result summary at the end: - - **On success**: `✅ Layer 1 integration tests PASSED` - - **On failure**: `❌ Layer 1 integration tests FAILED` - - The test runner's own console output already includes detailed counts, failure logs, assertion messages, and stack traces — the script only needs a clear pass/fail signal at the end. -6. For Layer 1, the script **MUST** verify Docker is running before starting tests. -7. For Layer 2, the script **MUST** handle starting and stopping the application. -8. For Layer 3, the script **SHOULD** accept Azure configuration via environment variables. -9. For Layer 4, the script **MUST** handle starting both old and new application versions. - -### Runner Script Filtering - -**Layers 1, 3, 4** use tag/category filters to execute test classes. **Layer 2 uses shell commands** (see [layer2-runner-script-templates.md](./references/layer2-runner-script-templates.md)). - -| Layer | Maven | Gradle | -|-------|-------|--------| -| 1 | `mvn verify -Dgroups=Layer1` | `./gradlew test -Dgroups=Layer1` | -| 2 | Shell-based smoke tests | Shell-based smoke tests | -| 3 | `mvn verify -Dgroups=Layer3` | `./gradlew test -Dgroups=Layer3` | -| 4 | `mvn verify -Dgroups=Layer4` | `./gradlew test -Dgroups=Layer4` | - -### Example Runner Script Structure (Layer 1) - -```bash -#!/bin/bash -set -euo pipefail - -# --- Auto-generated integration test runner --- -# Project type: <detected> -# Generated on: <date> - -# Verify prerequisites -if ! docker info > /dev/null 2>&1; then - echo "ERROR: Docker is not running. Please start Docker and try again." - exit 1 -fi - -# Run integration tests (project-specific command is embedded here) -# IMPORTANT: Always filter by the layer-specific tag to avoid running other layers' tests -# Test output (including any failure logs) goes directly to the console. -cd "$(dirname "$0")/../.." - -<project-specific-test-command> -# e.g., mvn verify -Dgroups=Layer1, ./gradlew test -Dgroups=Layer1 - -TEST_EXIT=$? - -# --- Print summary --- -echo "" -echo "========================================" -if [ $TEST_EXIT -eq 0 ]; then - echo "✅ Layer 1 integration tests PASSED" -else - echo "❌ Layer 1 integration tests FAILED" -fi -echo "========================================" -exit $TEST_EXIT -``` - -> **Note to implementers:** Replace `<project-specific-test-command>` with the real test command for the detected project type (Maven/Gradle). The test runner's own console output already includes detailed results — the script just appends a clear pass/fail signal at the end. - -## Completion Criteria - -1. **Integration Test Plan**: Create and output a plan file at `{modernization-work-folder}/integration-tests/integration-test-plan.md` that includes: - - Analysis of existing test coverage gaps - - Identified components requiring integration testing - - Testing strategy and approach for each component - - Dependencies and test setup requirements - - Expected test scenarios and validation criteria -2. All tests for the requested layer **run and pass**, show the running results to the user -3. Test results are reported with clear pass/fail status -4. Any failures are properly analyzed and resolved (see Handling Test Failures section) -5. Test artifacts (logs, screenshots, comparison reports) are saved - -6. **Version Control**: Commit changes separately for each layer with meaningful commit messages. Do not combine changes from different layers into a single commit. - - **Layer 1, 3, 4**: Single commit per layer including test classes and runner scripts (e.g., `Add Layer 1 local integration tests`) - - **Layer 2**: Multi-commit sequence as defined in [layer2-smoke-tests.md](./references/layer2-smoke-tests.md) (minimum 3 commits: artifacts → auth → restore). Runner scripts are part of the artifacts commit. - - **Git ignore respect**: Use standard `git add` commands. Do not force-add files. If files in `{modernization-work-folder}` are ignored by the project's `.gitignore`, respect that. - -7. **Integration Test Summary**: Create and output a summary file at `{modernization-work-folder}/integration-tests/integration-test-summary.md` that documents: - - All integration tests added (with file paths and descriptions) - - Test coverage improvements achieved - - Issues identified and resolved (both in source code and test code) - - Final test execution results - - Paths to generated runner scripts and the fixed commands to execute them - - Source code changes made during testing and their purpose -8. **Runner Scripts**: Generate standardized runner scripts at `{modernization-work-folder}/integration-tests/run-layer{N}-tests.sh` and `.ps1` (see Standardized Runner Scripts section). The scripts must embed all project-specific commands so users always run the same fixed command. Include runner scripts in the layer's commit (for Layer 2, in the artifacts commit). diff --git a/.github/skills/integration-tests/references/azure-auth-strategies.md b/.github/skills/integration-tests/references/azure-auth-strategies.md deleted file mode 100644 index 5300d4636..000000000 --- a/.github/skills/integration-tests/references/azure-auth-strategies.md +++ /dev/null @@ -1,189 +0,0 @@ -# Azure Authentication Strategies for Smoke Tests - -Migrated applications typically use **Managed Identity** (`DefaultAzureCredential`) which only works on Azure infrastructure. For local smoke testing, applications must connect to local emulators or have Azure services disabled. - -## Azure Dependency Classification - -Classify each Azure dependency into one of three categories: - -| Category | Smoke Test Strategy | Example Services | -|----------|---------------------|------------------| -| **Emulatable** | Use local emulator with connection string auth | Azurite, Cosmos Emulator, Service Bus Emulator, Event Hubs Emulator | -| **Lazy** | Skip — not validated at startup | On-demand blob uploads, external REST APIs | -| **Startup-required, non-emulatable** | Disable via config, or recommend Layer 3 | Key Vault, App Configuration | - -### Emulatable Azure Services - -These services have official emulators that can run in Docker containers: - -| Azure Service | Emulator Image | Dependencies | -|---------------|----------------|--------------| -| Blob / Queue / Table Storage | `mcr.microsoft.com/azure-storage/azurite` | None | -| Cosmos DB | `mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator` | None (but requires SSL trust store + endpoint/key auth) | -| SQL Database | `mcr.microsoft.com/mssql/server` | None (wire-compatible with SQL Server) | -| Service Bus | `mcr.microsoft.com/azure-messaging/servicebus-emulator` | Requires MSSQL companion + JSON config | -| Event Hubs | `mcr.microsoft.com/azure-messaging/eventhubs-emulator` | Requires Azurite companion + JSON config | - -> **Note:** Service Bus and Event Hubs emulators require companion containers and a JSON config file. See [azure-servicebus-testcontainers.md](./azure-servicebus-testcontainers.md) for the config format. - -**Cosmos DB emulator note:** Unlike other emulators which use connection strings, the Cosmos DB emulator authenticates via **endpoint + account key** and requires an **SSL certificate** imported into a trust store (e.g., `javax.net.ssl.trustStore` for Java). If SSL setup is too complex, treat Cosmos DB as non-emulatable and recommend Layer 3. - -### Lazy Azure Connections - -If an Azure client is only used inside request handlers or scheduled jobs (no `@PostConstruct` / `IHostedService.StartAsync` / health check probing it), it's lazy. **Skip it** — the app starts fine without it. - -**How to identify:** -- Client is injected but never called during startup -- Client is used only in REST endpoint handlers -- Client is used in background jobs that start after initialization - -### Startup-Required, Non-Emulatable Services - -Some Azure services are required at startup but have no local emulator. - -**Resolution strategies (in priority order):** - -1. **Disable via config** — e.g., `spring.cloud.azure.keyvault.secret.enabled=false` or `KeyVault__Enabled=false` with an `if` guard around registration. -2. **Stub the health check** — Skip that health indicator in the smoke profile. -3. **Accept partial startup** — Non-fatal errors are OK for Layer 2 if the app reaches a healthy state. -4. **Skip Layer 2, recommend Layer 3** — If the app cannot start without a real Azure connection. - -## Authentication Modification Strategies - -For each emulatable Azure dependency, modify how the application authenticates: - -### Config-Driven Applications - -**Examples:** Spring Boot applications with `application.properties` or `application.yml`, Quarkus/Micronaut applications with `application.properties` - -**When to use:** Applications that use a configuration framework to externalize settings. These apps read connection strings from config files at runtime. - -**Strategy:** Modify config files to add explicit emulator connection strings. Create or modify the main config file (NOT environment variables, NOT test-only config files). - -**Which config file to modify:** -- Spring Boot: `src/main/resources/application.properties` or `src/main/resources/application.yml` -- Quarkus: `src/main/resources/application.properties` - -**CRITICAL:** You MUST always modify the config file to add the explicit connection string value. Do NOT rely on environment variables. - -**Example:** - -`src/main/resources/application.properties`: -```properties -azure.storage.blob.connection-string=DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://localhost:10000/devstoreaccount1; -spring.data.mongodb.uri=mongodb://localhost:27017/mydb -``` - -**If the application code uses `@Bean` methods or manual client construction:** You may also need to modify the code to read these config properties if it doesn't already. Add code to accept the connection string property with fallback to the original auth. Then add the connection string value to the config file as shown above. - -### Hardcoded/Plain Applications - -**Examples:** Plain Java CLI apps without config frameworks - -**When to use:** Applications that have NO configuration framework (no Spring Boot, no application.properties). These apps construct clients directly in code with hardcoded values. - -**Strategy:** Modify the source code to hardcode emulator connection strings directly in the client construction code. Since these applications don't have config files to modify, the connection string must be in the source code itself to be committed to git. - -**Why hardcoding is required:** -- No config framework means no config files to modify -- Environment variables aren't committed to git, so they won't be reverted by the restore commit -- The auth commit must contain a reversible change in tracked files - -**Java example:** - -**Before:** -```java -public class BlobServiceClientProvider { - private static BlobServiceClient blobServiceClient; - - public static BlobServiceClient getClient() { - if (blobServiceClient == null) { - String endpoint = System.getenv("AZURE_STORAGE_ENDPOINT"); - blobServiceClient = new BlobServiceClientBuilder() - .endpoint(endpoint) - .credential(new DefaultAzureCredentialBuilder().build()) - .buildClient(); - } - return blobServiceClient; - } -} -``` - -**After:** -```java -public class BlobServiceClientProvider { - private static BlobServiceClient blobServiceClient; - - public static BlobServiceClient getClient() { - if (blobServiceClient == null) { - // Hardcoded connection string for smoke testing with Azurite emulator - String smokeTestConnectionString = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://localhost:10000/devstoreaccount1;"; - - if (smokeTestConnectionString != null && !smokeTestConnectionString.isEmpty()) { - blobServiceClient = new BlobServiceClientBuilder() - .connectionString(smokeTestConnectionString) - .buildClient(); - } else { - // Fallback to original Managed Identity auth - String endpoint = System.getenv("AZURE_STORAGE_ENDPOINT"); - blobServiceClient = new BlobServiceClientBuilder() - .endpoint(endpoint) - .credential(new DefaultAzureCredentialBuilder().build()) - .buildClient(); - } - } - return blobServiceClient; - } -} -``` - -**CRITICAL:** Only the source code changes are included in the auth commit. No config file changes because there are no config files. - -### Non-Emulatable Services - -**Strategy:** Disable via config or conditional guards: - -**Spring Boot example:** -```yaml -# application-smoke.yml -spring: - cloud: - azure: - keyvault: - secret: - enabled: false -``` - -If the app cannot start without the service, recommend Layer 3 (Azure integration tests). - -## Emulator Connection String Values - -Since `docker-compose.smoke.yml` uses **fixed host port mappings**, each emulator's connection string is a **static constant** — deterministic at generation time. - -| Service | Auth Type | How to Determine the Value | -|---------|-----------|----------------------------| -| Azurite (Blob/Queue/Table) | Connection string | Built from well-known account `devstoreaccount1`, well-known key, and mapped ports (10000/10001/10002). See [Azurite docs](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite#well-known-storage-account-and-key). | -| Service Bus | Connection string | Built from well-known SAS key + `UseDevelopmentEmulator=true`. See [Service Bus emulator docs](https://learn.microsoft.com/en-us/azure/service-bus-messaging/test-locally-with-service-bus-emulator). | -| Event Hubs | Connection string | Same pattern as Service Bus. See [Event Hubs emulator docs](https://learn.microsoft.com/en-us/azure/event-hubs/test-locally-with-event-hub-emulator). | -| Cosmos DB | Endpoint + key | Built from well-known emulator key + mapped port. See [Cosmos emulator docs](https://learn.microsoft.com/en-us/azure/cosmos-db/emulator). Also requires SSL trust store setup. | - -**Important:** The agent must look up the **actual current default credentials** from the linked official docs at generation time. Emulator defaults may change across versions. Do NOT hardcode connection strings from this file. - -## Decision Flow - -``` -For each Azure dependency: -├─ Has local emulator? → Add to docker-compose.smoke.yml → Modify auth to use emulator -├─ Lazy / on-demand? → Skip. Done. -├─ Can disable via config? → Disable in config override or code modification -└─ None of above → Report: "Layer 2 not feasible — use Layer 3" -``` - -## Modification Rules - -When modifying application code or config to use emulators: - -1. **Minimal changes only** — Only modify what's needed to switch auth from Managed Identity to emulator connection strings. Do not refactor, rename, or restructure. -2. **No new dependencies** — Use only packages already in the project. -3. **Reversible** — Changes should be easily revertable to restore original Managed Identity auth. -4. **No unrelated changes** — Never make refactoring, cleanup, or feature changes alongside auth modifications. diff --git a/.github/skills/integration-tests/references/azure-servicebus-testcontainers.md b/.github/skills/integration-tests/references/azure-servicebus-testcontainers.md deleted file mode 100644 index 50b596322..000000000 --- a/.github/skills/integration-tests/references/azure-servicebus-testcontainers.md +++ /dev/null @@ -1,688 +0,0 @@ -# Azure Service Bus Emulator TestContainers Coding Reference - -## Contents -- 1. MANDATORY - Choose Approach based on Spring/non-Spring, Spring Boot version, TestContainers version -- 2. MANDATORY - Scan all queues/topics/subscriptions before writing code -- 3. DO NOT mock -- 4. Example of Service Bus Emulator config.json -- 5. Spring Cloud Azure Version Compatibility -- 6. Emulator with ServiceBusEmulatorContainer (testcontainers >= 1.20.5) - + Setting up a network - + Starting a SQL Server container as dependency - + Starting a Service Bus Emulator container - + Using Azure Service Bus clients -- 7. Emulator with GenericContainer (testcontainers < 1.20.5) -- 8. Using Spring Cloud Azure with @ServiceConnection (Spring Boot >= 3.1) - + Container setup with @ServiceConnection - + Spring messaging pattern (ServiceBusTemplate / ServiceBusSenderClient) -- 9. Spring Boot 2.x Pattern -- 10. Handle ServiceBusAdministrationClient -- 11. Emulator Readiness and Retry -- 12. Emulator fails to start -- 13. Common Gotchas - -## MANDATORY - Choose Approach based on Spring/non-Spring, Spring Boot version, TestContainers version - -**You MUST check the project's testcontainers and Spring Boot versions BEFORE writing any Service Bus test code.** Using the wrong approach wastes significant time on compilation and runtime failures that are impossible to fix. - -- If project contains usage of `ServiceBusAdministrationClient`, use Service Bus emulator -- If Spring Boot **>= 3.1**, use `@ServiceConnection` for auto-wiring: [Using Spring Cloud Azure with @ServiceConnection](#using-spring-cloud-azure-with-serviceconnection-spring-boot--31) -- If Spring Boot **2.x**, use `@DynamicPropertySource` — `@ServiceConnection` is NOT available: [Spring Boot 2.x pattern](#spring-boot-2x-pattern) -- If testcontainers **>= 1.20.5**, use `ServiceBusEmulatorContainer` from `org.testcontainers:azure`: [Emulator with ServiceBusEmulatorContainer](#emulator-with-servicebusemulatorcontainer-testcontainers--1205) -- If testcontainers **< 1.20.5**, use `GenericContainer` with the emulator Docker image: [Emulator with GenericContainer](#emulator-with-genericcontainer-testcontainers--1205) - -**CRITICAL: `ServiceBusEmulatorContainer` does NOT exist in testcontainers before 1.20.5.** If you see `ClassNotFoundException` or `cannot find symbol: class ServiceBusEmulatorContainer`, the project's testcontainers version is too old. Switch to the GenericContainer approach or upgrade testcontainers. The Maven artifact is `org.testcontainers:azure` (NOT `testcontainers-azure`). - -## MANDATORY - Scan all queues/topics/subscriptions before writing code -The Service Bus emulator cannot create Service Bus queues/topics/subscriptions on the fly, so every resource need to be declared in the config.json. So scan the project to see what queues/topics/subscriptions need to be declared. And then define them in config.json. - -## Do NOT mock -**NEVER MOCK** the `ServiceBusSenderClient`, `ServiceBusTemplate`, `ServiceBusReceiverClient`, `ServiceBusProcessorClient`, `TokenCredential`, `ServiceBusAdministrationClient`, or **ANY bean related to the migrated service.** - -## Example of Service Bus Emulator config.json -Place this file at `src/test/resources/config.json` (or `service-bus-config.json`): - -```json -{ - "UserConfig": { - "Namespaces": [ - { - "Name": "sbemulatorns", - "Queues": [ - { - "Name": "queue.1", - "Properties": { - "DeadLetteringOnMessageExpiration": false, - "DefaultMessageTimeToLive": "PT1H", - "DuplicateDetectionHistoryTimeWindow": "PT20S", - "ForwardDeadLetteredMessagesTo": "", - "ForwardTo": "", - "LockDuration": "PT1M", - "MaxDeliveryCount": 3, - "RequiresDuplicateDetection": false, - "RequiresSession": false - } - } - ], - - "Topics": [ - { - "Name": "topic.1", - "Properties": { - "DefaultMessageTimeToLive": "PT1H", - "DuplicateDetectionHistoryTimeWindow": "PT20S", - "RequiresDuplicateDetection": false - }, - "Subscriptions": [ - { - "Name": "subscription.1", - "Properties": { - "DeadLetteringOnMessageExpiration": false, - "DefaultMessageTimeToLive": "PT1H", - "LockDuration": "PT1M", - "MaxDeliveryCount": 3, - "ForwardDeadLetteredMessagesTo": "", - "ForwardTo": "", - "RequiresSession": false - }, - "Rules": [ - { - "Name": "app-prop-filter-1", - "Properties": { - "FilterType": "Correlation", - "CorrelationFilter": { - "ContentType": "application/text", - "CorrelationId": "id1", - "Label": "subject1", - "MessageId": "msgid1", - "ReplyTo": "someQueue", - "ReplyToSessionId": "sessionId", - "SessionId": "session1", - "To": "xyz" - } - } - } - ] - }, - { - "Name": "subscription.2", - "Properties": { - "DeadLetteringOnMessageExpiration": false, - "DefaultMessageTimeToLive": "PT1H", - "LockDuration": "PT1M", - "MaxDeliveryCount": 3, - "ForwardDeadLetteredMessagesTo": "", - "ForwardTo": "", - "RequiresSession": false - }, - "Rules": [ - { - "Name": "user-prop-filter-1", - "Properties": { - "FilterType": "Correlation", - "CorrelationFilter": { - "Properties": { - "prop1": "value1" - } - } - } - } - ] - }, - { - "Name": "subscription.3", - "Properties": { - "DeadLetteringOnMessageExpiration": false, - "DefaultMessageTimeToLive": "PT1H", - "LockDuration": "PT1M", - "MaxDeliveryCount": 3, - "ForwardDeadLetteredMessagesTo": "", - "ForwardTo": "", - "RequiresSession": false - } - }, - { - "Name": "subscription.4", - "Properties": { - "DeadLetteringOnMessageExpiration": false, - "DefaultMessageTimeToLive": "PT1H", - "LockDuration": "PT1M", - "MaxDeliveryCount": 3, - "ForwardDeadLetteredMessagesTo": "", - "ForwardTo": "", - "RequiresSession": false - }, - "Rules": [ - { - "Name": "sql-filter-1", - "Properties": { - "FilterType": "Sql", - "SqlFilter": { - "SqlExpression": "sys.MessageId = '123456' AND userProp1 = 'value1'" - }, - "Action" : { - "SqlExpression": "SET sys.To = 'Entity'" - } - } - } - ] - } - ] - } - ] - } - ], - "Logging": { - "Type": "File" - } - } -} -``` - -## Spring Cloud Azure Version Compatibility - -Pick the Spring Cloud Azure version compatible with the project's Spring Boot version. See [aka.ms/spring/versions](https://aka.ms/spring/versions) for the compatibility matrix. - -| Spring Boot | Spring Cloud Azure | Notes | -|---|---|---| -| 2.x | 4.x | No `@ServiceConnection`, no `spring-cloud-azure-testcontainers`. Use `@DynamicPropertySource`. | -| 3.1.x - 3.5.x | 5.x | `@ServiceConnection` available | -| 4.0.x | 7.x | `@ServiceConnection` available | - -## Emulator with ServiceBusEmulatorContainer (testcontainers >= 1.20.5) - -**Requires: `org.testcontainers:azure` version >= 1.20.5** - -```xml -<dependency> - <groupId>org.testcontainers</groupId> - <artifactId>azure</artifactId> - <version>1.20.5</version><!-- or newer; class does NOT exist before 1.20.5 --> - <scope>test</scope> -</dependency> -<dependency> - <groupId>org.testcontainers</groupId> - <artifactId>mssqlserver</artifactId> - <scope>test</scope> -</dependency> -``` - -### Setting up a network - -```java -Network network = Network.newNetwork(); -``` - -### Starting a SQL Server container as dependency - -```java -MSSQLServerContainer<?> mssqlServerContainer = new MSSQLServerContainer<>( - "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04" -) - .acceptLicense() - .withPassword("yourStrong(!)Password") - .withCreateContainerCmdModifier(cmd -> { - cmd.getHostConfig().withCapAdd(Capability.SYS_PTRACE); - }) - .withNetwork(network); -``` - -### Starting a Service Bus Emulator container - -```java -ServiceBusEmulatorContainer emulator = new ServiceBusEmulatorContainer( - "mcr.microsoft.com/azure-messaging/servicebus-emulator:1.1.2" -) - .acceptLicense() - .withConfig(MountableFile.forClasspathResource("/service-bus-config.json")) - .withNetwork(network) - .withMsSqlServerContainer(mssqlServerContainer); -``` - -### Using Azure Service Bus clients - -```java -ServiceBusSenderClient senderClient = new ServiceBusClientBuilder() - .connectionString(emulator.getConnectionString()) - .sender() - .queueName("queue.1") - .buildClient(); - -ServiceBusProcessorClient processorClient = new ServiceBusClientBuilder() - .connectionString(emulator.getConnectionString()) - .processor() - .queueName("queue.1") - .processMessage(messageConsumer) - .processError(errorConsumer) - .buildProcessorClient(); -``` - -## Emulator with GenericContainer (testcontainers < 1.20.5) - -**Use this when the project's testcontainers version does not include `ServiceBusEmulatorContainer`.** This approach uses `GenericContainer` directly with the same emulator Docker image. - -```xml -<dependency> - <groupId>org.testcontainers</groupId> - <artifactId>testcontainers</artifactId> - <scope>test</scope> -</dependency> -<dependency> - <groupId>org.testcontainers</groupId> - <artifactId>junit-jupiter</artifactId> - <scope>test</scope> -</dependency> -<dependency> - <groupId>org.testcontainers</groupId> - <artifactId>mssqlserver</artifactId> - <scope>test</scope> -</dependency> -``` - -```java -@Testcontainers -@Tag("Layer1") -class ServiceBusEmulatorL1Test { - - static final Network NETWORK = Network.newNetwork(); - - @Container - static final MSSQLServerContainer<?> SQL_SERVER = new MSSQLServerContainer<>( - "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04") - .acceptLicense() - .withPassword("yourStrong(!)Password") - .withNetwork(NETWORK) - .withNetworkAliases("mssql"); - - @Container - static final GenericContainer<?> SERVICE_BUS = new GenericContainer<>( - "mcr.microsoft.com/azure-messaging/servicebus-emulator:1.1.2") - .withExposedPorts(5672) - .withNetwork(NETWORK) - .withEnv("ACCEPT_EULA", "Y") - .withEnv("MSSQL_SA_PASSWORD", "yourStrong(!)Password") - .withEnv("SQL_SERVER", "mssql") // network alias of the SQL Server container - .withCopyFileToContainer( - MountableFile.forClasspathResource("config.json"), - "/ServiceBus_Emulator/ConfigFiles/config.json") - .dependsOn(SQL_SERVER) - .waitingFor(Wait.forLogMessage(".*Emulator Service is Successfully Up!.*", 1) - .withStartupTimeout(Duration.ofMinutes(3))); - - static String getConnectionString() { - return String.format( - "Endpoint=sb://%s:%d;SharedAccessKeyName=RootManageSharedAccessKey;" - + "SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;", - SERVICE_BUS.getHost(), SERVICE_BUS.getMappedPort(5672)); - } - - private ServiceBusSenderClient senderClient; - private ServiceBusReceiverClient receiverClient; - - @BeforeAll - static void waitForEmulator() { - // Emulator needs extra time after port is ready for entities to initialize - // Use Awaitility — NEVER Thread.sleep() - Awaitility.await() - .atMost(Duration.ofSeconds(120)) - .pollInterval(Duration.ofSeconds(2)) - .until(() -> { - try { - ServiceBusSenderClient probe = new ServiceBusClientBuilder() - .connectionString(getConnectionString()) - .sender().queueName("queue.1").buildClient(); - probe.sendMessage(new ServiceBusMessage("probe")); - probe.close(); - return true; - } catch (Exception e) { - return false; - } - }); - } - - @BeforeEach - void setupClients() { - senderClient = new ServiceBusClientBuilder() - .connectionString(getConnectionString()) - .sender().queueName("queue.1").buildClient(); - receiverClient = new ServiceBusClientBuilder() - .connectionString(getConnectionString()) - .receiver().queueName("queue.1").buildClient(); - } - - @AfterEach - void closeClients() { - if (senderClient != null) senderClient.close(); - if (receiverClient != null) receiverClient.close(); - } -} -``` - -## Using Spring Cloud Azure with @ServiceConnection (Spring Boot >= 3.1) - -**Requires:** Spring Boot >= 3.1, `spring-cloud-azure-testcontainers`, testcontainers >= 1.20.5. - -`@ServiceConnection` is a Spring Boot 3.1+ feature. **Do NOT use this with Spring Boot 2.x — it will not compile.** For Spring Boot 2.x, see the [Spring Boot 2.x pattern](#spring-boot-2x-pattern) section. - -```xml -<properties> - <!-- Match this to your Spring Boot version per the table above --> - <version.spring.cloud.azure>5.25.0</version.spring.cloud.azure> -</properties> - -<dependencyManagement> - <dependencies> - <dependency> - <groupId>com.azure.spring</groupId> - <artifactId>spring-cloud-azure-dependencies</artifactId> - <version>${version.spring.cloud.azure}</version> - <type>pom</type> - <scope>import</scope> - </dependency> - </dependencies> -</dependencyManagement> - -<dependencies> - <!-- Use spring-messaging-azure-servicebus for ServiceBusTemplate/ServiceBusSenderClient --> - <dependency> - <groupId>com.azure.spring</groupId> - <artifactId>spring-messaging-azure-servicebus</artifactId> - </dependency> - <!-- OR use spring-cloud-azure-stream-binder-servicebus for Spring Cloud Stream Supplier/Consumer --> - <!-- - <dependency> - <groupId>com.azure.spring</groupId> - <artifactId>spring-cloud-azure-stream-binder-servicebus</artifactId> - </dependency> - --> - <dependency> - <groupId>com.azure.spring</groupId> - <artifactId>spring-cloud-azure-starter</artifactId> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-test</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-testcontainers</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.testcontainers</groupId> - <artifactId>junit-jupiter</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.azure.spring</groupId> - <artifactId>spring-cloud-azure-testcontainers</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.microsoft.sqlserver</groupId> - <artifactId>mssql-jdbc</artifactId> - <scope>test</scope> - </dependency> -</dependencies> -``` - -### Container setup with @ServiceConnection - -`@ServiceConnection` tells Spring Boot to auto-configure `AzureServiceBusConnectionDetails` from the running container — no manual connection string wiring needed. The `MSSQLServerContainer` is NOT annotated with `@Container` because `ServiceBusEmulatorContainer.withMsSqlServerContainer()` manages its lifecycle. - -```java -private static final Network NETWORK = Network.newNetwork(); - -private static final MSSQLServerContainer<?> SQLSERVER = new MSSQLServerContainer<>( - "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04") - .acceptLicense() - .withNetwork(NETWORK) - .withNetworkAliases("sqlserver"); - -@Container -@ServiceConnection -private static final ServiceBusEmulatorContainer SERVICE_BUS = new ServiceBusEmulatorContainer( - "mcr.microsoft.com/azure-messaging/servicebus-emulator:latest") - .acceptLicense() - .withCopyFileToContainer(MountableFile.forClasspathResource("config.json"), - "/ServiceBus_Emulator/ConfigFiles/config.json") - .withNetwork(NETWORK) - .withMsSqlServerContainer(SQLSERVER); -``` - -### Spring messaging pattern (ServiceBusTemplate / ServiceBusSenderClient) - -Use when the application uses `ServiceBusSenderClient` or `ServiceBusTemplate` for sending, and `ServiceBusRecordMessageListener` for processing. - -```java -@SpringJUnitConfig -@TestPropertySource(properties = { - "spring.cloud.azure.servicebus.entity-name=queue.1", - "spring.cloud.azure.servicebus.entity-type=queue" -}) -@Testcontainers -@Tag("Layer1") -class ServiceBusMessagingL1Test { - - // ... container setup as above ... - - @Autowired - private ServiceBusSenderClient senderClient; - - @Autowired - private ServiceBusTemplate serviceBusTemplate; - - @Test - void senderClientCanSendAndReceiveMessage() { - // The emulator depends on SQL Server and needs time to initialize messaging entities - waitAtMost(Duration.ofSeconds(120)).pollInterval(Duration.ofSeconds(2)).untilAsserted(() -> { - senderClient.sendMessage(new ServiceBusMessage("Hello World!")); - }); - - waitAtMost(Duration.ofSeconds(30)).untilAsserted(() -> { - assertThat(Config.MESSAGES).contains("Hello World!"); - }); - } - - @Test - void serviceBusTemplateCanSendAndReceiveMessage() { - waitAtMost(Duration.ofSeconds(120)).pollInterval(Duration.ofSeconds(2)).untilAsserted(() -> { - serviceBusTemplate.sendAsync("queue.1", - MessageBuilder.withPayload("Hello from template!").build()) - .block(Duration.ofSeconds(10)); - }); - - waitAtMost(Duration.ofSeconds(30)).untilAsserted(() -> { - assertThat(Config.MESSAGES).contains("Hello from template!"); - }); - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration(classes = { - AzureGlobalPropertiesAutoConfiguration.class, - AzureServiceBusAutoConfiguration.class, - AzureServiceBusMessagingAutoConfiguration.class}) - static class Config { - - private static final Set<String> MESSAGES = ConcurrentHashMap.newKeySet(); - - @Bean - ServiceBusRecordMessageListener processMessage() { - return context -> MESSAGES.add(context.getMessage().getBody().toString()); - } - - @Bean - ServiceBusErrorHandler errorHandler() { - return (context) -> { }; - } - } -} -``` - -## Spring Boot 2.x Pattern - -**Spring Boot 2.x does NOT support `@ServiceConnection` or `spring-boot-testcontainers`.** Use `@DynamicPropertySource` to inject the emulator connection string into the Spring context. - -```java -@SpringBootTest -@ActiveProfiles("test") // MANDATORY -@Testcontainers -@Tag("Layer1") -class MessageServiceL1Test { - - static final Network NETWORK = Network.newNetwork(); - - @Container - static final MSSQLServerContainer<?> SQL_SERVER = new MSSQLServerContainer<>( - "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04") - .acceptLicense() - .withPassword("yourStrong(!)Password") - .withNetwork(NETWORK) - .withNetworkAliases("mssql"); - - @Container - static final GenericContainer<?> SERVICE_BUS = new GenericContainer<>( - "mcr.microsoft.com/azure-messaging/servicebus-emulator:1.1.2") - .withExposedPorts(5672) - .withNetwork(NETWORK) - .withEnv("ACCEPT_EULA", "Y") - .withEnv("MSSQL_SA_PASSWORD", "yourStrong(!)Password") - .withEnv("SQL_SERVER", "mssql") - .withCopyFileToContainer( - MountableFile.forClasspathResource("config.json"), - "/ServiceBus_Emulator/ConfigFiles/config.json") - .dependsOn(SQL_SERVER) - .waitingFor(Wait.forLogMessage(".*Emulator Service is Successfully Up!.*", 1) - .withStartupTimeout(Duration.ofMinutes(3))); - - // NO @MockBean — all beans wired from the real emulator - @DynamicPropertySource - static void serviceBusProperties(DynamicPropertyRegistry registry) { - String connectionString = String.format( - "Endpoint=sb://%s:%d;SharedAccessKeyName=RootManageSharedAccessKey;" - + "SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;", - SERVICE_BUS.getHost(), SERVICE_BUS.getMappedPort(5672)); - registry.add("spring.cloud.azure.servicebus.connection-string", () -> connectionString); - registry.add("spring.cloud.azure.servicebus.namespace", () -> "sbemulatorns"); - // Disable managed identity — use the emulator connection string instead - registry.add("spring.cloud.azure.credential.managed-identity-enabled", () -> "false"); - } - - @Autowired - private MessageService messageService; // The app's own service class - - @Test - void sendMessageThroughApplicationService() { - // ALWAYS test through the application's own classes, not the SDK directly - Awaitility.await() - .atMost(Duration.ofSeconds(120)) - .pollInterval(Duration.ofSeconds(2)) - .untilAsserted(() -> { - messageService.sendMessage("test-queue", "Hello from test!"); - }); - } -} -``` - -## Handle ServiceBusAdministrationClient - -**CRITICAL: The Service Bus emulator does NOT support the ServiceBusAdministrationClient REST API.** The emulator only exposes AMQP on port 5672 for messaging operations. The `ServiceBusAdministrationClient` uses HTTPS REST API (port 443) which the emulator does not provide. Any call to `adminClient.getTopic()`, `adminClient.createSubscription()`, etc. will fail with `Connection refused: localhost:443`. - -### When the Application Uses ServiceBusAdministrationClient - -If the application has beans that use `ServiceBusAdministrationClient`, you MUST: -1. Use a test configuration that doesn't include the admin client. -2. **Include ALL dependent beans** - if `TopicProperties mainExchangeTopic` depends on `adminClient`, you must exclude BOTH -3. **Pre-create topics/queues/subscriptions in config.json** instead of relying on admin API calls - -### Complete Test Configuration Example - -When the application has code like this: - -```java -// Production code -@Bean -public ServiceBusAdministrationClient adminClient(AzureServiceBusProperties properties, TokenCredential credential) { - return new ServiceBusAdministrationClientBuilder() - .credential(properties.getFullyQualifiedNamespace(), credential) - .buildClient(); -} - -@Bean -public TopicProperties mainExchangeTopic(ServiceBusAdministrationClient adminClient) { - try { - return adminClient.getTopic(MAIN_EXCHANGE); // ← This FAILS against emulator! - } catch (ResourceNotFoundException e) { - return adminClient.createTopic(MAIN_EXCHANGE); - } -} -``` -**You MUST Exclude Admin Beans with @Profile:** - -```java -// Production code - mark with profile exclusion -@Bean -@Profile("!test") // Excluded in test profile -public ServiceBusAdministrationClient adminClient(AzureServiceBusProperties properties, TokenCredential credential) { - // ... -} - -@Bean -@Profile("!test") // Excluded in test profile -public TopicProperties mainExchangeTopic(ServiceBusAdministrationClient adminClient) { - // ... -} -``` - -**IMPORTANT:** Pre-create the topic in your `service-bus-config.json`: - -```json -{ - "UserConfig": { - "Namespaces": [{ - "Name": "sbemulatorns", - "Topics": [{ - "Name": "mainExchange", - "Subscriptions": [/* pre-create any needed subscriptions */] - }] - }] - } -} -``` - -## Emulator Readiness and Retry - -The Service Bus emulator takes significantly longer to start than Azurite because it depends on SQL Server initializing messaging entities. **Always use Awaitility retry/polling for initial send operations — never `Thread.sleep()`.** - -```java -// Typical total time from container start to first successful send: 60-120 seconds -waitAtMost(Duration.ofSeconds(120)) - .pollInterval(Duration.ofSeconds(2)) - .untilAsserted(() -> { - senderClient.sendMessage(new ServiceBusMessage("test")); - }); -``` - -## Emulator fails to start -If the emulator won't start (Docker not available, timeout, resource limits), **do NOT fall back to mocking.** Instead: -1. Increase the startup timeout (the emulator needs 60-120s) -2. Check Docker resources (emulator + SQL Server need ~4GB RAM) -3. Verify config.json is correctly mounted -4. Check the emulator logs for specific errors - -## Common Gotchas - -| Problem | Cause | Fix | -|---------|-------|-----| -| `ClassNotFoundException: ServiceBusEmulatorContainer` | testcontainers version < 1.20.5 | Upgrade to >= 1.20.5 OR use GenericContainer approach | -| `cannot find symbol: @ServiceConnection` | Spring Boot < 3.1 | Use `@DynamicPropertySource` instead (see Spring Boot 2.x pattern) | -| `UnsatisfiedDependencyException: TokenCredential` | Custom `@Configuration` creates Azure beans without correct emulator properties | Add `@ActiveProfiles("test")` AND provide emulator connection string via `@DynamicPropertySource` so all beans connect to the real emulator | -| `ServiceBusException: Entity not found` | Emulator entities not yet initialized | Use `waitAtMost` retry pattern with Awaitility | -| `Connection refused on port 5672` | SQL Server not ready when emulator starts | Use `dependsOn(SQL_SERVER)` + `waitingFor` log message strategy | -| `config.json not found` | Wrong mount path | Ensure `MountableFile.forClasspathResource("config.json")` matches file in `src/test/resources/` | -| Queue/topic name mismatch | config.json names don't match test properties | Verify `entity-name` matches config.json `Name` field | -| `No qualifying bean of type ServiceBusSenderClient` | Missing auto-configuration imports | Add `@ImportAutoConfiguration` with `AzureGlobalPropertiesAutoConfiguration`, `AzureServiceBusAutoConfiguration`, `AzureServiceBusMessagingAutoConfiguration` | -| `Checkpointer is null` | `auto-complete` not disabled | Set `spring.cloud.stream.servicebus.bindings.<fn>-in-0.consumer.auto-complete=false` | -| `InvalidDestinationException` on context start | Test context loads production JMS `@Configuration` that connects to fake endpoint | Add `@ActiveProfiles("test")` and provide correct emulator connection properties via `@DynamicPropertySource` | -| Tests hang during context startup | `@SpringBootTest` loads full context with real Azure/DB connections | Add `@ActiveProfiles("test")` and provide all emulator properties via `@DynamicPropertySource`, or narrow context with `classes = {...}` | diff --git a/.github/skills/integration-tests/references/azure-storage-testcontainers.md b/.github/skills/integration-tests/references/azure-storage-testcontainers.md deleted file mode 100644 index 4449ca75c..000000000 --- a/.github/skills/integration-tests/references/azure-storage-testcontainers.md +++ /dev/null @@ -1,276 +0,0 @@ -# Azure Blob Storage with Azurite TestContainers Coding Reference - -## Contents -- 1.Azurite-Specific Self-Checks -- 2.Azurite Container Setup - + Azurite well-known credentials -- 3.Azurite URL Format Gotcha -- 4.Spring Boot Config Override for Blob Storage - + ⚠️ CRITICAL: `System.getenv()` vs Spring Properties Mismatch -- 5. Shared Azurite Base Class -- 6. Azure Blob-Specific Test Patterns - + Testing Application Code (Not the SDK) - + Asserting on Behavior, Not Structure - + Error Handling with BlobStorageException - -## 1.Azurite-Specific Self-Checks -Before running tests, verify: -- [ ] If any application code reads config via `System.getenv()`, you've provided values through constructor injection or `@TestConfiguration` beans — NOT through `@DynamicPropertySource` (which only sets Spring properties) -- [ ] If the application parses URLs to extract container names, you've handled the Azurite URL format difference (see section 2) -- [ ] No test uses `DefaultAzureCredentialBuilder` — use `StorageSharedKeyCredential` with Azurite dev credentials -- [ ] No test checks for `blob.core.windows.net` in URLs — Azurite URLs use `localhost` -- [ ] `@ActiveProfiles("test")` is on every `@SpringBootTest` class (if using Spring Boot) -- [ ] `@BeforeEach` cleanup deletes all blob containers to prevent cross-test contamination - -## 2.Azurite Container Setup -```java -new GenericContainer<>("mcr.microsoft.com/azure-storage/azurite:latest") - .withExposedPorts(10000) - .withCommand("azurite-blob", "--blobHost", "0.0.0.0") - .waitingFor(Wait.forListeningPort()); // REQUIRED — prevents race conditions -``` - -### Azurite well-known credentials (safe for local testing only) -- Account name: `devstoreaccount1` -- Account key: `Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==` - -## 3.Azurite URL Format Gotcha -**IMPORTANT — Azurite URL format differs from production Azure Blob Storage:** - -- **Production Azure:** `https://<account>.blob.core.windows.net/<container>/<blob>` -- **Azurite:** `http://<host>:<port>/devstoreaccount1/<container>/<blob>` - -If the application code parses Azure Blob Storage URLs (e.g., extracting container name from the URL path), the Azurite URL will have an extra `/devstoreaccount1/` path segment that production URLs don't have. This causes: -- Container name extracted as `devstoreaccount1` instead of the actual container name -- URL-based detection logic (e.g., checking for `blob.core.windows.net`) failing for Azurite URLs -- Path indices being off-by-one when splitting URLs into segments - -**How to handle this — choose the approach that requires the LEAST production code change:** - -1. **Best approach — Inject the container name and BlobServiceClient separately** instead of having the application parse them from a URL: - ```java - // Add a test-friendly constructor that accepts pre-built client + container name - // Minimal source change: 3-4 lines - S3FileSystemStore(String rootPath, BlobServiceClient client, String containerName) { - this.blobServiceClient = client; - this.containerName = containerName; - this.rootPath = rootPath; - } - ``` - -2. **If the application detects Azure by checking for `blob.core.windows.net`** in the URL (common pattern), provide an override mechanism so tests can force Azure mode: - ```java - // Add a boolean flag or config property to bypass URL detection - S3FileSystemStore(String rootPath, FileSystem fs, BlobServiceClient client, boolean isAzure) { - this.blobServiceClient = client; - this.isAzureMode = isAzure; // skip blob.core.windows.net check - } - ``` -3. **If the application splits the URL path to extract container names**, the path indices will be different for Azurite vs Azure: - - Azure URL path: `/<container>/<blob>` -> `pathParts[1]` = container name - - Azurite URL path: `/devstoreaccount1/<container>/<blob>` -> `pathParts[1]` = `devstoreaccount1`, `pathParts[2]` = container name - - **Never assume Azurite URLs have the same path structure as production Azure URLs.** Instead, pass the container name as a parameter to avoid URL parsing entirely. - -**Self-check:** Before running tests, ask "Does any application code parse URLs to extract container names or detect Azure mode?" If yes, you MUST handle the Azurite URL format difference or 60%+ of tests will fail at runtime. - -## 4.Spring Boot Config Override for Blob Storage - -Production code often uses `DefaultAzureCredentialBuilder` which requires HTTPS and real Azure endpoints. Tests use local Azurite over HTTP with well-known keys. You **MUST** override the production bean configuration so the test context starts successfully. - -**Step 1 — ALWAYS add `@ActiveProfiles("test")` to every `@SpringBootTest` class:** -```java -@SpringBootTest -@ActiveProfiles("test") // MANDATORY — prevents production @Profile("!test") beans from loading -@Testcontainers -class MyServiceL1Test { ... } -``` -Without `@ActiveProfiles("test")`, production configuration classes (DataSource configs, credential builders, startup initializers) will load and fail because they try to connect to real services. This is the **#1 cause of Spring context startup failures** in integration tests. - -**Step 2 — use `@TestConfiguration` with `@Primary` to override production beans:** - -```java -@TestConfiguration -public class TestBlobStorageConfig { - // Override the production BlobServiceClient that uses DefaultAzureCredential - @Bean - @Primary - public BlobServiceClient blobServiceClient( - @Value("${azure.storage.endpoint}") String endpoint) { - // Azurite well-known credentials — safe for local testing only - StorageSharedKeyCredential credential = new StorageSharedKeyCredential( - "devstoreaccount1", - "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="); - return new BlobServiceClientBuilder() - .endpoint(endpoint) - .credential(credential) - .buildClient(); - } -} -``` - -**Step 3 — narrow the Spring context when full context is too heavy:** -If `@SpringBootTest` loads too many unrelated beans (startup initializers, schedulers, external integrations) that fail during context startup, use context slicing: -```java -@SpringBootTest(classes = {MyService.class, TestBlobStorageConfig.class}) -``` -This loads only the beans you need for testing, avoiding failures from unrelated components. - -### ⚠️ CRITICAL: `System.getenv()` vs Spring Properties Mismatch - -**`@DynamicPropertySource` sets Spring properties — it does NOT set environment variables.** If the application's DAO/service reads configuration via `System.getenv("AZURE_STORAGE_ENDPOINT")`, setting `registry.add("AZURE_STORAGE_ENDPOINT", ...)` in `@DynamicPropertySource` will NOT work. The DAO will receive `null` and fail with `NullPointerException` before any test runs. - -**How to detect this:** Before writing any test, `grep -r "System.getenv\|System.getProperty" src/main/` to find all environment variable reads in the application code. If you find any, you MUST use one of the approaches below. - -**Fix — choose the approach that requires the LEAST production code change:** - -1. **Best approach — Add a constructor that accepts the dependencies directly** (minimal safe source change, 3-5 lines): - ```java - // Add to the production DAO class: - AzureBlobDigitalMediaDAO(BlobServiceClient client, String containerName) { - this.blobServiceClient = client; - this.containerName = containerName; - } - ``` - Then in the test, provide the client via `@TestConfiguration` with `@Primary`: - ```java - @TestConfiguration - static class TestConfig { - @Bean @Primary - public AzureBlobDigitalMediaDAO testDao() { - return new AzureBlobDigitalMediaDAO(blobServiceClient, CONTAINER_NAME); - } - } - ``` - -2. **Alternative — Use `@TestConfiguration` `@Primary` bean + `@ConditionalOnMissingBean`** on the production config class so the test bean takes precedence. - -3. **Last resort — Set actual environment variables via `System.setProperty()` paired with changing production code from `System.getenv()` to `System.getProperty()`** (slightly larger source change but avoids constructor changes). - -**Anti-pattern — DO NOT DO THIS:** -```java -// WRONG: @DynamicPropertySource does NOT populate System.getenv() -@DynamicPropertySource -static void props(DynamicPropertyRegistry registry) { - registry.add("AZURE_STORAGE_ENDPOINT", () -> azuriteEndpoint); // ❌ DAO calls System.getenv(), not Spring -} -``` - -**Self-check:** For every `System.getenv()` call in the production code, verify your test provides the value through a mechanism the production code actually reads. `@DynamicPropertySource` only works for code that reads from Spring's `Environment` (e.g., `@Value`, `@ConfigurationProperties`). - -**Key rules:** -- ALWAYS add `@ActiveProfiles("test")` to every `@SpringBootTest` test class — this is the most common mistake. -- NEVER use `DefaultAzureCredentialBuilder` in tests — it will fail on HTTP endpoints and in CI. -- ALWAYS use `StorageSharedKeyCredential` with Azurite's well-known dev credentials for Blob Storage tests. -- Provide test properties via `@DynamicPropertySource` from the TestContainers container (e.g., `azuriteContainer.getHost()` + `azuriteContainer.getMappedPort(10000)`). -- If the full `@SpringBootTest` context fails to start, narrow it with `classes = {...}` rather than trying to mock/stub all failing beans. - -## 5.Shared Azurite Base Class - -When you have 2+ test classes using Azurite, extract the container declaration and client construction into a shared abstract base class: - -```java -// Shared base class — declared once, reused by all test classes -@Testcontainers -abstract class AbstractAzuriteL1Test { - @Container - static final GenericContainer<?> azurite = new GenericContainer<>( - "mcr.microsoft.com/azure-storage/azurite:latest") - .withExposedPorts(10000) - .withCommand("azurite-blob", "--blobHost", "0.0.0.0"); - - protected static BlobServiceClient blobServiceClient; - - @BeforeAll - static void initClient() { - String endpoint = String.format("http://%s:%d/devstoreaccount1", - azurite.getHost(), azurite.getMappedPort(10000)); - blobServiceClient = new BlobServiceClientBuilder() - .connectionString(getAzuriteConnectionString()) - .buildClient(); - } -} - -// Each test class extends the base — no duplicated container setup -@Tag("Layer1") -class EventHandlerL1Test extends AbstractAzuriteL1Test { ... } -class S3ClientUtilL1Test extends AbstractAzuriteL1Test { ... } -``` - -## 6.Azure Blob-Specific Test Patterns - -### Testing Application Code (Not the SDK) - -**Anti-pattern — DO NOT DO THIS:** -```java -// WRONG: Test calls Azure SDK directly instead of the application's CreateBucket class -@Test void testCreateBucketClass() { - // This tests the Azure SDK, NOT the application code - blobServiceClient.createBlobContainer("test-container"); - assertTrue(blobServiceClient.getBlobContainerClient("test-container").exists()); -} -``` - -**Anti-pattern — DO NOT DO THIS either:** -```java -// WRONG: Tests individual Azure Blob operations instead of the application's handler -@Test void testUploadBlob() { - BlobContainerClient container = blobServiceClient.getBlobContainerClient("test"); - container.create(); - container.getBlobClient("file.txt").upload(BinaryData.fromString("data"), true); - String content = container.getBlobClient("file.txt").downloadContent().toString(); - assertEquals("data", content); - // This verifies Azure SDK works — it does NOT test the application's EventHandler -} -``` - -**Correct pattern — invoke the application's own entry points:** -```java -// RIGHT: Test calls the application's own handler method end-to-end -@Test void testHandleRequestProcessesEventsEndToEnd() { - // Arrange — pre-populate Azurite with test event data - uploadTestEvent("container1", "event1.txt", "status:SHIPPED\ntimestamp:1573410202"); - - // Act — invoke the APPLICATION's handler, not the SDK - EventHandler handler = new EventHandler(blobServiceClient); - handler.handleRequest(mockContext); - - // Assert — verify the application produced the expected output - String summary = downloadBlob("summary-container", "summary.txt"); - assertThat(summary).contains("SHIPPED"); -} -``` - -### Asserting on Behavior, Not Structure - -**Every write test must read the data back and verify content.** If you write a blob to Azurite, download it and assert the content matches — do NOT just assert that the container exists (which is always true if you created it in `@BeforeEach`). A test whose only assertion is `assertTrue(container.exists())` or `assertNotNull(result)` is effectively testing nothing. - -### Error Handling with BlobStorageException - -```java -// RIGHT: Test error handling through the application class -@Test void testCreateBucketWithInvalidName() { - RuntimeException ex = assertThrows(RuntimeException.class, - () -> createBucket.createBucketAsync("INVALID-UPPERCASE")); - assertThat(ex.getMessage()).contains("Failed to create bucket"); - assertThat(ex.getCause()).isInstanceOf(BlobStorageException.class); -} -``` - -For each `catch (BlobStorageException e)` block in the migrated code, write a corresponding test: -```java -// If the source code has: -try { - blobClient.upload(data, true); -} catch (BlobStorageException e) { - throw new RuntimeException("Failed to create bucket", e); -} - -// Then you MUST have this test: -@Test void testCreateBucketWrapsStorageException() { - RuntimeException ex = assertThrows(RuntimeException.class, - () -> createBucket.createBucketAsync("INVALID")); - assertThat(ex.getMessage()).contains("Failed to create bucket"); - assertThat(ex.getCause()).isInstanceOf(BlobStorageException.class); -} -``` diff --git a/.github/skills/integration-tests/references/layer1-local-integration.md b/.github/skills/integration-tests/references/layer1-local-integration.md deleted file mode 100644 index 2b2d06262..000000000 --- a/.github/skills/integration-tests/references/layer1-local-integration.md +++ /dev/null @@ -1,358 +0,0 @@ -# Layer 1: Local Integration Tests - -## Contents -- Prerequisites (Docker & TestContainers available) -- Azure Authentication Strategies for Integration Tests Layer 1 (TokenCredential,Connection Strings, Keys) - + Emulatable Azure Services - + Emulator Connection String Values - + Modification Rules -- Principles - + 1. Core Principles (naming convention, no source code modification to fix TestContainers or Docker compatibility issues) - + 2. MOST IMPORTANT: Test application code, not the SDK - + 3. Make untestable code testable with minimal, safe source changes - + 4. Wire and test the full execution path - + 5. Assert on behavior, not structure - + 6. Only set up what the test uses - + 7. Test edge cases - + 8. Cover downstream consumers - + 9. Only label tests as integration tests if they integrate external systems - + 10. Stay scoped to the migration target - + 11. DO NOT use any test ordering mechanism - + 12. DO NOT use reflection to access or modify private fields,DO NOT widen field visibility - + 13. DO write specific, descriptive assertions - + 14. DO structure every test with clear Arrange-Act-Assert (AAA) sections - + 15. DO add `@BeforeEach` cleanup when tests share a container - + 16. DO verify the test count after `mvn verify` matches expectations - + 17. DO extract shared test infrastructure into a base class or helper when you have 2+ test classes - + 18. DO extract commonly repeated test patterns into helper methods - + 19. DO NOT leave `System.out.println` or debug logging statements in test code - + 20. NEVER use `Thread.sleep()` to wait for containers to start - -## Prerequisites - -- Docker installed and running -- TestContainers library available for the project's language - -## Azure Authentication Strategies for Integration Tests Layer 1 - -Migrated applications typically use **Microsoft Entra ID OAuth** such as **Managed Identity** (`DefaultAzureCredential`) which only works on Azure infrastructure. For local integration testing applications must connect to local emulators. - -### Emulatable Azure Services - -These services have official emulators that can run in Docker containers: - -| Azure Service | Emulator Image | Dependencies | -|---------------|----------------|--------------| -| Blob / Queue / Table Storage | `mcr.microsoft.com/azure-storage/azurite` | None | -| Cosmos DB | `mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator` | None (but requires SSL trust store + endpoint/key auth) | -| SQL Database | `mcr.microsoft.com/mssql/server` | None (wire-compatible with SQL Server) | -| Service Bus | `mcr.microsoft.com/azure-messaging/servicebus-emulator` | Requires MSSQL companion + JSON config | -| Event Hubs | `mcr.microsoft.com/azure-messaging/eventhubs-emulator` | Requires Azurite companion + JSON config | - -> **Note:** Service Bus and Event Hubs emulators require companion containers and a JSON config file. See [azure-servicebus-testcontainers.md](references/azure-servicebus-testcontainers.md) for the config format. - -**Cosmos DB emulator note:** Unlike other emulators which use connection strings, the Cosmos DB emulator authenticates via **endpoint + account key** and requires an **SSL certificate** imported into a trust store (e.g., `javax.net.ssl.trustStore` for Java). If SSL setup is too complex, treat Cosmos DB as non-emulatable and recommend Layer 3. - -### Authentication Modification Strategies (TokenCredential,Connection Strings, Keys) - -For each emulatable Azure dependency, modify how the application authenticates: - -#### Config-Driven Applications - -**Examples:** Spring Boot applications with `application.properties` or `application.yml`, Quarkus/Micronaut applications with `application.properties`. - -**Strategy:** Inject the connection string via test configurations, like property source. - -**CRITICAL:** You MUST always modify the config file to add the explicit connection string value. Do NOT rely on environment variables. - -#### Hardcoded/Plain Applications - -**Examples:** Plain Java CLI apps without config frameworks - -**When to use:** Applications that have NO configuration framework (no Spring Boot, no application.properties). These apps construct clients directly in code with hardcoded values. - -**Strategy:** Modify the source code to extend the client constructor which accepts hardcode emulator connection strings. Since these applications don't have config files to modify, the connection string must be in the source code itself to be committed to git. - -**Java example:** - -**Before:** -```java -public class BlobServiceClientProvider { - private static BlobServiceClient blobServiceClient; - - public static BlobServiceClient getClient() { - if (blobServiceClient == null) { - String endpoint = System.getenv("AZURE_STORAGE_ENDPOINT"); - blobServiceClient = new BlobServiceClientBuilder() - .endpoint(endpoint) - .credential(new DefaultAzureCredentialBuilder().build()) - .buildClient(); - } - return blobServiceClient; - } -} -``` - -**After:** -```java -public class BlobServiceClientProvider { - private static BlobServiceClient blobServiceClient; - - public static BlobServiceClient getClient() { - if (blobServiceClient == null) { - String endpoint = System.getenv("AZURE_STORAGE_ENDPOINT"); - blobServiceClient = new BlobServiceClientBuilder() - .endpoint(endpoint) - .credential(new DefaultAzureCredentialBuilder().build()) - .buildClient(); - } - return blobServiceClient; - } - - public static BlobServiceClient getClient(String connectionString) { - if (blobServiceClient == null) { - blobServiceClient = new BlobServiceClientBuilder() - .connectionString(testConnectionString) - .buildClient(); - } - return blobServiceClient; - } -} -``` - -### Emulator Connection String Values - -Each emulator's connection string is built from **well-known credentials** that are consistent across all emulator instances. - -| Service | Auth Type | How to Determine the Value | -|---------|-----------|----------------------------| -| Azurite (Blob/Queue/Table) | Connection string | Built from well-known account `devstoreaccount1`, well-known key, and mapped ports (10000/10001/10002). See [Azurite docs](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite#well-known-storage-account-and-key). | -| Service Bus | Connection string | Built from well-known SAS key + `UseDevelopmentEmulator=true`. See [Service Bus emulator docs](https://learn.microsoft.com/en-us/azure/service-bus-messaging/test-locally-with-service-bus-emulator). | -| Event Hubs | Connection string | Same pattern as Service Bus. See [Event Hubs emulator docs](https://learn.microsoft.com/en-us/azure/event-hubs/test-locally-with-event-hub-emulator). | -| Cosmos DB | Endpoint + key | Built from well-known emulator key + mapped port. See [Cosmos emulator docs](https://learn.microsoft.com/en-us/azure/cosmos-db/emulator). Also requires SSL trust store setup. | - -**Important:** The agent must look up the **actual current default credentials** from the linked official docs at generation time. Emulator defaults may change across versions. Do NOT hardcode connection strings from this file. - -### Modification Rules - -When modifying application code or config to use emulators: - -1. **Minimal changes only** — Only modify what's needed to switch auth from Managed Identity to emulator connection strings. Do not refactor, rename, or restructure. -2. **No new dependencies** — Use only packages already in the project. -3. **Reversible** — Changes should be easily revertable to restore original Managed Identity auth. -4. **No unrelated changes** — Never make refactoring, cleanup, or feature changes alongside auth modifications. - -## Principles - -### Core Principles - -1. **DO integration tests** to verify that different components interact correctly, focusing on data exchange and interface connections. -2. **DO write** comprehensive integration tests using containers to simulate all migrated dependencies, **especially Azure services**. -6. **NEVER modify application source code** to fix TestContainers or Docker compatibility issues. -8. **DO use `*L1Test.java`** as the class name suffix for Layer 1 test classes. This matches Maven Surefire's default `*Test.java` pattern - -### MOST IMPORTANT: Test application code, not the SDK - -Always instantiate and invoke the project's own classes/methods. Never call third-party library APIs directly in the test as a substitute for testing the application. If the application has a service class with methods like `handleRequest()`, `processData()`, or `createBucket()`, your tests MUST call those methods. - **Anti-pattern — DO NOT DO THIS:** - ```java - // WRONG: Test calls SDK directly instead of the application's own class - @Test void testServiceMethod() { - // This tests the SDK, NOT the application code - sdkClient.doOperation("test-input"); - assertTrue(sdkClient.getResult("test-input").exists()); - } - ``` - - **Correct pattern — invoke the application's own entry points:** - ```java - // RIGHT: Test calls the application's own handler method end-to-end - @Test void testHandleRequestProcessesDataEndToEnd() { - // Arrange — pre-populate test data - setupTestData("container1", "data1.txt", "status:ACTIVE\ntimestamp:1573410202"); - - // Act — invoke the APPLICATION's handler, not the SDK - MyHandler handler = new MyHandler(sdkClient); - handler.handleRequest(mockContext); - - // Assert — verify the application produced the expected output - String result = readOutput("output-container", "result.txt"); - assertThat(result).contains("ACTIVE"); - } - ``` - **Never bypass the application class by re-implementing its logic with direct SDK calls.** - - > For Azure Blob Storage-specific examples (Azurite anti-patterns, `BlobServiceClient` injection, `EventHandler` testing), see [azure-storage-testcontainers.md](./azure-storage-testcontainers.md). - -### Make untestable code testable with minimal, safe source changes - -If production code cannot be invoked from a test, introduce the smallest possible change (e.g., adding a method, widening visibility, extracting a parameter) to enable it. Never alter existing behavior, signatures, or control flow. Never work around untestable code by re-implementing its logic in the test. - -### Wire and test the full execution path - -Tests must exercise the end-to-end flow from input through business logic to output, not individual layers (controller layer or database layer) in isolation. - -### Assert on behavior, not structure - -Verify correct values, side effects, and state transitions — not just that a result is non-null or non-empty, nor rely on string containment or format checks alone. **Every write test must read the data back and verify content.** A test whose only assertion is `assertTrue(result.exists())` or `assertNotNull(result)` is effectively testing nothing. - -### Only set up what the test uses - -Every configured property, container, or singleton in setUp must be exercised by the test. Remove dead setup. - -### Test error handling at the application level with precise assertions — this is MANDATORY, not optional. - - **Anti-pattern — DO NOT DO THIS:** - ```java - // WRONG: Only testing happy paths - @Test void testOperation() { sdkClient.doOperation("test"); /* only happy path */ } - ``` - - **Correct pattern:** - ```java - // RIGHT: Test error handling through the application class - @Test void testOperationWithInvalidInput() { - RuntimeException ex = assertThrows(RuntimeException.class, - () -> myService.processInput("INVALID-INPUT")); - assertThat(ex.getMessage()).contains("Failed to process"); - assertThat(ex.getCause()).isInstanceOf(SomeSDKException.class); - } - ``` - - **Correct pattern for JSON deserialization error (common with Redis/cache migrations):** - ```java - // RIGHT: Inject corrupted data directly into the store, then test the app's error path - @Test void testGetPersonWithCorruptedJson() { - // Arrange — write invalid JSON directly to Redis in the SAME namespace the app uses - redisCommands.set("personCache:badKey", "{not-valid-json!!}"); - - // Act & Assert — the app's getPerson() should catch JsonProcessingException and wrap it - RuntimeException ex = assertThrows(RuntimeException.class, - () -> cacheManager.getPerson("badKey")); - assertThat(ex.getMessage()).contains("Failed to deserialize"); - assertThat(ex.getCause()).isInstanceOf(JsonProcessingException.class); - } - ``` - **Note:** When testing deserialization errors, write corrupted data to the **same key namespace/prefix** that the application reads from. A common mistake is writing to namespace `stringCache:key` but reading from `personCache:key` — this just produces a cache miss (null), not a deserialization error. - - > For Azure Blob Storage-specific error handling patterns (e.g., `BlobStorageException` wrapping), see [azure-storage-testcontainers.md](./azure-storage-testcontainers.md#5-azure-blob-specific-test-patterns). - - #### Migration-Critical Error Scenarios Checklist - - The following error scenarios are the most commonly missed in migration integration tests. **You MUST check each row and write a test for every scenario that applies to your migration.** Skipping these is the #1 cause of low error handling scores. - - | # | Scenario | When it applies | What to test | Example assertion | - |---|----------|----------------|--------------|-------------------| - | 1 | **SDK exception wrapping** | App has `catch (SDKException e) { throw new ...}` | Trigger the SDK exception through the app's own method and verify the wrapper exception type, message, AND cause chain | `assertThat(ex.getCause()).isInstanceOf(SDKException.class)` | - | 2 | **Resource-not-found via app method** | App reads blobs, DB rows, cache keys that may not exist | Call the app's read method with a non-existent resource; assert on the specific return (null, empty Optional, 404) — not just "no exception" | `assertThat(dao.load(99999, "x")).isNull()` | - | 3 | **Inconsistent state between stores** | App uses 2+ stores (DB + blob, DB + cache) | Write metadata to one store but NOT the other, then call the app's read method — verify it handles the mismatch (exception, null, graceful fallback) | Insert DB row, don't upload blob -> `dao.load()` should throw/return-null | - | 4 | **Invalid/null input through app methods** | App has public methods accepting user-provided strings, IDs, names | Pass null, empty string, and boundary-length values through the app's own method; assert specific exception type or error response | `assertThrows(IllegalArgumentException.class, () -> svc.create(null))` | - | 5 | **Duplicate/conflict operations** | App creates named resources (containers, keys, DB records) | Create a resource, then try to create it again through the app method; verify the specific conflict behavior (exception type, idempotent success, or error code) | `assertThat(ex.getMessage()).contains("already exists")` | - | 6 | **Delete non-existent resource** | App has delete/remove methods | Call delete on a resource that doesn't exist; verify whether it throws, returns false, or is idempotent — **this often differs between AWS SDK and Azure SDK** | `assertThat(svc.delete("nonexistent")).isFalse()` | - | 7 | **Operations after close/shutdown** | App has lifecycle methods (close, shutdown, stopService) | Call close(), then attempt a normal operation; verify it throws the expected exception (NPE, IllegalStateException, etc.) | `svc.close(); assertThrows(IllegalStateException.class, () -> svc.read("key"))` | - | 8 | **Corrupted/invalid data in store** | App deserializes data from external store (JSON from Redis, parsed blob content) | Write corrupted/malformed data directly to the store, then call the app's read method; verify the deserialization error is properly handled | `redis.set("key", "{bad-json}"); assertThrows(RuntimeException.class, () -> mgr.get("key"))` | - - **Self-check:** Count your error test methods. If you have fewer than 3 error tests from the table above, you almost certainly have gaps. Go back and add more. - -### Cover downstream consumers - -If the migrated code produces output consumed by other components (config generators, report builders), test those consumers too. Verify output is consumable by the next component in the pipeline — write then read back through the real consumer API to confirm round-trip correctness. - -### Only label tests as integration tests if they integrate external systems - -Tests with no containers, network, or filesystem dependencies are unit tests, which is not within the IT scope. Do not generate them alongside integration tests. - -### Stay scoped to the migration target - -Only generate tests for code that uses the migrated service. Do not generate unrelated tests for general project utilities. - -### DO NOT use any test ordering mechanism — this is an AUTOMATIC QUALITY DEDUCTION - -This includes JUnit 5 `@Order` / `@TestMethodOrder`, TestNG `dependsOnMethods` / `priority`, and any other framework-specific ordering. Tests MUST be independent and run in any order. Each test must create its own data and clean up after itself. Test ordering indicates shared mutable state — a critical quality issue. Evaluators specifically check for `@Order` and `@TestMethodOrder` annotations and will deduct points for their presence. - - **Anti-pattern — DO NOT DO THIS:** - ```java - // WRONG: @Order creates test interdependence — automatic quality deduction - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - class MyL1Test { - @Test @Order(1) void testCreate() { ... } - @Test @Order(2) void testRead() { ... } // implicitly depends on testCreate - } - ``` - - **Correct pattern:** - ```java - // RIGHT: Each test is self-contained with its own setup - class MyL1Test { - @BeforeEach void cleanup() { /* clean all state */ } - @Test void testCreate() { /* creates its own data */ } - @Test void testRead() { /* creates its own data, then reads */ } - } - ``` -### DO NOT use reflection to access or modify private fields, and DO NOT widen field visibility (private->protected/public) in production code for test access. - -Both approaches are fragile and tightly couple tests to implementation details. Reflection breaks on Java 17+ with strong encapsulation. Widening visibility pollutes the production API and can cause compilation errors when test classes are in a different package (protected access requires same package or subclass). Instead: - - For singletons: add a package-private or test-visible constructor/factory method to the production class (minimal safe change). - - For environment variables: use `@DynamicPropertySource`, `System.setProperty()` with matching application code reads, constructor/setter injection, or `@TestConfiguration` beans. - - For configuration files: use `@TestPropertySource`, classpath-based overrides in `src/test/resources/`, or `@DynamicPropertySource`. - - For injecting test dependencies: use constructor injection, setter injection, or `@TestConfiguration` with `@Primary` beans. - - For inspecting internal state: add a package-private getter method or test the observable behavior (outputs, side effects) instead of reading internal fields. - -### DO write specific, descriptive assertions - - ```java - // WRONG — poor failure message: "expected: true but was: false" - assertTrue(containers.contains("my-container")); - assertTrue(ex.getCause() instanceof SomeException); - - // RIGHT — clear failure message showing actual values - assertThat(containers).contains("my-container"); - assertThat(ex.getCause()).isInstanceOf(SomeException.class); - assertThat(result.getName()).isEqualTo("expected-name"); // shows both values on failure - ``` - - Regardless of library, always assert on specific values — not just `assertNotNull(result)` or `assertTrue(success)`. Include `assertInstanceOf()` (JUnit 5.8+) instead of `assertTrue(x instanceof Y)` for better error messages. - -### DO structure every test with clear Arrange-Act-Assert (AAA) sections - separated by blank lines. Each test should verify ONE logical behavior. Do not combine multiple unrelated operations in a single test method. - -### DO add `@BeforeEach` cleanup when tests share a container - -If multiple tests use the same TestContainers instance (e.g., a shared Redis or Azurite container), each test must clean up its state in `@BeforeEach` or `@AfterEach` (e.g., flush Redis, delete all blob containers, truncate database tables). Stale data from one test must never affect another. Without cleanup, test execution order determines results — a critical reliability issue. - -### DO verify the test count after `mvn verify` matches expectations - -Before committing, run `mvn verify` and confirm the number of tests discovered and executed matches the number of test methods you wrote. If the count is lower, some tests are not being discovered — fix the build configuration. - -### DO extract shared test infrastructure into a base class or helper when you have 2+ test classes - -If multiple test classes use the same TestContainers setup (e.g., same Azurite/Redis/PostgreSQL container), extract the container declaration, connection string construction, and `@DynamicPropertySource` into a shared abstract base class (e.g., `AbstractAzuriteL1Test` or `AbstractRedisL1Test`). This eliminates duplication and ensures consistent infrastructure configuration. Each test class that needs the container simply extends the base class. - - > For an Azurite-specific shared base class example (`AbstractAzuriteL1Test`), see [azure-storage-testcontainers.md](./azure-storage-testcontainers.md#4-shared-azurite-base-class). - -### DO extract commonly repeated test patterns into helper methods - -If you find yourself writing the same 3+ lines more than twice (e.g., listing blob names, creating a user and getting the ID, uploading test data), extract it into a descriptive helper method. This improves readability and reduces maintenance burden. - -### DO NOT leave `System.out.println` or debug logging statements in test code - -Remove all diagnostic print statements (`System.out.println`, `System.err.println`, `e.printStackTrace()`) before committing. If you need to inspect state during development, use proper assertions instead. Debug output clutters test logs, makes failures harder to diagnose, and indicates incomplete cleanup. - -### NEVER use `Thread.sleep()` to wait for containers to start - -TestContainers' `.start()` already waits for exposed ports to be ready. If you need additional readiness checks, use `.waitingFor(Wait.forListeningPort())` or `.waitingFor(Wait.forLogMessage(...))` on the container definition. `Thread.sleep()` is a flakiness time bomb — too short on slow CI, too long on fast machines. - -**Anti-pattern — DO NOT DO THIS:** -```java -// WRONG: Arbitrary sleep after container start -container.start(); -Thread.sleep(2000); // flaky — may be too short or too long -``` - -**Correct pattern:** -```java -// RIGHT: Use TestContainers built-in wait strategy -static final GenericContainer<?> myContainer = new GenericContainer<>("image:latest") - .withExposedPorts(PORT) - .waitingFor(Wait.forListeningPort()); // Reliable readiness check -``` diff --git a/.github/skills/integration-tests/references/layer2-runner-script-templates.md b/.github/skills/integration-tests/references/layer2-runner-script-templates.md deleted file mode 100644 index 76b69ef0a..000000000 --- a/.github/skills/integration-tests/references/layer2-runner-script-templates.md +++ /dev/null @@ -1,287 +0,0 @@ -# Layer 2 Runner Script Templates - -## Script Role - -The runner script is a **test runner only**. It starts infrastructure, builds the app, runs smoke tests, and reports results. It does NOT manage git commits or handle test failures — that is the agent's responsibility. - -## When to Use - -- **Agent execution (during Layer 2 generation):** After creating the auth commit (Step 4), the agent executes this script to run smoke tests. If tests fail, the agent analyzes errors, applies fixes, and re-runs the script. -- **User execution (manual re-runs):** Users must checkout the auth commit first, then run the script to verify smoke tests still pass. - -## Placeholders to Replace - -When generating the scripts, replace these placeholders with project-specific values: - -- `<project-specific-build-command>`: The build command for the detected project type - - Maven: `mvn package -DskipTests` - - Gradle: `./gradlew build -x test` - - .NET: `dotnet build` - - npm: `npm run build` - -- `<project-specific-start-command>`: The command to start the application - - Maven (Spring Boot): `mvn spring-boot:run` or `java -jar target/*.jar` - - Gradle (Spring Boot): `./gradlew bootRun` or `java -jar build/libs/*.jar` - - .NET: `dotnet run` or `dotnet MyApp.dll` - - npm: `npm start` - -## Bash Template (run-layer2-tests.sh) - -**NOTE:** This script should be placed in `{modernization-work-folder}/integration-tests/`. The script navigates to the project root to execute commands. - -```bash -#!/bin/bash -set -e - -# --- Auto-generated Layer 2 smoke test runner --- -# Project: {ProjectName} ({Language}, {Framework}) -# Starts infrastructure, builds and runs the app, verifies it stays alive -# and responds to HTTP requests without fatal errors. -# -# Usage: -# bash {modernization-work-folder}/integration-tests/run-layer2-tests.sh -# -# Environment variable overrides (optional): -# APP_PORT - Application port (default: 8080) -# HEALTH_PATH - Health endpoint (default: /) - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" # Navigate to project root -COMPOSE_FILE="$PROJECT_ROOT/src/test/resources/docker-compose.smoke.yml" -APP_LOG="/tmp/app-smoke-$$.log" - -APP_PORT="${APP_PORT:-8080}" -APP_URL="http://localhost:$APP_PORT" -HEALTH_PATH="${HEALTH_PATH:-/health}" # Adjust to detected health endpoint -STARTUP_TIMEOUT=60 -STABILITY_WAIT=5 -CHECKS_PASSED=0 -CHECKS_FAILED=0 -APP_PID="" - -pass() { echo " ✅ $1"; CHECKS_PASSED=$((CHECKS_PASSED + 1)); } -fail() { echo " ❌ $1"; CHECKS_FAILED=$((CHECKS_FAILED + 1)); } - -cleanup() { - [ -n "$APP_PID" ] && kill $APP_PID 2>/dev/null || true - [ -n "$APP_PID" ] && wait $APP_PID 2>/dev/null || true - docker compose -f "$COMPOSE_FILE" down -v 2>/dev/null || true - rm -f "$APP_LOG" -} -trap cleanup EXIT - -cd "$PROJECT_ROOT" - -# --- Step 1: Verify Docker --- -docker info > /dev/null 2>&1 || { echo "ERROR: Docker is not running."; exit 1; } - -# --- Step 2: Start infrastructure --- -echo "Starting infrastructure..." -docker compose -f "$COMPOSE_FILE" up -d --wait - -# --- Step 3: Build --- -echo "Building application..." -<project-specific-build-command> - -# --- Step 4: Start application --- -echo "Starting application..." -<project-specific-start-command> > "$APP_LOG" 2>&1 & -APP_PID=$! - -# --- Step 5: Check — Process alive --- -sleep $STABILITY_WAIT -if kill -0 $APP_PID 2>/dev/null; then - pass "Process is alive (PID $APP_PID)" -else - fail "Process crashed on startup" - tail -20 "$APP_LOG" 2>/dev/null || true - exit 1 -fi - -# --- Step 6: Check — Health probe --- -HEALTH_STATUS="000" -for i in $(seq 1 $STARTUP_TIMEOUT); do - HEALTH_STATUS=$(curl -sf -o /dev/null -w "%{http_code}" "${APP_URL}${HEALTH_PATH}" 2>/dev/null || echo "000") - [ "$HEALTH_STATUS" != "000" ] && break - kill -0 $APP_PID 2>/dev/null || { fail "Process died during health probe"; break; } - sleep 1 -done -[[ "$HEALTH_STATUS" =~ ^[1234] ]] && pass "Health probe (HTTP $HEALTH_STATUS)" \ - || fail "Health probe failed (HTTP $HEALTH_STATUS)" - -# --- Step 7: Check — Clean startup logs --- -if grep -qiE "FATAL|panic|unhandled.exception|OutOfMemory|StackOverflow|segfault" "$APP_LOG" 2>/dev/null; then - fail "Fatal error patterns in startup logs" -else - pass "No fatal errors in startup logs" -fi - -# --- Summary --- -echo "" -echo "========================================" -echo "Results: $CHECKS_PASSED passed, $CHECKS_FAILED failed" -if [ $CHECKS_FAILED -gt 0 ]; then - echo "❌ Layer 2 smoke tests FAILED" - exit 1 -fi -echo "✅ Layer 2 smoke tests PASSED" -echo "========================================" -``` - -## PowerShell Template (run-layer2-tests.ps1) - -**NOTE:** This script should be placed in `{modernization-work-folder}/integration-tests/`. The script navigates to the project root to execute commands. - -```powershell -#Requires -Version 5.1 -$ErrorActionPreference = "Stop" - -# --- Auto-generated Layer 2 smoke test runner --- -# Project: {ProjectName} ({Language}, {Framework}) -# Starts infrastructure, builds and runs the app, verifies it stays alive -# and responds to HTTP requests without fatal errors. -# -# Usage: -# powershell {modernization-work-folder}/integration-tests/run-layer2-tests.ps1 -# -# Environment variable overrides (optional): -# APP_PORT - Application port (default: 8080) -# HEALTH_PATH - Health endpoint (default: /) - -$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path -$ProjectRoot = Resolve-Path (Join-Path $ScriptDir "..\..") # Navigate to project root -$ComposeFile = Join-Path $ProjectRoot "src\test\resources\docker-compose.smoke.yml" -$AppLog = Join-Path $env:TEMP "app-smoke-$PID.log" - -$AppPort = if ($env:APP_PORT) { $env:APP_PORT } else { 8080 } -$AppUrl = "http://localhost:$AppPort" -$HealthPath = if ($env:HEALTH_PATH) { $env:HEALTH_PATH } else { "/health" } -$StartupTimeout = 60 -$StabilityWait = 5 -$ChecksPassed = 0 -$ChecksFailed = 0 -$AppProcess = $null - -function Pass($message) { - Write-Host " ✅ $message" -ForegroundColor Green - $script:ChecksPassed++ -} - -function Fail($message) { - Write-Host " ❌ $message" -ForegroundColor Red - $script:ChecksFailed++ -} - -function Cleanup { - if ($AppProcess -and !$AppProcess.HasExited) { - Stop-Process -Id $AppProcess.Id -Force -ErrorAction SilentlyContinue - Wait-Process -Id $AppProcess.Id -ErrorAction SilentlyContinue - } - docker compose -f $ComposeFile down -v 2>$null - if (Test-Path $AppLog) { Remove-Item $AppLog -Force } -} - -# Register cleanup -try { - Set-Location $ProjectRoot - - # --- Step 1: Verify Docker --- - docker info >$null 2>&1 - if ($LASTEXITCODE -ne 0) { - Write-Host "ERROR: Docker is not running." -ForegroundColor Red - exit 1 - } - - # --- Step 2: Start infrastructure --- - Write-Host "Starting infrastructure..." - docker compose -f $ComposeFile up -d --wait - - # --- Step 3: Build --- - Write-Host "Building application..." - <project-specific-build-command> - - # --- Step 4: Start application --- - Write-Host "Starting application..." - $AppProcess = Start-Process -FilePath <project-specific-start-command> -RedirectStandardOutput $AppLog -RedirectStandardError $AppLog -PassThru -NoNewWindow - - # --- Step 5: Check — Process alive --- - Start-Sleep -Seconds $StabilityWait - if (!$AppProcess.HasExited) { - Pass "Process is alive (PID $($AppProcess.Id))" - } else { - Fail "Process crashed on startup" - if (Test-Path $AppLog) { Get-Content $AppLog -Tail 20 } - exit 1 - } - - # --- Step 6: Check — Health probe --- - $HealthStatus = "000" - for ($i = 1; $i -le $StartupTimeout; $i++) { - try { - $response = Invoke-WebRequest -Uri "$AppUrl$HealthPath" -UseBasicParsing -TimeoutSec 1 -ErrorAction SilentlyContinue - $HealthStatus = $response.StatusCode - break - } catch { - $HealthStatus = "000" - } - if ($AppProcess.HasExited) { - Fail "Process died during health probe" - break - } - Start-Sleep -Seconds 1 - } - if ($HealthStatus -match "^[1234]") { - Pass "Health probe (HTTP $HealthStatus)" - } else { - Fail "Health probe failed (HTTP $HealthStatus)" - } - - # --- Step 7: Check — Clean startup logs --- - if (Test-Path $AppLog) { - $logContent = Get-Content $AppLog -Raw - if ($logContent -match "(?i)(FATAL|panic|unhandled.?exception|OutOfMemory|StackOverflow|segfault)") { - Fail "Fatal error patterns in startup logs" - } else { - Pass "No fatal errors in startup logs" - } - } - - # --- Summary --- - Write-Host "" - Write-Host "========================================" - Write-Host "Results: $ChecksPassed passed, $ChecksFailed failed" - if ($ChecksFailed -gt 0) { - Write-Host "❌ Layer 2 smoke tests FAILED" -ForegroundColor Red - exit 1 - } - Write-Host "✅ Layer 2 smoke tests PASSED" -ForegroundColor Green - Write-Host "========================================" -} finally { - Cleanup -} -``` - -## Script Behavior - -### What the Script Does - -1. **Verify Docker** — Check if Docker is running -2. **Start infrastructure** — `docker compose up` with all dependencies -3. **Build application** — Run project-specific build command -4. **Start application** — Run in background, log to temp file -5. **Check: Process alive** — Verify process didn't crash (5s stability wait) -6. **Check: Health probe** — HTTP health check (60s timeout, any non-5xx = pass) -7. **Check: Clean logs** — Scan for fatal error patterns (FATAL, panic, OOM, etc.) -8. **Report results** — Print pass/fail summary -9. **Cleanup** — Kill app, docker down, remove temp log - -### Exit Codes - -- `0` — All checks passed -- `1` — One or more checks failed - -### Environment Variables (Optional) - -Users can override defaults: -- `APP_PORT` — Application port (default: 8080) -- `HEALTH_PATH` — Health endpoint path (default: /health) diff --git a/.github/skills/integration-tests/references/layer2-smoke-tests.md b/.github/skills/integration-tests/references/layer2-smoke-tests.md deleted file mode 100644 index f85215ee1..000000000 --- a/.github/skills/integration-tests/references/layer2-smoke-tests.md +++ /dev/null @@ -1,261 +0,0 @@ -# Layer 2: Smoke Tests - -**Goal:** "Does the whole application start and stay alive?" - -Verify the complete application boots successfully, reaches a healthy state, and produces no crash-level errors. Layer 2 does **NOT** test individual features, APIs, or business logic — that is Layer 1's responsibility. - -## What Layer 2 Is and Is Not - -| Layer 2 IS | Layer 2 IS NOT | -|------------|----------------| -| Verifying the process starts without crashing | Testing specific API endpoints or features | -| Checking a single health/readiness probe | Hitting every REST route or gRPC method | -| Scanning startup logs for fatal errors | Asserting on response payloads or data | -| Detecting missing configuration or broken DI | Exercising SDK integrations or components | -| Provisioning ALL infrastructure the app needs | Only setting up migrated-component containers | - -## No Test Classes Required - -Layer 2 does **NOT** generate test classes. The runner script (`run-layer2-tests.sh` / `run-layer2-tests.ps1`) **is** the test — it provisions infrastructure, starts the app, runs health checks via `curl` and shell built-ins, and reports pass/fail. No JUnit test code. - -**Layer 2 is independent of Layer 1.** Layer 1 tests only migrated components; Layer 2 must provision ALL application dependencies. - -## Prerequisites - -- Application builds successfully -- Docker installed and running - -## Azure Authentication for Smoke Tests - -Migrated applications typically use **Managed Identity** (`DefaultAzureCredential`) which only works on Azure infrastructure. For local smoke testing, you must modify the application to connect to local emulators instead. - -**See [azure-auth-strategies.md](./azure-auth-strategies.md) for:** -- How to classify Azure dependencies (Emulatable, Lazy, Non-emulatable) -- Emulator images and configuration -- Authentication modification strategies (config-driven vs code-driven apps) -- Emulator connection string values -- Decision flow for handling each dependency type - -**Summary:** For each Azure dependency, determine if it's emulatable (use local emulator), lazy (skip), or startup-required non-emulatable (disable via config or recommend Layer 3). - -## Workflow - -> **CRITICAL — Commit order matters.** Follow Steps 1–8 in exact order. The artifacts commit (Step 3) MUST come before the auth commit (Step 4). Do not combine them. Do not reorder them. - -The workflow produces **a multi-commit sequence** (exactly 3 commits): - -| # | Commit | Contains | -|---|--------|----------| -| 1 | `[layer-2] Add smoke test artifacts` | docker-compose.smoke.yml, runner scripts, AND any source code fixes needed for smoke tests to pass. **All fixes (infrastructure, runner scripts, source code) must be amended to this commit.** | -| 2 | `[smoke-test] Replace Managed Identity with emulator connection strings` | Config file changes (e.g., `application.properties`) with explicit emulator connection strings, and any necessary auth-related code changes. **Auth-related fixes must be amended to this commit.** | -| 3 | `[smoke-test] Restore Managed Identity auth` | Reverts **only commit 2** by SHA — restores original Managed Identity config | - -**CRITICAL — Amend strategy:** -- Fixes to docker-compose.smoke.yml → amend commit 1 -- Fixes to runner scripts → amend commit 1 -- Source code bugs discovered during testing (DI wiring, null refs, etc.) → **amend commit 1** -- Fixes to auth config files → amend commit 2 -- Fixes to auth-related code → amend commit 2 - -This ensures when users checkout commit 2 (auth) to run smoke tests locally, they have ALL fixes: commit 1 contains working artifacts AND all source code fixes, commit 2 contains working auth config. - -The agent executes the smoke test runner script (Step 7) after creating commit 2, and may need to amend commits 1 or 2 during retries. - -**Retry on failure:** If the runner script fails, the agent analyzes the output and attempts a fix: -- **Smoke-artifact failure** (wrong port in compose, bad docker-compose config, bad runner script) → **amend commit 1** with fixes and re-run Step 7 -- **Source-code failure** (broken DI wiring, null reference in initializer, missing config guard, startup crash from migrated code) → **amend commit 1** with fixes and re-run Step 7. Apply the **Handling Test Failures** guidance from the main skill file. -- **Auth-config failure** (wrong connection string in config file, missing config property, auth-related code issue) → **amend commit 2** with fixes and re-run Step 7 - -Max **3 retries** total (across all failure types). If the agent cannot diagnose the root cause or the fix would require architectural changes, stop and report. - -### Step 1: Analyze ALL Application Dependencies - -Scan the **entire** application to identify every external dependency required for startup: - -- Build files: `pom.xml`, `build.gradle`, `*.csproj`, `package.json` -- Config: `application.yml`, `application.properties`, `appsettings.json`, `.env` -- Source code: client initializations, `@Autowired`/`@Inject` services -- Existing Docker/compose files - -**For each Azure dependency, classify it** using the decision flow from [azure-auth-strategies.md](./azure-auth-strategies.md): -- **Emulatable** → Add emulator to docker-compose, will modify auth in Step 4 -- **Lazy** → Skip (doesn't block startup) -- **Non-emulatable** → Disable via config in Step 4, or recommend Layer 3 - -**For non-Azure dependencies:** - -| Category | Example | Action | -|----------|---------|--------| -| Standard databases | PostgreSQL, MySQL, MongoDB, Redis | Add to `docker-compose.smoke.yml` with standard image | -| Azure wire-compatible | Azure DB for PostgreSQL/MySQL, Azure Cache for Redis, Azure SQL | Use open-source image (`postgres:16`, `redis:7`, `mcr.microsoft.com/mssql/server`) | - -**Rules:** Include anything that crashes the app on startup. Skip lazy/on-demand dependencies. Reuse Docker images and ports from Layer 1 where applicable. If an existing `docker-compose.yml` already defines all needed services, prefer reusing it. - -### Step 2: Generate Docker Compose - -Create `docker-compose.smoke.yml` in the test resources directory. The file provisions ALL required dependencies. Every service must have a healthcheck. Include proper ports and volume mounts. - -**File location:** `src/test/resources/docker-compose.smoke.yml` - -### Step 3: Generate Runner Scripts and Commit Artifacts - -Generate `run-layer2-tests.sh` and `run-layer2-tests.ps1` (see Runner Script Template below). - -**File locations:** -- `{modernization-work-folder}/integration-tests/run-layer2-tests.sh` -- `{modernization-work-folder}/integration-tests/run-layer2-tests.ps1` - -Then commit all generated artifacts: - -``` -git add -A -git commit -m "[layer-2] Add smoke test artifacts" -``` - -This commit initially contains only generated files (docker-compose.smoke.yml, runner scripts). No source code changes yet. Files in `.github/` may be excluded if the project's `.gitignore` blocks them — this is acceptable. - -**CRITICAL:** If smoke tests fail during Step 7, amend this commit with ALL fixes: -``` -# After fixing docker-compose.smoke.yml, runner scripts, OR source code -git add -A -git commit --amend --no-edit -``` - -This includes source code bugs discovered during smoke testing. The commit message says "Add smoke test artifacts" but the commit will contain test infrastructure (docker-compose, runner scripts) AND source code fixes needed for tests to pass. This ensures users who checkout the auth commit (Step 4) will have all fixes via this commit in git history. - -### Step 4: Commit Auth Changes - -**CRITICAL:** This step is MANDATORY. You must ALWAYS create an auth commit that modifies config files. - -Modify the application configuration files (NOT environment variables) to use explicit emulator connection strings. See [azure-auth-strategies.md](./azure-auth-strategies.md) for: -- Which config files to modify (`application.properties`, `appsettings.json`, etc.) -- Emulator connection string formats -- Code modification patterns if needed - -Create the auth commit: - -```bash -git add -A -git commit -m "[smoke-test] Replace Managed Identity with emulator connection strings" -``` - -Record the commit SHA for Step 8. - -### Step 5: Verify Config File Changes - -**Do NOT modify runner scripts with environment variables.** The config files from Step 4 contain all necessary connection strings. - -Verify that the auth commit includes: -- All modified config files with explicit connection string values -- Any code changes if the app was hardcoded/plain application -- No environment variable exports or overrides - -The runner scripts will start the application as-is, and the app will read connection strings from the config files you just modified. - -### Step 6: Auto-Detect Application Type - -Analyze the project to determine how it starts and how to verify liveness: - -| Indicator | App Type | Start Command | Liveness Check | -|-----------|----------|---------------|----------------| -| Spring Boot, `@SpringBootApplication` | Java Web/API | `./mvnw spring-boot:run` or `java -jar` | HTTP health probe | -| `@Scheduled`, background jobs | Worker/Background | `./mvnw spring-boot:run` | Process stays alive for N seconds | -| `main()` with no server | CLI/Batch | `java -jar` | Process exits with code 0 | - -### Step 7: Execute Smoke Tests via Runner Script - -After creating the auth commit (Step 4) and detecting the application type (Step 6), execute the smoke test runner script: - -```bash -bash {modernization-work-folder}/integration-tests/run-layer2-tests.sh -# OR on Windows: -powershell {modernization-work-folder}/integration-tests/run-layer2-tests.ps1 -``` - -**The script will:** -1. Verify Docker is running -2. Start infrastructure (`docker compose up`) -3. Build the application -4. Start the application in background -5. Run three health checks: - - **Check 1:** Process is alive after stability wait (5s) - - **Check 2:** Health probe returns non-5xx HTTP response (web/API apps only) - - **Check 3:** No fatal error patterns in startup logs (FATAL, panic, OutOfMemory, etc.) -6. Report pass/fail and exit with appropriate code -7. Clean up (kill app, docker down) - -**If the script exits with code 0:** -- ✅ Tests passed -- Proceed to Step 8 (create restore commit) - -**If the script exits with non-zero:** -- ❌ Tests failed (likely auth-config issues) -- Analyze the script's output to determine root cause -- **Amend the auth commit (Step 5)** with fixes -- Re-run the script (max 3 retries total) - -**Important:** At this point, all source code fixes should already be done (Step 4). Failures here are typically auth configuration issues (wrong connection strings, missing config properties). - -**CRITICAL — Do NOT Create Test Classes:** -- Layer 2 does NOT use JUnit test classes -- The runner script IS the test - it uses shell commands (curl, grep, etc.) -- Do NOT create any `.java` test files for Layer 2 -- If you need to improve smoke testing, modify the runner scripts, not create test classes - -### Step 8: Create Restore Commit - -After smoke tests pass, create the restore commit to restore Managed Identity auth: - -```bash -git revert --no-edit <auth-commit-sha> -git commit --amend -m "[smoke-test] Restore Managed Identity auth" -``` - -This keeps the auth commit in history (visible in `git log`) while restoring the codebase to use Managed Identity. - -**CRITICAL:** All smoke test artifacts (docker-compose.smoke.yml, runner scripts) and source code fixes are in commit 1. Users can checkout the auth commit (commit 2) to run smoke tests locally and will have all necessary fixes via commit 1 in git history. - -## Handling Failures - -**CRITICAL:** All fixes must be amended to either commit 1 (smoke artifacts + source code) or commit 2 (auth config). Never create separate fix commits. - -Testing happens in Step 7 (after both commits 1 and 2 are created). When failures occur: - -| Failure | Likely Cause | Action | -|---------|-------------|--------| -| Infrastructure won't start | Port conflict, Docker issue, bad docker-compose config | **Amend commit 1** (fix docker-compose.smoke.yml) and re-run Step 7 | -| Build fails | Compile error in source code, missing dependencies | **Amend commit 1** (fix source code) and re-run Step 7. Apply Handling Test Failures guidance. | -| Process crashes immediately | Broken DI wiring, null ref, missing config guard, startup crash, OR wrong auth config | **Analyze stack trace** → amend commit 1 (source code bugs) or commit 2 (auth issues) and re-run Step 7 | -| Runner script fails | Wrong app start command, incorrect paths, bad classpath | **Amend commit 1** (fix runner scripts) and re-run Step 7 | -| Health probe times out | Wrong port in config, slow startup | **Amend commit 1** (fix runner script health check) and re-run Step 7 | -| Health probe returns 5xx | Internal error from missing config or code bug | **Analyze** → amend commit 1 (code) or commit 2 (auth) and re-run Step 7 | -| Fatal log patterns | Unhandled exceptions at startup | **Analyze stack trace** → amend commit 1 (source code) or commit 2 (auth config) if root cause is identifiable; otherwise report | -| Fatal log patterns | Unhandled exceptions at startup | **Analyze stack trace → fix** if root cause is identifiable; otherwise report | - -**Key principles:** -- Layer 2 fixes **both** its own generated artifacts **and** source-code issues it discovers. The goal is a passing smoke test, not just a report. -- Use the **Handling Test Failures** guidance from the main skill file to decide what to fix and how. -- Keep source-code fixes **minimal and targeted** — fix the specific startup blocker (e.g., null guard, missing config binding, broken DI registration). Do not refactor or change architecture. -- Max **3 retries** total. If the root cause is unclear, the fix would require architectural changes, or the app genuinely needs a real Azure service with no workaround, stop and report. - -## Standardized Runner Scripts - -Generate `run-layer2-tests.sh` and `run-layer2-tests.ps1` in `{modernization-work-folder}/integration-tests/`. These are test runners that start infrastructure, build the app, run smoke tests, and report results. - -**See [layer2-runner-script-templates.md](./layer2-runner-script-templates.md) for:** -- Complete bash and PowerShell script templates -- Placeholder replacement guide -- Script behavior and exit codes -- Environment variable overrides - -Users run: -- Unix: `bash {modernization-work-folder}/integration-tests/run-layer2-tests.sh` -- Windows: `powershell {modernization-work-folder}/integration-tests/run-layer2-tests.ps1` - -## Pass Criteria - -- All infrastructure containers reach healthy state -- Application builds and starts without crashing -- Health probe returns non-5xx (web/API apps) -- No fatal-level errors in startup logs -- Clean shutdown of app and infrastructure diff --git a/.github/skills/integration-tests/references/layer3-azure-integration.md b/.github/skills/integration-tests/references/layer3-azure-integration.md deleted file mode 100644 index df30130ef..000000000 --- a/.github/skills/integration-tests/references/layer3-azure-integration.md +++ /dev/null @@ -1,194 +0,0 @@ -# Layer 3: Azure Integration Tests - -**Goal:** "Does it work in real cloud environment?" - -Deploy to Azure staging environment and test against real Azure services. - -## Test Isolation - -- **DO use `L3Test` as the class name suffix** for all Layer 3 test classes (e.g., `AzureSqlL3Test`, `BlobStorageL3Test`). The `*Test` suffix matches Maven Surefire's default discovery pattern — no build plugin changes needed. -- **DO annotate every test class with a `Layer3` tag/category** so runner scripts filter precisely and never trigger Layer 1, 2, or 4 tests. See the Test Isolation Convention in the main skill file for the exact annotation per language/framework. -- The runner script **MUST filter by the `Layer3` tag** (e.g., `mvn verify -Dgroups=Layer3`, `dotnet test --filter Category=Layer3`, `pytest -m layer3`) - -## Prerequisites - -- Azure subscription with staging environment -- Azure CLI installed and authenticated -- Infrastructure-as-Code templates (Bicep/ARM/Terraform) - -## Workflow - -### 1. Identify Azure Services - -Map application dependencies to Azure services: - -| Local Dependency | Azure Service | Configuration Needed | -|-----------------|---------------|---------------------| -| SQL Server | Azure SQL Database | Connection string, firewall | -| PostgreSQL | Azure Database for PostgreSQL | Connection string, SSL | -| Redis | Azure Cache for Redis | Connection string, access key | -| File storage | Azure Blob Storage | Connection string, container | -| Message queue | Azure Service Bus | Connection string, queue | -| Key vault | Azure Key Vault | Managed identity, access policy | -| Logging | Application Insights | Instrumentation key | - -### 2. Deploy to Staging - -#### Using Azure CLI - -```bash -# Set variables -RESOURCE_GROUP="rg-app-staging" -LOCATION="eastus" -APP_NAME="app-integration-test-$(date +%s)" - -# Create resource group -az group create --name $RESOURCE_GROUP --location $LOCATION - -# Deploy infrastructure -az deployment group create \ - --resource-group $RESOURCE_GROUP \ - --template-file infra/main.bicep \ - --parameters environment=staging - -# Deploy application -az webapp deploy \ - --resource-group $RESOURCE_GROUP \ - --name $APP_NAME \ - --src-path ./publish.zip -``` - -#### Using GitHub Actions - -```yaml -- name: Deploy to Staging - uses: azure/webapps-deploy@v2 - with: - app-name: ${{ env.APP_NAME }} - slot-name: staging - package: ./publish.zip -``` - -### 3. Configure Azure Services - -```bash -# Get connection strings from deployed resources -SQL_CONN=$(az sql db show-connection-string \ - --server $SQL_SERVER \ - --name $DB_NAME \ - --client ado.net) - -REDIS_CONN=$(az redis list-keys \ - --resource-group $RESOURCE_GROUP \ - --name $REDIS_NAME \ - --query primaryKey -o tsv) - -STORAGE_CONN=$(az storage account show-connection-string \ - --resource-group $RESOURCE_GROUP \ - --name $STORAGE_NAME \ - --query connectionString -o tsv) - -# Update app settings -az webapp config appsettings set \ - --resource-group $RESOURCE_GROUP \ - --name $APP_NAME \ - --settings \ - "ConnectionStrings__Default=$SQL_CONN" \ - "Redis__ConnectionString=$REDIS_CONN" \ - "Storage__ConnectionString=$STORAGE_CONN" -``` - -### 4. Run Integration Tests Against Staging - -```bash -# Set test target to staging URL -export TEST_BASE_URL="https://$APP_NAME.azurewebsites.net" - -# Run Layer 3 integration tests only (filter by Layer3 tag) -dotnet test --filter Category=Layer3 -``` - -Test scenario areas for Azure (all tagged with `Layer3`): - -| Scenario Area | Tests | -|----------|-------| -| Database | CRUD operations, transactions, stored procedures | -| Storage | Blob upload/download, container operations | -| Cache | Get/set, expiration, distributed locks | -| Messaging | Send/receive, dead letter, retry | -| Identity | Authentication, authorization, managed identity | - -### 5. Validate Azure-Specific Features - -```csharp -[Trait("Category", "Layer3")] -public class AzureSqlL3Test -{ - [Fact] - public async Task CanConnectToAzureSql() - { - await using var conn = new SqlConnection(_connectionString); - await conn.OpenAsync(); - conn.State.Should().Be(ConnectionState.Open); - } - - [Fact] - public async Task TransactionWorksAcrossMultipleTables() - { - // Test Azure SQL transaction behavior - } -} - -[Trait("Category", "Layer3")] -public class AzureBlobL3Test -{ - [Fact] - public async Task CanUploadAndDownloadBlob() - { - var container = _blobClient.GetBlobContainerClient("test"); - await container.CreateIfNotExistsAsync(); - - var blob = container.GetBlobClient("test.txt"); - await blob.UploadAsync(new BinaryData("test content")); - - var downloaded = await blob.DownloadContentAsync(); - downloaded.Value.Content.ToString().Should().Be("test content"); - } -} -``` - -### 6. Collect Metrics and Logs - -```bash -# Get Application Insights logs -az monitor app-insights query \ - --app $APP_INSIGHTS_NAME \ - --analytics-query "traces | where timestamp > ago(1h) | order by timestamp desc | take 100" - -# Check for errors -az monitor app-insights query \ - --app $APP_INSIGHTS_NAME \ - --analytics-query "exceptions | where timestamp > ago(1h)" - -# Get performance metrics -az monitor metrics list \ - --resource $APP_RESOURCE_ID \ - --metric "Requests,AverageResponseTime,Http5xx" -``` - -### 7. Cleanup - -```bash -# Delete staging resources -az group delete --name $RESOURCE_GROUP --yes --no-wait -``` - -## Pass Criteria - -- Application deploys successfully to Azure -- All Azure service connections work -- Integration tests pass against real services -- No 5xx errors in Application Insights -- Performance is within acceptable thresholds -- Logs show no critical errors -- Runner scripts generated per the Standardized Runner Scripts convention in the main skill file diff --git a/.github/skills/integration-tests/references/layer4-behavioral-comparison.md b/.github/skills/integration-tests/references/layer4-behavioral-comparison.md deleted file mode 100644 index 0eceb1c71..000000000 --- a/.github/skills/integration-tests/references/layer4-behavioral-comparison.md +++ /dev/null @@ -1,242 +0,0 @@ -# Layer 4: Behavioral Comparison - -**Goal:** "Does it match the original?" - -Run old and new versions side-by-side and compare outputs for identical inputs. - -## Test Isolation - -- **DO use `L4Test` as the class name suffix** for all Layer 4 behavioral comparison test classes (e.g., `OrderApiL4Test`, `UserServiceL4Test`). The `*Test` suffix matches Maven Surefire's default discovery pattern — no build plugin changes needed. -- **DO annotate every test class with a `Layer4` tag/category** so runner scripts filter precisely and never trigger Layer 1, 2, or 3 tests. See the Test Isolation Convention in the main skill file for the exact annotation per language/framework. -- The runner script **MUST filter by the `Layer4` tag** (e.g., `mvn verify -Dgroups=Layer4`, `dotnet test --filter Category=Layer4`, `pytest -m layer4`) - -## Prerequisites - -- Access to both original and migrated application code -- Ability to run both versions simultaneously -- Test data/scenarios from production or comprehensive test suite - -## Workflow - -### 1. Set Up Side-by-Side Environment - -``` -┌─────────────────┐ ┌─────────────────┐ -│ Original App │ │ Migrated App │ -│ (Port 8080) │ │ (Port 8081) │ -└────────┬────────┘ └────────┬────────┘ - │ │ - └───────────┬───────────┘ - │ - ┌──────┴──────┐ - │ Comparator │ - │ Tests │ - └─────────────┘ -``` - -#### Docker Compose Setup - -```yaml -version: '3.8' -services: - original-app: - build: - context: ./original - ports: - - "8080:80" - environment: - - ConnectionStrings__Default=${DB_CONNECTION} - - migrated-app: - build: - context: ./migrated - ports: - - "8081:80" - environment: - - ConnectionStrings__Default=${DB_CONNECTION} - - # Shared database for consistent state - database: - image: mcr.microsoft.com/mssql/server:2022-latest - environment: - - ACCEPT_EULA=Y - - SA_PASSWORD=YourStrong!Passw0rd -``` - -### 2. Define Comparison Test Cases - -Identify all testable behaviors: - -| Category | Test Inputs | Comparison Points | -|----------|-------------|-------------------| -| API responses | Same HTTP requests | Status code, response body, headers | -| Data operations | Same CRUD operations | Database state, return values | -| Business logic | Same input parameters | Calculation results, decisions | -| Error handling | Invalid inputs | Error codes, messages | -| Edge cases | Boundary values | Behavior consistency | - -### 3. Create Comparison Test Framework - -```csharp -public class BehaviorComparisonTests -{ - private readonly HttpClient _originalClient; - private readonly HttpClient _migratedClient; - - public BehaviorComparisonTests() - { - _originalClient = new HttpClient { BaseAddress = new Uri("http://localhost:8080") }; - _migratedClient = new HttpClient { BaseAddress = new Uri("http://localhost:8081") }; - } - - [Theory] - [MemberData(nameof(GetTestCases))] - public async Task ResponsesMatch(TestCase testCase) - { - // Execute same request against both - var originalResponse = await ExecuteRequest(_originalClient, testCase); - var migratedResponse = await ExecuteRequest(_migratedClient, testCase); - - // Compare responses - var comparison = CompareResponses(originalResponse, migratedResponse); - - comparison.IsMatch.Should().BeTrue( - $"Mismatch in {testCase.Name}:\n{comparison.Differences}"); - } - - private ComparisonResult CompareResponses(Response original, Response migrated) - { - var differences = new List<string>(); - - // Compare status codes - if (original.StatusCode != migrated.StatusCode) - differences.Add($"Status: {original.StatusCode} vs {migrated.StatusCode}"); - - // Compare response bodies (with normalization) - var normalizedOriginal = NormalizeResponse(original.Body); - var normalizedMigrated = NormalizeResponse(migrated.Body); - - if (!JsonEquals(normalizedOriginal, normalizedMigrated)) - differences.Add($"Body differs:\nOriginal: {normalizedOriginal}\nMigrated: {normalizedMigrated}"); - - return new ComparisonResult - { - IsMatch = differences.Count == 0, - Differences = string.Join("\n", differences) - }; - } - - private string NormalizeResponse(string json) - { - // Remove fields that are expected to differ - var obj = JsonSerializer.Deserialize<JsonElement>(json); - return RemoveIgnoredFields(obj, new[] { "timestamp", "requestId", "version" }); - } -} -``` - -### 4. Handle Expected Differences - -Some differences are expected and should be ignored: - -| Field Type | Example | Handling | -|-----------|---------|----------| -| Timestamps | `createdAt`, `updatedAt` | Ignore or compare format only | -| IDs | `requestId`, `correlationId` | Ignore | -| Version info | `apiVersion`, `buildNumber` | Ignore | -| Order | Array element order | Sort before compare | -| Precision | Float/decimal precision | Round to acceptable precision | - -```csharp -public class ResponseNormalizer -{ - private readonly HashSet<string> _ignoredFields = new() - { - "timestamp", "createdAt", "updatedAt", - "requestId", "correlationId", "traceId", - "version", "buildNumber" - }; - - public JsonElement Normalize(JsonElement element) - { - // Remove ignored fields - // Sort arrays - // Normalize number precision - // etc. - } -} -``` - -### 5. Generate Comparison Report - -```markdown -# Behavioral Comparison Report - -## Summary -- Total test cases: 150 -- Matching: 147 (98%) -- Differences: 3 (2%) - -## Differences Found - -### Case: GET /api/orders/123 -| Field | Original | Migrated | -|-------|----------|----------| -| `items[0].price` | 19.99 | 19.990000 | - -**Analysis:** Floating point precision difference, acceptable. - -### Case: POST /api/users (duplicate email) -| Aspect | Original | Migrated | -|--------|----------|----------| -| Status | 400 | 409 | -| Message | "Email exists" | "Duplicate email" | - -**Analysis:** Different but semantically equivalent error handling. - -## Recommendations -1. Accept precision differences as expected -2. Review error message changes with stakeholders -3. All critical business logic matches ✓ -``` - -### 6. Run Comparison Suite - -```bash -# Start both applications -docker-compose up -d - -# Wait for both to be healthy -./wait-for-healthy.sh http://localhost:8080/health -./wait-for-healthy.sh http://localhost:8081/health - -# Run Layer 4 comparison tests only (filter by Layer4 tag) -dotnet test --filter Category=Layer4 - -# Generate report -dotnet test --logger "html;LogFileName=comparison-report.html" - -# Cleanup -docker-compose down -``` - -## Handling Database State - -For stateful comparisons, ensure both applications start with identical data: - -```bash -# Reset database before each test -docker-compose exec database /opt/mssql-tools/bin/sqlcmd \ - -S localhost -U sa -P 'YourStrong!Passw0rd' \ - -i /scripts/reset-test-data.sql -``` - -## Pass Criteria - -- All API responses match (after normalization) -- Database state changes are identical -- Business logic produces same results -- Error handling is semantically equivalent -- Performance is comparable (within 20% variance) -- No regressions in functionality -- Runner scripts generated per the Standardized Runner Scripts convention in the main skill file diff --git a/.github/skills/playbook-create/SKILL.md b/.github/skills/playbook-create/SKILL.md deleted file mode 100644 index 43f664b38..000000000 --- a/.github/skills/playbook-create/SKILL.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -name: playbook-create -description: Generate or update modernization playbook from document sources. Use this skill when the user wants to create a playbook, sync playbook from a document or GitHub issue, extract migration policies from architecture docs, or update existing playbook files with new decisions. ---- - -# Playbook Create - -Analyze source documents and generate a modernization playbook — three markdown files that capture an organization's modernization strategy, approved migration targets, and enforceable policies (standards + guardrails). - -## User Input - -- **output-path** (Required): The folder to save the playbook files. -- **source-file-path** (Optional): Path to the source file or directory containing the document content - -## Output Structure - -``` -${output-path}/ -├── charter.md # Scope, modernization strategy (6R), and principles -├── targets.md # Approved target technologies, library mappings, and target artifacts -└── policies.md # Standards + guardrails: naming, security, compliance, prohibited/required tech, validation gates -``` - -## Principles - -- **Source Fidelity**: The playbook is loaded and enforced by automated agents at runtime — a fabricated policy causes wrong migration decisions. Only include content explicitly present in the source document or user prompt. If a category isn't mentioned, omit that section entirely rather than adding placeholders. -- **Incremental Merge**: When output files already exist, merge at the **section level** — update sections with new or changed content, preserve unchanged sections verbatim. If the source explicitly removes or contradicts an existing entry, update that entry. Never drop existing content simply because the source is silent on it. -- **Direct Policy Output**: State policies as-is. Do not include rationale, explanations, or implementation guidance — those belong elsewhere (skills). - -## Classification Principles - -Each file serves a distinct purpose and is consumed at different stages of the modernization workflow: - -- **charter.md** — Playbook metadata (name, version), scope (covered applications, languages, constraints), modernization strategy (6R decision table with override conditions), and guiding principles. Loaded during assessment and plan creation to determine what to modernize and what strategy to apply. -- **targets.md** — Approved framework versions, compute/data/integration services, source-to-target library mappings, and target artifacts (container base images). Loaded during assessment (to define target services to assess against) and plan creation (to determine what tasks to generate). -- **policies.md** — Naming & metadata standards, security requirements, compliance requirements, guardrails (prohibited technologies/patterns, required elements, region constraints), validation & quality gates, and coding style guidelines. Loaded during assessment, plan creation, and execution to enforce standards and guardrails. - -## Workflow - -### Step 1: Read and Analyze Source - -1. If ${source-file-path} is provided, read the content (may be a GitHub issue export, markdown file, or a directory of files — if a directory, read all files recursively) -2. Check if output files already exist in ${output-path} — read them for merge comparison -3. Classify each decision from the source (and/or the user prompt) into one of the three output files using the Classification Guide above - -If no source file is provided, work with the user prompt and any existing playbook files only. - -### Step 2: Generate Playbook Files - -For each file, use the corresponding template as the structural reference, then fill in content extracted from the source. -Only include sections/subsections that have meaningful, source-backed content. Do not emit empty headings, empty tables, or placeholder-only sections. - -#### charter.md - -Use the template [charter-template](charter-template.md) as a section catalog: -- Metadata, Scope, Modernization Strategy (6R Guidelines), Principles - -#### targets.md - -Use the template [targets-template](targets-template.md) as a section catalog: -- Target Frameworks, Target Compute Services, Target Data Services, Target Integration Services, Target Libraries, Target Artifacts - -#### policies.md - -Use the template [policies-template](policies-template.md) as a section catalog: -- Naming & Metadata Standards, Security Requirements, Compliance Requirements, Guardrails (Hard Boundaries), Validation & Quality Gates, Coding Style Guidelines - -For each file: if it already exists, merge new content; if not, create it fresh. - -### Step 3: Validate - -Verify the output before finishing: -- [ ] All three files exist in ${output-path} -- [ ] Each file includes only sections with meaningful content from the source -- [ ] No empty headings, empty tables, or placeholder-only sections remain -- [ ] Every decision in the source document is reflected in at least one output file -- [ ] No content was invented beyond what the source provides - -### Step 4: Present Summary - -Report to the user: -- Number of target technologies defined -- Number of library migration mappings captured -- Number of prohibited technologies/patterns -- Number of required elements -- Number of validation/quality gates -- Sections omitted due to missing source content — flag these as gaps for architect review diff --git a/.github/skills/playbook-create/charter-template.md b/.github/skills/playbook-create/charter-template.md deleted file mode 100644 index 646e8a30c..000000000 --- a/.github/skills/playbook-create/charter-template.md +++ /dev/null @@ -1,30 +0,0 @@ -# Charter - -## Metadata - -| Field | Value | -|-------|-------| -| Playbook Name | | -| Version | | -| Changelog | | - -## Scope - -### Covered Applications and Languages - -### Application Types - -**Included:** - -**Excluded:** - -### Custom Libraries - -### Constraints - -## Modernization Strategy (6R Guidelines) - -| Application Type | Default Strategy | Override Conditions | -|------------------|-----------------|---------------------| - -## Principles diff --git a/.github/skills/playbook-create/policies-template.md b/.github/skills/playbook-create/policies-template.md deleted file mode 100644 index 04e844e48..000000000 --- a/.github/skills/playbook-create/policies-template.md +++ /dev/null @@ -1,72 +0,0 @@ -# Policies - -## Naming & Metadata Standards - -### Resource Naming Patterns - -| Resource Type | Pattern | Example | -|--------------|---------|---------| - -### Tagging Requirements - -| Tag | Required | Description | -|-----|----------|-------------| - -## Security Requirements - -### Authentication & Authorization - -### Secrets Management - -### Network Security - -### Encryption - -## Compliance Requirements - -### Applicable Frameworks - -| Framework | Key Constraints | -|-----------|----------------| - -### Data Classification - -## Guardrails (Hard Boundaries) - -### Prohibited Technologies - -| Technology | Reason | Approved Alternative | -|-----------|--------|---------------------| - -### Prohibited Patterns - -| Pattern | Reason | Approved Alternative | -|---------|--------|---------------------| - -### Required Elements - -Every modernized application must include: - -#### Cloud Resources - -#### Monitoring - -#### CI/CD - -#### Testing - -### Approved Regions / Residency Constraints - -## Validation & Quality Gates - -### Required Scanners/Tools - -### Pipeline Gates - -### Confidence Thresholds - -## Coding Style Guidelines - -### Coding Standards - -### Frontend Style Guidelines diff --git a/.github/skills/playbook-create/targets-template.md b/.github/skills/playbook-create/targets-template.md deleted file mode 100644 index 05334f689..000000000 --- a/.github/skills/playbook-create/targets-template.md +++ /dev/null @@ -1,31 +0,0 @@ -# Targets - -## Target Frameworks - -| Language | Target Version | Notes | -|----------|---------------|-------| - -## Target Compute Services - -| Platform | Use When | -|----------|----------| - -## Target Data Services - -| Service | Use When | -|---------|----------| - -## Target Integration Services - -| Service | Use When | -|---------|----------| - -## Target Libraries - -| Source | Target | Notes | -|--------|--------|-------| - -## Target Artifacts - -| Artifact | Location | Notes | -|----------|----------|-------| diff --git a/.github/skills/rearchitect/SKILL.md b/.github/skills/rearchitect/SKILL.md deleted file mode 100644 index 7a94508ec..000000000 --- a/.github/skills/rearchitect/SKILL.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -name: rearchitect -description: Scan project for Apache Struts and WinForms usage, report findings with modern alternatives ---- - -# Rearchitect — Legacy Framework Detection - -Scan the current project to detect outdated or unmaintained frameworks/technology stacks, report findings, and suggest modern alternatives. Save results via the `write_assessment_result` tool. - -## Input Parameters - -- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) - -## Execution Steps - -### Step 1: Determine Project Type - -Identify the project's technology stack by looking for marker files: - -| Marker File | Project Type | -|-------------|-------------| -| `pom.xml`, `build.gradle`, `build.gradle.kts` | Java/JVM | -| `*.csproj`, `*.sln`, `*.slnx` | .NET | -| `web.xml` | Java Web (Servlet) | - -### Step 2: Run Detection - -**Only** check the two targets listed below. Do **not** scan for or report any other frameworks, libraries, or dependencies beyond these two targets. - ---- - -#### Required Targets - -##### 1. Apache Struts - -**Configuration file detection:** -- `pom.xml` / `build.gradle` / `build.gradle.kts`: search for `org.apache.struts`, `struts2-core`, `struts-core`, `struts-taglib` -- `web.xml`: search for `org.apache.struts`, `StrutsPrepareAndExecuteFilter`, `ActionServlet` - -**Source code detection:** -- Java files: search for `import org.apache.struts`, `import com.opensymphony.xwork2` -- JSP files: search for `<%@ taglib.*struts`, `<s:` (Struts 2 tags) - -**Alternatives:** Spring Boot + Spring MVC, or Quarkus / Micronaut - -**Fixed explanation (use verbatim when detected):** -> Apache Struts has reached end-of-life and no longer receives security patches or bug fixes. It has a history of critical remote code execution vulnerabilities (e.g., CVE-2017-5638, CVE-2023-50164) that made it one of the most exploited frameworks in the Java ecosystem. Continued use exposes the application to known, unpatched attack vectors. Migration to a modern, actively maintained framework such as Spring Boot is strongly recommended to ensure ongoing security support and access to current Java platform features. - -##### 2. WinForms (Windows Forms) - -**Configuration file detection:** -- `.csproj`: search for `<UseWindowsForms>true</UseWindowsForms>`, `System.Windows.Forms`, `<OutputType>WinExe</OutputType>` (combined with WindowsForms references) - -**Source code detection:** -- C# files: search for `using System.Windows.Forms`, `: Form`, `: UserControl` (in System.Windows.Forms context) -- Presence of `.Designer.cs` files - -**Alternatives:** WPF, MAUI, Avalonia UI, or Blazor Desktop - -**Fixed explanation (use verbatim when detected):** -> Windows Forms (WinForms) is a legacy UI framework tied exclusively to Windows and .NET Framework. While it still receives minimal maintenance in .NET 8+, it lacks modern UI capabilities such as responsive layouts, high-DPI scaling, hardware-accelerated rendering, and cross-platform support. Its designer-centric, event-driven programming model makes it difficult to adopt modern patterns like MVVM or data binding. Migrating to WPF is recommended for richer user experiences, better maintainability, and modern UI patterns. - ---- - -### Step 3: Save Output - -Call the `write_assessment_result` tool with the following parameters: -- `resultJson`: the detection results as a JSON string -- `assessmentDir`: the value of the `assessment_dir` variable - -The JSON must strictly follow this format: - -```json -{ - "outdatedFrameworks": [ - { - "name": "Apache Struts 2", - "old": "struts2", - "new": "spring-boot", - "status": "end-of-life", - "detectedVersion": "2.5.30", - "migrationComplexity": "high", - "detectedIn": { - "configFiles": ["path/to/pom.xml"], - "sourceFiles": ["path/to/Action.java", "path/to/Login.jsp"] - }, - "alternatives": [ - "Spring Boot + Spring MVC", - "Quarkus", - "Micronaut" - ], - "explanation": "Apache Struts has reached end-of-life and no longer receives security patches or bug fixes. It has a history of critical remote code execution vulnerabilities (e.g., CVE-2017-5638, CVE-2023-50164) that made it one of the most exploited frameworks in the Java ecosystem. Continued use exposes the application to known, unpatched attack vectors. Migration to a modern, actively maintained framework such as Spring Boot is strongly recommended to ensure ongoing security support and access to current Java platform features." - } - ] -} -``` - -**JSON field descriptions:** -- `name`: Full framework name (with version distinction, e.g. "Apache Struts 1" vs "Apache Struts 2") -- `old`: Short identifier of the legacy framework (e.g. `struts2`, `winforms`) -- `new`: Short identifier of the recommended primary alternative (e.g. `spring-boot`, `maui`, `blazor`) -- `status`: `"end-of-life"` | `"deprecated"` | `"unmaintained"` | `"security-vulnerability"` | `"critical-bug"` | `"runtime-incompatible"` -- `detectedVersion`: Version string detected from config files, or `null` if not determinable -- `migrationComplexity`: `"high"` | `"medium"` | `"low"` -- `detectedIn.configFiles`: List of config file paths where references were detected -- `detectedIn.sourceFiles`: List of source file paths where references were detected -- `alternatives`: List of all recommended alternative frameworks -- `explanation`: Fixed explanation text for why this framework needs to be upgraded — use the exact text specified in each target's "Fixed explanation" section above - -If no outdated frameworks are detected, pass `{"outdatedFrameworks": []}` to the tool. - -**The JSON passed to the tool must contain ONLY the JSON object described above. No other text or formatting.** - -## Error Handling - -- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` -- **No build files found**: Output: `> ERROR: No recognized build files found at {workspace-path}. Verify the path is correct.` -- **Insufficient info**: Generate a best-effort report from available data. Set `detectedVersion` to `null` for dependencies where the version cannot be determined. - -## Success Criteria - -- All detection targets are checked against both configuration files and source code -- No frameworks or dependencies beyond Apache Struts and WinForms are reported -- JSON is valid and follows the specified schema exactly -- Only high-confidence findings are reported — no guesses or uncertain cases -- Result saved via `write_assessment_result` tool diff --git a/.github/skills/reconcile-tasks-with-plan/SKILL.md b/.github/skills/reconcile-tasks-with-plan/SKILL.md deleted file mode 100644 index c63c67210..000000000 --- a/.github/skills/reconcile-tasks-with-plan/SKILL.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -name: reconcile-tasks-with-plan -description: Update tasks.json to match the current plan.md content without modifying plan.md ---- - -# Reconcile tasks.json with plan.md - -This skill synchronizes tasks.json with plan.md when the plan has been manually updated. -It reads the current plan.md and tasks.json, detects differences, and rewrites tasks.json -to reflect the plan. **Do NOT modify plan.md** — it is the source of truth for task intent. - -## User Input - -- modernization-work-folder (Mandatory): The folder containing plan.md and .metadata/tasks.json -- language (Mandatory): The programming language of the project (java or dotnet) - -## Workflow - -1. **Read current state**: Read the following files from `${modernization-work-folder}`: - - `plan.md` — the authoritative modernization plan (source of truth for task intent) - - `.metadata/tasks.json` — the current structured task list (source of truth for execution state) - -2. **Detect inconsistencies**: Compare plan.md against the tasks defined in .metadata/tasks.json. Look for: - - Tasks described in plan.md that are missing from tasks.json - - Tasks in tasks.json that are no longer mentioned in plan.md - - Changes in task descriptions, requirements, scope, or ordering between the two files - -3. **Update tasks.json**: If inconsistencies are found, rewrite .metadata/tasks.json to match plan.md: - - Refer to the json schema tasks-schema.json for the correct task structure - - Add new tasks that appear in plan.md but are missing from tasks.json - - Remove tasks that are no longer described in plan.md - - Update descriptions, requirements, or ordering to match plan.md - - **Preserve task IDs**: For tasks that clearly map to existing entries, keep the same task ID - - **Preserve execution state**: Do NOT reset tasks that already have a `status` of "success", "failed", or "skipped". Keep their `status`, `taskSummary`, and `successCriteriaStatus` unchanged - - **Preserve metadata**: Keep the `metadata` block unchanged (same `planName`, `createdAt`, etc.) - - Follow the same task breakdown rules and schema conventions as `create-modernization-plan` - - Consult `java-upgrade-guideline.md` or `dotnet-upgrade-guideline.md` as applicable for upgrade tasks - -4. **Skip if consistent**: If no meaningful inconsistencies are found between plan.md and tasks.json, do not write any files. Simply respond that no changes were needed. - -## Important Notes - -- **Never modify plan.md** — it is the user's manually edited source of truth -- Only modify tasks that are genuinely affected by changes in plan.md -- Each task must remain independently testable -- Do not change task types unless the plan.md clearly indicates a different type diff --git a/.github/skills/repository-dependency-graph/SKILL.md b/.github/skills/repository-dependency-graph/SKILL.md deleted file mode 100644 index 76b1e1dd4..000000000 --- a/.github/skills/repository-dependency-graph/SKILL.md +++ /dev/null @@ -1,250 +0,0 @@ ---- -name: repository-dependency-graph -description: Analyze the service topology of a multi-repository application. Given an application name and repository paths, identifies each independently deployable service, infers each service's role and language, detects inter-service dependencies, and produces a topology graph (Markdown). ---- - -# Repository Dependency Graph - -<!-- ff:ai_analysis:start --> - -Analyze the service topology of the application identified by the `name` parameter. For each -repository in `entries`, identify the independently deployable services it contains, infer their -roles and languages, and detect inter-service dependencies. Produce a topology graph in Markdown -format and save it to `{report-dir}/application-topology-graph.md`. - -## Input Parameters - -- `name` (required): The short, human-readable display name for the application. Used as the - report heading and in the service table. -- `entries` (required, list): One or more repository entries belonging to this application. Each - entry is an object with: - - `repoName` (required): The canonical display name for the repository (e.g. `order-service`). - Used in the topology graph, service table, and as the basis for slug generation. Takes - precedence over the directory name for all naming and dependency-matching purposes. - - `path` (required): The local filesystem path to the repository root. - - At least one entry must have an accessible `path`. -- `report-dir` (required): The directory where the output file is written. The directory is - created and managed by the CLI runner; the skill must not modify its path or structure. - -**Output filename**: `{report-dir}/application-topology-graph.md` - -## Execution Steps - -### Step 1: Validate Inputs - -1. Verify `name` is non-empty. If empty, abort with: - `> ERROR: The 'name' parameter is required and must not be empty.` -2. For each entry in `entries`, verify both `repoName` and `path` are present and non-empty. If - either is missing, abort with: - `> ERROR: Each entry in 'entries' must have both 'repoName' and 'path' fields.` -3. For each entry in `entries`, check whether `path` is accessible (exists and is readable). - - Collect accessible entries into a working set. - - Collect inaccessible entries into an `inaccessible` list for reporting. -4. If the working set is empty (all paths are inaccessible), abort with: - `> ERROR: Topology analysis skipped for '{name}': none of the provided repository paths could be accessed.` -5. If `report-dir` does not exist or is not writable, abort with: - `> ERROR: Output directory '{report-dir}' does not exist or is not writable.` - -### Step 2: Per-Repository Service Identification - -For each accessible entry in `entries`, identify independently deployable services using `entry.path` -as the filesystem root. Use `entry.repoName` as the canonical repository name — it replaces -directory-name inference for display labels, slug generation, and cross-repository dependency -matching. - -**Build file detection** (determines language, framework, and service candidates): - -| Build file | Language | Framework hints | -|------------|----------|-----------------| -| `pom.xml` | java | Check `<parent>` for `spring-boot-starter-parent` → Spring Boot; `quarkus-bom` → Quarkus; `micronaut-parent` → Micronaut | -| `build.gradle` / `build.gradle.kts` | java | Check `plugins {}` for `org.springframework.boot`, `io.quarkus`, `io.micronaut.application` | -| `*.csproj` | dotnet | Check `<TargetFramework>` and packages for `Microsoft.AspNetCore.*` → ASP.NET Core; `Microsoft.Azure.Functions.Worker` → Azure Functions | -| `*.sln` / `*.slnx` | dotnet | Multi-project solution; recurse into sub-projects | -| `package.json` (with `"start"` script or `"main"` field) | javascript/typescript | Check `"dependencies"` for `express`, `fastify`, `koa`, `@nestjs/core`, `next`, `react`, `vue`, `@angular/core` | -| `tsconfig.json` (without `package.json`) | typescript | Infer TypeScript library | - -**Service identity** (one candidate per independently deployable unit): - -- For single-service repos: use `entry.repoName` as the service name. -- For monorepos: use `entry.repoName` as the repository label; detect multiple deployable units by looking for: - - Multiple `Dockerfile` files at different subdirectory levels (each names a service) - - Multiple `*.csproj` files with `<OutputType>Exe</OutputType>` or `<OutputType>exe</OutputType>` - - Multiple `pom.xml` files in subdirectories (each with its own `<artifactId>`) - - Multiple `package.json` files with a `"start"` or `"main"` script at subdirectory level - - Each detected unit becomes a separate Service entry; `subPath` is set to its relative path within the repo. - -**ServiceRole inference rules** (apply in order; first match wins): - -| Role | Evidence | -|------|----------| -| `ApiGateway` | Name or directory contains `gateway`, `proxy`, `edge`, `ingress`; OR Spring Cloud Gateway / Netflix Zuul dependency detected | -| `Frontend` | Framework is React, Angular, Vue, Blazor, Next.js, Nuxt; OR name contains `ui`, `web`, `frontend`, `portal`, `dashboard` | -| `Worker` | No inbound HTTP port exposed in Dockerfile; OR name contains `worker`, `consumer`, `processor`, `job`, `scheduler`, `daemon`; OR Spring Batch / Azure WebJobs / Hangfire dependency detected | -| `DataService` | Name contains `db`, `data`, `repository`, `store`, `cache`; OR heavy ORM usage (Spring Data JPA, EF Core DbContext is >50% of dependencies) | -| `SharedLibrary` | No `Dockerfile` and no executable entry point; name contains `lib`, `shared`, `common`, `sdk`, `client` | -| `WebApi` | HTTP framework detected (Spring MVC, ASP.NET Core controllers, Express, NestJS, FastAPI) and none of the above matched | -| `Unknown` | None of the above rules matched | - -**Service ID**: Lowercase slug of service name (replace spaces, dots, underscores with hyphens; remove non-alphanumeric except hyphens). Must be unique within the application. - -### Step 3: Cross-Repository Dependency Detection - -For each service, scan the following configuration and build files for references to other service names/identifiers discovered in Step 2: - -**Files to scan**: -- `application.properties`, `application.yml`, `application.yaml` (Spring Boot) -- `appsettings.json`, `appsettings.*.json` (ASP.NET Core) -- `*.env`, `.env`, `.env.*` -- `docker-compose.yml`, `docker-compose.yaml`, `docker-compose.*.yml` -- Helm chart `values.yaml`, `values.*.yaml` -- Kubernetes manifests (`*.yaml` in `k8s/`, `kubernetes/`, `deploy/`, `manifests/` directories) -- `pom.xml` (Maven dependencies — detect another service's `artifactId` as a dependency) -- `*.csproj` (NuGet `<PackageReference>` — detect another service's project/package name) -- `package.json` (`dependencies` / `devDependencies` — detect another service's package name) - -**What to look for**: - -| DependencyType | Evidence | -|----------------|----------| -| `HttpCall` | Property value matching a pattern like `http(s)://{service-name}`, `{service-name}.default.svc`, `{service-name}:PORT`, or an environment variable named `{SERVICE_NAME}_URL` / `{SERVICE_NAME}_HOST` / `{SERVICE_NAME}_BASE_URL` | -| `MessageQueue` | Property key or value containing a topic/queue name that also appears in another service's config (e.g., `spring.kafka.topic`, `rabbitmq.queue`, `azure.servicebus.topic`) | -| `SharedLibrary` | Build file dependency whose artifact/package name matches another service's slug or name (common for `SharedLibrary`-role services) | -| `DirectReference` | `depends_on:` in docker-compose; Kubernetes service reference; direct project reference in `.sln` / `*.csproj` | - -For each detected dependency, record: -- `targetServiceId` (the other service's slug) -- `dependencyType` (from the table above) -- `evidence` (the config file path and key/value that triggered the match, e.g., `appsettings.json: ServiceUrls:OrderService = http://order-service`) - -Only record dependencies where **both** the source service and the target service are within the analyzed set. Do not record dependencies on external services (databases, cloud services, etc.) — those are covered by the `dependency-map` skill. - -### Step 4: Cycle Detection - -Perform a depth-first search (DFS) on the directed dependency graph. - -- Maintain a visited set and a recursion stack. -- When a back edge is detected (a node already in the recursion stack is encountered again), record the cycle as a warning string: - `"Circular dependency detected: {ServiceA} → {ServiceB} → ... → {ServiceA}"` -- Continue DFS after recording the cycle (do not abort). -- Collect all cycle warning strings into `cycleWarnings`. - -### Step 5: Duplicate Service Detection - -For each pair of services, check: -1. Are their slugified names identical? (e.g., `order-service` and `order-service`) -2. Do their names differ only by separator or case after normalization? (e.g., `orderservice` == `order_service` == `OrderService`) -3. Do their primary entry-point artifact names match? (e.g., same Maven `<artifactId>`, same .NET assembly name) - -If any condition is true, add to that service's `warnings` list: -`"WARNING: Potential duplicate of '{other-service-name}' (from {other-repo-name} at {other-repo-path}). Verify these are not the same service."` - -### Step 6: Generate Mermaid Diagram - -Build a `flowchart TD` diagram. - -**Node format**: `{ServiceId}["{ServiceName}\n({Role})"]` -- Example: `orderSvc["order-service\n(WebApi)"]` - -**Edge format** (normal dependency): -`{SourceId} -->|"{DependencyType}"| {TargetId}` -- Example: `apiGateway -->|"HttpCall"| orderSvc` - -**Cycle edge format**: -`{SourceId} -.->|"⚠ cycle"| {TargetId}` - -**Node label rules**: -- Use plain text only; avoid `@`, `#`, `$`, `%`, `&`, `<`, `>`, `"` inside node labels -- Replace double quotes in names with single quotes before embedding in labels -- All node IDs must be unique across the diagram - -**Scale limit (40-node rule)**: -- If total service count ≤ 40: show all services individually. -- If total service count > 40: collapse per-repository into aggregate nodes: - - `{repoSlug}Grp["{repoName}\n({N} services)"]` where `{repoSlug}` is the slug of `entry.repoName` - - Show only cross-repository edges between aggregate nodes. - - Add a note at the top of the diagram section: `> Note: {N} services exceed the 40-node display limit. Services are grouped by repository.` - -### Step 7: Render Output - -Produce the final output content: - -**Markdown format** : - -``` -# Topology Graph: {name} - -Analyzed {N} service(s) across {M} repositor(y/ies) for application "{name}" on {YYYY-MM-DD HH:MM UTC}. - -## Services - -```mermaid -{mermaid diagram content} -``` - -## Service Details - -| Service | Role | Language | Source Repository | Warnings | -|---------|------|----------|------------------|----------| -| {service-name} | {Role} | {language} | {repoName} | {warnings or —} | -... - -## Warnings - -- {cycle warning 1} -- {cycle warning 2} -- {duplicate warning} -- Inaccessible repository: {repoName} ({path}) (skipped) -``` -(Omit `## Warnings` section entirely when no warnings exist.) - -### Step 8: Save Output - -1. Compute the output filename: - - Full path: `{report-dir}/application-topology-graph.md` -2. Write the rendered content to the output file (create or overwrite). -3. Log: `Topology graph for '{name}' saved to {output-path}` - -## Scaling Rules - -- Maximum 40 Mermaid nodes for GitHub rendering compatibility and diagram legibility. -- When service count > 40: collapse to per-repository aggregate nodes (Step 6 scale limit rule). -- Performance expectation: analysis of 3–10 repositories should complete in under 5 minutes on a - standard developer workstation. -- For very large monorepos (>20 sub-projects), limit per-repo service detection to a maximum of - 10 services; add a note in the Warnings section: `Note: Repository '{repo}' contains more than - 10 detected services; only the first 10 are shown.` - -## Mermaid Syntax Rules - -- Use `flowchart TD` (top-down layout). -- Avoid special characters in node labels: `@`, `#`, `$`, `%`, `&`, `<`, `>`. -- Always quote arrow labels with double quotes: `-->|"label"|`. -- Use `-.->` (dotted arrow) for cycle edges with label `"⚠ cycle"`. -- All node IDs must be unique across the entire diagram. -- Do not use `subgraph` — flat node layout only (services are already grouped logically by role - via node labels). - -## Error Handling - -| Condition | Behavior | -|-----------|----------| -| All `entries` inaccessible | Abort with error message (Step 1). No output file written. | -| Subset of paths inaccessible | Continue with accessible subset. Add each inaccessible entry as `Inaccessible repository: {repoName} ({path}) (skipped)` in Warnings section. | -| Missing `repoName` or `path` field | Abort with error message (Step 1). No output file written. | -| No build files found in any repository | Best-effort: list each repo as a service with `role: Unknown` and `language: unknown`. Add note in Warnings: `Note: No recognized build files were found. Service roles could not be inferred.` | -| Unsupported project type | Set `language: unknown` and `role: Unknown` for that service. Do not fail. | -| Service name collision (duplicate IDs after slugification) | Append the `repoName` as a suffix: `{slug}-{repo-name-slug}`. | -| Output file write error | Log error: `Failed to write topology graph for '{name}' to {report-dir}/application-topology-graph.md: {error}`. Do not abort the parent process. | - -## Success Criteria - -- Output file `{report-dir}/application-topology-graph.md` is created and non-empty. -- File contains at least one service node in the Mermaid diagram. -- All inaccessible repository paths are listed in the Warnings section (none silently ignored). -- The Mermaid diagram contains no syntax errors (valid `flowchart TD` syntax). -- The Service Details table has one row per detected service. -- The Warnings section is present only when at least one warning exists. -- No unhandled exceptions propagate to the assessment pipeline. - -<!-- ff:ai_analysis:end --> diff --git a/.github/skills/security-assessment-merge/SKILL.md b/.github/skills/security-assessment-merge/SKILL.md deleted file mode 100644 index da58db577..000000000 --- a/.github/skills/security-assessment-merge/SKILL.md +++ /dev/null @@ -1,318 +0,0 @@ ---- -name: security-assessment-merge -description: Merge CVE and CWE security assessment results into a unified security report and update report.json ---- - -# Security Assessment: Merge and Report - -## Role - -You are a **security assessment aggregator**. Your task is to read all CVE and CWE result files produced by earlier security skills, merge them into a unified security assessment report, and inject the findings into `report.json`. - -> **Important:** You are a data aggregator, NOT an analyzer. Do NOT re-scan the codebase. Your sole responsibility is to read, normalize, merge, and write the security findings that were already produced by the CVE and CWE assessment skills. - -## Working Directory - -All security assessment input and output files are located under: - -``` -.github/modernize/assessment/engines/security/ -``` - -All file paths in this skill are relative to this directory unless otherwise noted. - -## Objective - -1. Read all security assessment result files from the `.github/modernize/assessment/engines/security/` directory -2. Normalize CVE and CWE findings into a unified format -3. Generate `security-assessment.json` (machine-readable merged report) in the same directory -4. Generate `security-assessment.md` (human-readable markdown report) in the same directory -5. Inject a `"security"` array into the existing `report.json` - -## Instructions - -### Step 1: Read CVE Results - -Read the CVE result file at `.github/modernize/assessment/engines/security/cve-assessment-result.json`. - -This file is a **flat JSON array** where each element has: -```json -{ - "id": "CVE-2024-xxxx", - "name": "Summary", - "status": "FOUND", - "category": "CVE", - "severity": "critical|high|medium|low", - "storyPoint": 1, - "evidence": { - "files": ["pom.xml:42"], - "explanation": "Markdown description..." - } -} -``` - -Only include entries where `status` is `"FOUND"`. - -**Filter by minimum CVE severity:** The minimum severity threshold is provided in the assessment prompt instructions. Only include CVE findings whose severity meets or exceeds the specified threshold. The severity order from lowest to highest is: `low` < `medium` < `high` < `critical`. Exclude findings with unknown or missing severity. If no threshold was specified in the prompt, default to `high`. - -If the file does not exist or is empty, treat CVE findings as an empty list. - -### Step 2: Read CWE Results - -Read all CWE result files matching `.github/modernize/assessment/engines/security/result-cwe-*.json`. - -Each CWE file uses a **wrapper format**: -```json -{ - "input_name": "CWE - Category Name", - "status": "success", - "result": { - "values": [ - { - "id": "CWE-79", - "name": "Cross-site Scripting", - "status": "FOUND", - "category": "Injection Attacks", - "severity": "optional", - "storyPoint": 8, - "description": "The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.", - "evidence": { - "files": ["src/Controller.java"], - "explanation": "Description..." - } - } - ] - } -} -``` - -Navigate to `result.values` in each file and extract entries where `status` is `"FOUND"`. - -If no CWE files exist, treat CWE findings as an empty list. - -### Step 3: Build the Unified Security Findings Array - -Transform all FOUND CVE and CWE items into the unified format: - -```json -{ - "id": "CVE-2024-xxxx or CWE-79", - "title": "Human-readable title", - "category": "CVE or CWE category (e.g., Injection Attacks)", - "severity": "mandatory|optional|potential", - "description": "Detailed description", - "evidence": { - "files": ["path/to/file.java"], - "explanation": "Why this was flagged" - }, - "storyPoint": 1 -} -``` - -For **CVE findings**: Map `name` → `title`, use `explanation` as both `description` and `evidence.explanation`. **Map the raw CVE severity to assessment severity levels:** -- `critical` or `high` → `mandatory` -- `medium` → `optional` -- `low` or unknown → `potential` - -For **CWE findings**: Map `name` → `title`, map `severity` → `severity` (already in assessment format), map `storyPoint` → `storyPoint`, map `description` → `description`, use `explanation` as `evidence.explanation`. - -### Step 4: Calculate Summary Statistics - -Count: -- `totalFindings`: Total number of FOUND CVE + CWE items -- `cveCount`: Number of CVE findings -- `cweCount`: Number of CWE findings -- `bySeverity`: Count of findings grouped by severity (`mandatory`, `optional`, `potential`) -- `byCategory`: Count of findings grouped by category (`CVE`, `Injection Attacks`, etc.) -- `totalRulesAssessed`: Total number of CWE checklist items across all `.github/modernize/assessment/engines/security/result-cwe-*.json` files (both FOUND and NOT_FOUND) -- `rulesPassed`: `totalRulesAssessed - cweCount` - -### Step 5: Write security-assessment.json - -Write the full merged report to `.github/modernize/assessment/engines/security/security-assessment.json`: - -```json -{ - "GeneratedAt": "2026-04-09T12:00:00.0000000Z", - "ProjectPath": ".", - "Summary": { - "TotalFindings": 5, - "CveCount": 2, - "CweCount": 3, - "BySeverity": { "mandatory": 3, "optional": 1, "potential": 1 }, - "ByCategory": { "CVE": 2, "Injection Attacks": 2, "Code Quality": 1 }, - "TotalRulesAssessed": 59, - "RulesPassed": 56 - }, - "CveFindings": [ - { - "Id": "CVE-2024-xxxx", - "Name": "Vulnerability Title", - "Category": "CVE", - "Severity": "mandatory", - "StoryPoint": 1, - "Description": "...", - "Files": ["pom.xml:42"], - "Explanation": "..." - } - ], - "CweFindings": [ - { - "Id": "CWE-79", - "Name": "Cross-site Scripting", - "Category": "Injection Attacks", - "Severity": "optional", - "StoryPoint": 8, - "Description": "...", - "Files": ["src/Controller.java"], - "Explanation": "..." - } - ] -} -``` - -### Step 6: Write security-assessment.md - -Write a human-readable markdown report to `.github/modernize/assessment/engines/security/security-assessment.md`: - -```markdown -# Security Assessment Report - -**Generated:** <timestamp> - -## Summary - -| Metric | Count | -|--------|-------| -| Total Findings | N | -| CVE Vulnerabilities | N | -| CWE Vulnerabilities | N | -| Total Rules Assessed | N | -| Rules Passed | N | - -### By Severity - -| Severity | Count | -|----------|-------| -| mandatory | N | -| optional | N | -| potential | N | - -## CVE Findings (Dependency Vulnerabilities) - -### CVE-2024-xxxx: Title -- **Severity:** mandatory -- **Story Points:** 1 -- **Files:** pom.xml:42 - -<explanation> - -## CWE Findings (Code-Level Vulnerabilities) - -### CWE-79: Cross-site Scripting -- **Category:** Injection Attacks -- **Severity:** optional -- **Story Points:** 8 -- **Files:** src/Controller.java - -<explanation> -``` - -If there are no findings at all, write: -```markdown -## No security vulnerabilities found. - -The assessment did not detect any CVE or CWE vulnerabilities in the codebase. -``` - -### Step 7: Merge into report.json - -The `report.json` file lives in a versioned report directory: - -``` -.github/modernize/assessment/reports/report-{reportId}/report.json -``` - -where `{reportId}` is a `yyyyMMddHHmmss` timestamp (e.g., `20260410120000`). This directory is created by the main assessment skill. - -**Step 7a: Locate report.json** - -Find the latest versioned report directory by listing directories matching the `report-*` pattern and sorting in descending order (newest first): - -```bash -REPORTS_DIR=".github/modernize/assessment/reports" -REPORT_DIR=$(ls -d "$REPORTS_DIR"/report-* 2>/dev/null | sort -r | head -n 1) - -if [ -n "$REPORT_DIR" ] && [ -f "$REPORT_DIR/report.json" ]; then - echo "Found report.json at: $REPORT_DIR/report.json" -else - echo "Warning: No versioned report directory found under $REPORTS_DIR" -fi -``` - -**Step 7b: Merge security findings into report.json** - -**Use `jq` for safe JSON manipulation** — do NOT manually rewrite report.json. - -Write the unified findings array to a temporary file, then merge: - -```bash -SECURITY_DIR=".github/modernize/assessment/engines/security" - -# Write the unified findings array -cat > "$SECURITY_DIR/unified-findings.json" << 'SECURITY_EOF' -[ - ... unified findings array from Step 3 ... -] -SECURITY_EOF - -# Merge into report.json using jq -if [ -n "$REPORT_DIR" ] && [ -f "$REPORT_DIR/report.json" ] && command -v jq &> /dev/null; then - jq --argjson sec "$(cat "$SECURITY_DIR/unified-findings.json")" '. + {"security": $sec}' "$REPORT_DIR/report.json" > "$REPORT_DIR/report.json.tmp" && mv "$REPORT_DIR/report.json.tmp" "$REPORT_DIR/report.json" -elif [ -n "$REPORT_DIR" ] && [ -f "$REPORT_DIR/report.json" ]; then - # Fallback without jq: use python - python3 -c " -import json -report_path = '$REPORT_DIR/report.json' -with open(report_path, 'r') as f: report = json.load(f) -with open('$SECURITY_DIR/unified-findings.json', 'r') as f: security = json.load(f) -report['security'] = security -with open(report_path, 'w') as f: json.dump(report, f, indent=2) -" 2>/dev/null || echo "Warning: Could not merge security into report.json (jq and python3 unavailable)" -else - echo "Warning: report.json not found — skipping merge. The standalone security-assessment.json is still valid." -fi - -# Clean up temp file -rm -f "$SECURITY_DIR/unified-findings.json" -``` - -**Step 7c: Handle missing report.json** - -If no `report-*` directory or `report.json` exists (e.g., AppCAT was not run or failed), create a minimal stub in a new versioned directory: - -```bash -if [ -z "$REPORT_DIR" ] || [ ! -f "$REPORT_DIR/report.json" ]; then - REPORT_ID=$(date -u +"%Y%m%d%H%M%S") - REPORT_DIR="$REPORTS_DIR/report-$REPORT_ID" - mkdir -p "$REPORT_DIR" - cat > "$REPORT_DIR/report.json" << STUB_EOF -{ - "metadata": { - "id": "$REPORT_ID", - "generated_at": "$(date -u +"%Y-%m-%dT%H:%M:%S.0000000Z")", - "note": "Security-only report (AppCAT was not run or failed)" - }, - "security": $(cat "$SECURITY_DIR/unified-findings.json" 2>/dev/null || echo "[]") -} -STUB_EOF - echo "Created stub report at: $REPORT_DIR/report.json" -fi -``` - -## Error Handling - -- If no security result files exist at all, write empty reports (`security-assessment.json` with zero findings, `security-assessment.md` with "No vulnerabilities found") -- If a CWE result file is malformed, skip it and continue with the rest -- If the `report.json` merge fails, log a warning but do NOT fail the overall task — the standalone `security-assessment.json` is still valid -- Always produce all three output files (`security-assessment.json`, `security-assessment.md`, and the merged `report.json`) diff --git a/.github/skills/validate-playbook-compliance/SKILL.md b/.github/skills/validate-playbook-compliance/SKILL.md deleted file mode 100644 index 19ae310ef..000000000 --- a/.github/skills/validate-playbook-compliance/SKILL.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: validate-playbook-compliance -description: Validate playbook compliance by mapping playbook rules to plan tasks ---- - -# Validate Playbook Compliance - -Map each playbook rule to the tasks in the modernization plan and produce a compliance summary. - -## User Input - -- tasks-json-path (Mandatory): Path to the tasks.json file -- compliance-output-path (Mandatory): Path to write the compliance markdown summary - -## Workflow - -1. Read the tasks from ${tasks-json-path} -2. Read the playbook files provided as attachments -3. For each playbook rule, determine which task (if any) addresses it -4. Write a markdown summary to ${compliance-output-path} with the following format: - -## Playbook Compliance - -| Playbook | Rule | Status | Task | -|----------|------|--------|------| -| targets.md | brief rule summary | ✅ COVERED | 001 | -| policies.md | another rule | ❌ NOT COVERED | - | - -**COVERED: X/Y · NOT COVERED: Z/Y** - -Include all rules from all playbook files. Only write the markdown file, do not modify any other files. diff --git a/.github/skills/validate-playbook-evidence/SKILL.md b/.github/skills/validate-playbook-evidence/SKILL.md deleted file mode 100644 index ae4d51192..000000000 --- a/.github/skills/validate-playbook-evidence/SKILL.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: validate-playbook-evidence -description: Analyze code changes and produce playbook compliance evidence from git diff ---- - -# Validate Playbook Evidence - -Analyze the git diff and produce playbook compliance evidence showing which rules were implemented. - -## User Input - -- baseline-commit-sha (Mandatory): The baseline commit SHA to diff from -- playbook-file-list (Mandatory): Comma-separated list of playbook file names -- evidence-output-path (Mandatory): Path to write the evidence markdown summary - -## Workflow - -1. Analyze the git diff from baseline commit ${baseline-commit-sha} to HEAD -2. The playbook files are: ${playbook-file-list} -3. Write a markdown summary to ${evidence-output-path} with the following format: - -## Playbook Code Evidence (from diff) - -### [policies.md] -**Rule: brief rule summary** -```diff -+ filepath:line added code -- filepath:line removed code -``` - -Focus on the 2-5 most impactful rules. Each diff line starts with '+' or '-' and includes file:line prefix. -Only write the markdown file, do not modify any other files.