{
  "steward": "bicep-testing-steward",
  "project": "Azure-AI-RAG-CSharp-Semantic-Kernel-Functions",
  "runDate": "2026-03-22",
  "runId": "2026-03-22T00-00-00",
  "findings": [
    {
      "id": "ITST-TEST-001",
      "title": "No Bicep test files exist anywhere in the infra folder",
      "severity": "critical",
      "category": "TEST",
      "file": "infra/",
      "description": "There are no native Bicep test blocks (test { }) in any .bicep file, and no dedicated test modules under infra/. Without test coverage, parameter misconfigurations and broken module wiring go undetected until a live deployment attempt.",
      "recommendation": "Create Bicep test files using native test blocks for each key module (main, database, storage, OpenAI). Example: infra/tests/main.test.bicep with a test block that exercises the main deployment scenario.",
      "status": "open"
    },
    {
      "id": "ITST-LINT-001",
      "title": "No bicepconfig.json — linting is unconfigured and unenforced",
      "severity": "critical",
      "category": "LINT",
      "file": "infra/",
      "description": "No bicepconfig.json exists in the repository. The Bicep linter defaults apply, meaning key rules such as no-unused-params, no-hardcoded-env-urls, and secure-params-in-nested-deploy are set to warning rather than error, and linting is never surfaced in any CI gate.",
      "recommendation": "Add infra/bicepconfig.json configuring no-unused-params, no-unused-vars, no-hardcoded-env-urls, and secure-params-in-nested-deploy as level: error.",
      "status": "open"
    },
    {
      "id": "ITST-WHATIF-001",
      "title": "No what-if validation before deployment — changes applied directly",
      "severity": "critical",
      "category": "WHATIF",
      "file": "infra/deploy.ps1",
      "description": "The deploy.ps1 script calls az deployment sub create directly with no preceding az deployment sub what-if step. There is no CI/CD pipeline in the repository. Infrastructure changes are applied to the target subscription without any preview or approval gate, increasing the risk of unintended resource changes or deletions.",
      "recommendation": "Add an az deployment sub what-if step before az deployment sub create in deploy.ps1, prompt for confirmation, and add a CI pipeline job that runs what-if on every pull request.",
      "status": "open"
    },
    {
      "id": "ITST-PSRULE-001",
      "title": "No PSRule for Azure configuration — no compliance testing",
      "severity": "notable",
      "category": "PSRULE",
      "file": "infra/",
      "description": "No .ps-rule/ folder, no ps-rule.yaml, and no PSRule baseline exist. Known Azure best-practice violations in the current Bicep code (shared key access on storage, public network access on OpenAI, deprecated role assignment API versions) would be caught automatically by PSRule for Azure but are currently undetected.",
      "recommendation": "Add a .ps-rule/ folder with ps-rule.yaml referencing the Azure.Default baseline. Run Invoke-PSRule in CI against all Bicep files in infra/.",
      "status": "open"
    },
    {
      "id": "ITST-LINT-002",
      "title": "key-vault.bicep is empty (0 bytes) — no lint or content check catches this",
      "severity": "notable",
      "category": "LINT",
      "file": "infra/core/security/key-vault.bicep",
      "description": "The file infra/core/security/key-vault.bicep exists but is completely empty. If any module references it in the future, the deployment will fail with a confusing error. No linting configuration or CI check detects empty Bicep module files.",
      "recommendation": "Either implement the key-vault.bicep module with its required Key Vault resource definition, or remove the empty file. Enforce linting in CI to surface empty or no-resource modules.",
      "status": "open"
    },
    {
      "id": "ITST-LINT-003",
      "title": "secure-params-in-nested-deploy rule not enforced — CosmosDB connection string passed as plain string",
      "severity": "notable",
      "category": "LINT",
      "file": "infra/app/api-app.bicep",
      "line": 66,
      "description": "The CosmosDb_ConnectionString app setting is set to an empty string literal in api-app.bicep. The deployment pattern has no @secure() decorator on any parameter that would carry a real connection string. Without the secure-params-in-nested-deploy lint rule enforced, a future change that threads a real secret through as a plain string parameter would pass through linting and build without warning.",
      "recommendation": "If a real connection string will ever be passed as a parameter, annotate it with @secure(). Enforce secure-params-in-nested-deploy as level: error in bicepconfig.json.",
      "status": "open"
    },
    {
      "id": "ITST-PARAM-001",
      "title": "Storage account name has no @minLength(3) / @maxLength(24) constraint",
      "severity": "minor",
      "category": "PARAM",
      "file": "infra/core/storage/blob-storage-account.bicep",
      "line": 1,
      "description": "Azure Storage account names must be 3–24 characters, lowercase alphanumeric only. The accountName parameter has no length decorators, so an invalid name will cause a deployment failure at ARM validation time with an unhelpful error rather than a clear Bicep validation message.",
      "recommendation": "Add @minLength(3) @maxLength(24) and a @description decorator to the accountName parameter.",
      "status": "open"
    },
    {
      "id": "ITST-PARAM-002",
      "title": "Cosmos DB container throughput has no @minValue(400) / @maxValue(1000000) constraint",
      "severity": "minor",
      "category": "PARAM",
      "file": "infra/core/database/cosmos-db/nosql/container.bicep",
      "line": 19,
      "description": "The throughput parameter accepts any int value. Azure Cosmos DB manual throughput must be between 400 and 1,000,000 RU/s. Passing a value outside this range causes a deployment failure with an ARM error rather than a clear validation message at the Bicep layer.",
      "recommendation": "Add @minValue(400) @maxValue(1000000) to the throughput parameter.",
      "status": "open"
    },
    {
      "id": "ITST-PARAM-003",
      "title": "Multiple app module parameters have no @description or length constraints",
      "severity": "minor",
      "category": "PARAM",
      "file": "infra/app/api-app.bicep",
      "description": "All string parameters in infra/app/api-app.bicep, infra/app/loader-function.bicep, and infra/app/web-app.bicep lack @description decorators and length/value constraints. This reduces discoverability and means invalid parameter values are caught only at ARM deployment time.",
      "recommendation": "Add @description decorators to all public parameters. Apply @minLength/@maxLength based on Azure resource naming limits for name parameters (App Service names: 2–60 characters, for example).",
      "status": "open"
    },
    {
      "id": "ITST-PARAM-004",
      "title": "main.bicep and search-services.bicep use parameter validation decorators correctly",
      "severity": "info",
      "category": "PARAM",
      "file": "infra/main.bicep",
      "description": "The main.bicep entry point applies @minLength and @maxLength on environmentName and projectName, and @minLength on location. The search-services.bicep module uses @allowed on hostingMode, publicNetworkAccess, and semanticSearch. These are positive examples of parameter validation that should be extended to the rest of the module library.",
      "status": "open"
    }
  ],
  "summary": {
    "critical": 3,
    "notable": 3,
    "minor": 3,
    "info": 1,
    "total": 10
  }
}
