# 3.4.0

**Release Date:** April 13, 2026

---

## ✨ New Features

### CLI Tools

#### SAIF CLI Restructuring — Phases 1–3: `saif doctor`, `saif agent`, and Command Consolidation 🩺

**PR:** [#562](https://github.com/saif-corp/forge/pull/562)

The SAIF CLI has been restructured following industry patterns from Aspire CLI, `gh`, and `azd` to be equally productive for humans and AI coding agents. Phases 1–3 introduce structured environment diagnostics, a renamed `agent` surface, and a consolidated update workflow.

**What's New:**

- ✅ **`saif doctor`** — Runs all environment checks; renders table or JSON envelope (`schema_version` + `summary` fields). `--format json` always exits 0; errors appear in the JSON body for agent-safe consumption
- ✅ **`saif doctor fix`** — Subcommand that remediates issues with `--dry-run`, `--self`, `--tools`, `--templates` filters
- ✅ **`saif agent`** — Replaces `saif mcp`; `saif agent mcp` starts the MCP server, `saif agent init` configures VS Code and Copilot CLI environments
- ✅ **Backward compatibility** — `saif mcp` and `saif update` remain as hidden deprecated aliases through 3.x

**`saif doctor` Example:**

```bash
# Diagnose environment
saif doctor
saif doctor --format json    # Always exits 0; errors in JSON body

# Fix issues
saif doctor fix
saif doctor fix --dry-run    # Preview changes
saif doctor fix --tools      # Only update dev tools
saif doctor fix --self       # Only update SAIF CLI
```

**Benefits:**

- 🚀 `--format json` contract enables agent-driven environment management
- 🔧 `--dry-run` on mutations lets agents preview without risk
- 🎯 Filtered fixes (`--self`, `--tools`, `--templates`) replace monolithic update

---

#### SAIF CLI Restructuring — Phases 4–6: `saif config`, `saif docs`, Command Migrations, and Federated Search 🔧

**PR:** [#571](https://github.com/saif-corp/forge/pull/571)

Continues the CLI restructuring with configuration management, documentation commands, structural renames with backward-compatible aliases, and a first-class federated search command.

**What's New:**

- ✅ **`saif config`** — Configuration management backed by `~/.saif/config.json`. Supports `list`, `get`, `set`, and `validate` subcommands with dot-notation keys (`output.format`, `update.channel`, `agent.autoUpdate`)
- ✅ **`saif docs`** — Documentation commands wrapping the `IDocumentationService` index: `docs list`, `docs search <query>`, `docs get <slug> [--section <heading>]`
- ✅ **`saif pipeline`** (renamed from `saif build`) — Adds explicit `pipeline run` subcommand; `saif build` remains a hidden alias through 3.x
- ✅ **`saif auth`** (renamed from `saif token`) — `auth generate --plain` outputs raw token to stdout for scripting/agent use
- ✅ **`saif search`** — Federated cross-domain search that fans out across repositories, apps, and docs concurrently via `Task.WhenAll`

**`saif search` Example:**

```bash
saif search <query> [--verbose] [--format table|json]
saif repo search --repository-name <name>
saif docs search <query>
saif app search [--audience <uri>] [--app-id <id>] [--name <name>]
```

**Benefits:**

- 🔍 Single command searches all domains in parallel; domain failures surface as warnings so partial results are always returned
- ⚙️ `saif config validate` is zero-side-effect and agent-safe
- 📖 `saif docs get --section <heading>` extracts a single heading for targeted agent reads

---

### Terraform Modules

#### Custom Environments Support for `tfe-bootstrapper-team` 🌍

**PR:** [#510](https://github.com/saif-corp/forge/pull/510)

The `tfe-bootstrapper-team` module now accepts a `custom_environments` variable, allowing teams to provision Terraform Cloud workspaces for environments beyond the standard platform set.

**What's New:**

- ✅ **`custom_environments` variable** — Typed as `map(object({ Name, ShortName, Description, IsProduction }))`, defaulting to `{}`
- ✅ **Automatic merging** — Custom environments are merged with standard `module.names.Environments`; workspaces are provisioned for all entries
- ✅ **Non-breaking** — Omitting `custom_environments` produces identical behaviour to the previous version

**Example:**

```hcl
module "team_bootstrap" {
  source = "..."

  custom_environments = {
    "performance" = {
      Name          = "Performance"
      ShortName     = "prf"
      Description   = "Performance testing environment"
      IsProduction  = false
    }
  }
}
```

---

#### Cosmos DB Unique Key Constraints for `saif-api-service` 🔑

**PR:** [#552](https://github.com/saif-corp/forge/pull/552)

End-to-end `unique_keys` support has been added for Cosmos DB serverless NoSQL containers, from the Terraform module variable through the feature template YAML.

**What's New:**

- ✅ **`unique_keys` field** — Added to `cosmosdb_nosql_serverless_settings.containers`; each entry is a list of one or more paths (single-path or composite constraints)
- ✅ **Feature template support** — `feature-database-cosmosdb.tf` extracts `unique_keys` from YAML using `coalesce` to handle missing or null values gracefully
- ✅ **`cosmosdb_nosql` module bumped to `~> 4.0.0`** — Required to support `list(list(string))` type for composite key constraints
- ✅ **Documentation** — New "Unique Key Constraints" section added to the Cosmos NoSQL guide with YAML examples and migration notes

**Example:**

```yaml
# database-cosmosdb-containers.yaml
containers:
  - container_name: Users
    partition_key: /PartitionKey
    unique_keys:
      - ["/email"]                          # single-path constraint
  - container_name: Reports
    partition_key: /PartitionKey
    unique_keys:
      - ["/userId", "/reportMonth"]         # composite constraint
```

> ⚠️ **Note:** Adding unique keys to an existing Cosmos DB container requires recreation of the container. Review the migration notes in the [Cosmos NoSQL Guide](../guides/development/data/cosmos-nosql.md).

---

### Security

#### APIM Subscription Key Authentication with Crypto Registration 🔐

**PR:** [#565](https://github.com/saif-corp/forge/pull/565) · Closes [#456](https://github.com/saif-corp/forge/issues/456)

The `saif-api-service` module's subscription key authentication has been extended to support optional crypto registration for legacy .NET callers, with updated documentation covering the full end-to-end setup.

**What's New:**

- ✅ **`application_secrets` variable** — Accepts user-provided subscription keys per environment; wired into the APIM subscription resource via `local_secrets.tf`
- ✅ **Crypto registration support** — Pipeline `cryptoRegistration` parameter enables hash-based key registration for legacy service consumers
- ✅ **Revised documentation** — Full rewrite of `subscription-key-auth.md` covering variable group setup, pipeline configuration, .NET retrieval pattern, key rotation, and troubleshooting

**Documentation:** [Subscription Key Authentication Guide](../guides/security/configuration/subscription-key-auth.md)

---

### Naming Module

#### `TeamSubscriptions` Group with `PlatformDev` Entry 🏗️

**PR:** [#587](https://github.com/saif-corp/forge/pull/587)

A new `TeamSubscriptions` group has been added to the naming static locals, introducing a `PlatformDev` entry for the Platform team's development subscription.

**What's New:**

- ✅ **`TeamSubscriptions` group** — Sits between `SandboxSubscriptions` (individual dev sandboxes) and `Subscriptions` (formal UAT/Prod environments)
- ✅ **`PlatformDev` entry** — References `local.Tenants.Corporate.Name` consistently with other entries; accessible via `local.TeamSubscriptions.PlatformDev`

---

## 🔧 Enhancements

_No user-facing enhancements in this release._

---

## 🐛 Bug Fixes

- **`fix(operations)`** — Updated response type for async resource actions to match actual API contract
- **`fix(azdo)`** — Updated `NodeTool` task to `UseNode` for correct Node.js version specification in Azure DevOps pipelines
- **`fix(platform)`** — Resolved missing OTEL tracer, logger, and meter provider global registrations; fixes gaps in telemetry coverage for platform services

---

## 📚 Documentation

- **Integration Test Environment Variables** — New guide covering how to pass required environment variables into CI/CD integration test runs ([`docs/guides/development/testing/integration-test-environment-variables.md`](../guides/development/testing/integration-test-environment-variables.md))

---

## 🔄 Breaking Changes

None in this release ✅

---

## 📋 Additional Notes

- Total commits: 32
- Contributors: brishe, emmjoh, jasyue, Copilot

---

### Support

- 📧 Teams Support Channel: [Support](https://teams.microsoft.com/l/channel/19%3Acb611810fb0b42b080cfff5590bdd51c%40thread.tacv2/Support?groupId=514d2dac-2d62-48ce-bf99-0fa0ce39469c&tenantId=a86cb8ed-369b-4df5-ace5-43811f6e08cf)

---
