Skip to content

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

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:

# 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

PR: #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:

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

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:

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

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:

# 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.


Security

APIM Subscription Key Authentication with Crypto Registration ๐Ÿ”

PR: #565 ยท Closes #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


Naming Module

TeamSubscriptions Group with PlatformDev Entry ๐Ÿ—๏ธ

PR: #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


๐Ÿ”„ Breaking Changes

None in this release โœ…


๐Ÿ“‹ Additional Notes

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

Support

  • ๐Ÿ“ง Teams Support Channel: Support