# 3.9.0

**Release Date:** September 2, 2026

This release ships the forge and forge-planning skill packages as installable Agent Plugins, bundles the Mosaic MCP server for design-system access, and completes the multi-phase effort to eliminate `tfe_outputs` remote-state coupling in Terraform modules — with a CI guardrail so it can't regress. The CLI adds plan-mode permission classification for `saif` commands and Agent Plugin auto-install/update via `doctor fix`, and Terraform defaults blob storage to private-endpoint isolation.

---

## ✨ New Features

### Agent Plugins & MCP

- Ship forge and forge-planning as installable Agent Plugins packages, bundling the Mosaic MCP server in the forge package ([`cafa0c53`](https://github.com/saif-corp/forge/commit/cafa0c53e982d4b7a7d26b15482a6418e3038441) | [#1001](https://github.com/saif-corp/forge/pull/1001), [`25d84b2c`](https://github.com/saif-corp/forge/commit/25d84b2c17b1223a3b688253d0f0fd31d81c8c6a) | [#1040](https://github.com/saif-corp/forge/pull/1040))
- **cli** - `saif agent init` registers and directly installs Forge Agent Plugins, now defaulting to a user-scoped install ([`c7cc1954`](https://github.com/saif-corp/forge/commit/c7cc1954c9afd090510c80a5b09f342ec4d880bd) | [#1012](https://github.com/saif-corp/forge/pull/1012), [`4f59d668`](https://github.com/saif-corp/forge/commit/4f59d6687dfb9e6573a764dd687a83c1498cb267) | [#987](https://github.com/saif-corp/forge/pull/987))
- **cli** - `saif doctor fix` detects and updates installed Agent Plugins ([`f03d7cf0`](https://github.com/saif-corp/forge/commit/f03d7cf02f266de3a4142b3187d3046233907bfe) | [#1034](https://github.com/saif-corp/forge/pull/1034))
- **mosaic** - bump Mosaic to v18 ([`e4f93a53`](https://github.com/saif-corp/forge/commit/e4f93a53805c18a2021a8b8acbee0b2dc879b643) | [#976](https://github.com/saif-corp/forge/pull/976))
- **mcp** - upgrade to MCP 2026-07-28 with explicit conversation IDs ([`e0a940ac`](https://github.com/saif-corp/forge/commit/e0a940ace54fb0a1939f0e16f0d80b7d18d684d2) | [#1024](https://github.com/saif-corp/forge/pull/1024))

### CLI

- Classify `saif` commands as read-only/mutating and generate plan-mode permission rules from the classification ([`b6189973`](https://github.com/saif-corp/forge/commit/b61899730f17e1f849c027347ceb3c05190613c6) | [#977](https://github.com/saif-corp/forge/pull/977))
- Scope pipeline logs to the job/step in a build URL ([`c3677a3d`](https://github.com/saif-corp/forge/commit/c3677a3ddf38e3892b0c0407a7f54563fe3a4495) | [#1107](https://github.com/saif-corp/forge/pull/1107))
- Show installed and latest versions in `doctor` results ([`2fb00883`](https://github.com/saif-corp/forge/commit/2fb0088310d876a611d4db6e5336b878c0d504fe) | [#1072](https://github.com/saif-corp/forge/pull/1072))
- Add `--trace-id` to otel traces and logs ([`745b21bf`](https://github.com/saif-corp/forge/commit/745b21bfb9a95a7706fbe9377b3a8eaea17f9c40) | [#921](https://github.com/saif-corp/forge/pull/921))

### Terraform

- Default blob storage to a private endpoint with network isolation ([`c5810602`](https://github.com/saif-corp/forge/commit/c5810602cfb2615025b54c9dc34d900961933447) | [#1037](https://github.com/saif-corp/forge/pull/1037))
- Grant Document Intelligence RBAC via an identity module flag ([`b80b35c3`](https://github.com/saif-corp/forge/commit/b80b35c3c2aaa2a6b2b9701775409fed121d12fc) | [#1047](https://github.com/saif-corp/forge/pull/1047))
- Configure the Okta provider from an env-category variable set, and attach the existing Okta variable set to app workspaces via `tfe-bootstrapper` ([`a59e76fc`](https://github.com/saif-corp/forge/commit/a59e76fcfa8897f45e5baa085b944c7b954c7db9) | [#845](https://github.com/saif-corp/forge/pull/845), [`aeda4776`](https://github.com/saif-corp/forge/commit/aeda47768ab72f4e6f9a5dcb1e96b0fb07931642) | [#1023](https://github.com/saif-corp/forge/pull/1023))
- Eliminate the residual `okta_app` `tfe_outputs` read, closing out the #845 migration ([`6a6b5685`](https://github.com/saif-corp/forge/commit/6a6b56856f83857c7661e4a4049b33278d5c41ed))
- **infra** - add app-specific custom domain support to Front Door routes ([`f93a7fe3`](https://github.com/saif-corp/forge/commit/f93a7fe38132bfa88adbfc943f09fb84e2ad7fa7) | [#929](https://github.com/saif-corp/forge/pull/929))

### Governance & Templates

- **templates** - add PlatformDev as a bootstrap `additional_environments` entry ([`832f5043`](https://github.com/saif-corp/forge/commit/832f504310d2dbe58284910342f8c3b4922dfd84) | [#1031](https://github.com/saif-corp/forge/pull/1031))
- **business-roles-corp** - warn when `manual_users` is set in non-production ([`9938d4ad`](https://github.com/saif-corp/forge/commit/9938d4ad44e9d8d2c971ebf065b26bdc43d3c0de) | [#1110](https://github.com/saif-corp/forge/pull/1110))
- **client** - add TanStack Query ([`16bf191c`](https://github.com/saif-corp/forge/commit/16bf191cac8215587bba8fd6cac8c304a8de0f31) | [#964](https://github.com/saif-corp/forge/pull/964))

---

## 🔧 Enhancements

- **infra** - eliminate all remaining `tfe_outputs` remote-state lookups (#845 Phase 1 — zero residuals) ([`b36c51e4`](https://github.com/saif-corp/forge/commit/b36c51e4a4fda36d2c2ee4aa85b58e8fdfabd247) | [#914](https://github.com/saif-corp/forge/pull/914))
- **cli** - retire MCP guided-workflow prompts for shipped skills ([`41112865`](https://github.com/saif-corp/forge/commit/4111286537d3ac2cf05da8320165302b3dc89fee) | [#1017](https://github.com/saif-corp/forge/pull/1017))
- Fix oversized skill descriptions and strip anti-triggers ([`20c3bd8c`](https://github.com/saif-corp/forge/commit/20c3bd8c3a1d5fbe627d6403a1c4c91fa1870143) | [#1068](https://github.com/saif-corp/forge/pull/1068))

---

## 🐛 Bug Fixes

### CLI

- Exclude Smithy's native-duplicate MCP tools from the remote bridge ([`ab6fe358`](https://github.com/saif-corp/forge/commit/ab6fe3587737307ab8540d080ad4715cf4dd5fcd) | [#1013](https://github.com/saif-corp/forge/pull/1013))
- Compare remote URLs semantically in `AddRemoteAsync` ([`ffd3f0b4`](https://github.com/saif-corp/forge/commit/ffd3f0b4d9a9d61f4237c59823abe912c14894de) | [#961](https://github.com/saif-corp/forge/pull/961))
- Use `-EncodedCommand` for the detached self-update process ([`69879833`](https://github.com/saif-corp/forge/commit/698798334fdd6e515c1a6b4e1676130e19427119) | [#960](https://github.com/saif-corp/forge/pull/960))
- Emit filter-field syntax in the traces explorer deep link ([`683c821f`](https://github.com/saif-corp/forge/commit/683c821f21ac74b46c7a76068a7ae58aa2b6cc5a) | [#955](https://github.com/saif-corp/forge/pull/955))
- Surface failed pipeline steps whose log lives on an ancestor record ([`f494e214`](https://github.com/saif-corp/forge/commit/f494e2147e93edf16ff4cd2337142dd763b0a814) | [#954](https://github.com/saif-corp/forge/pull/954))

### Terraform

- Avoid a `depends_on` cycle in `saif-application-permissions` ([`aebba880`](https://github.com/saif-corp/forge/commit/aebba880d0a8333453eab8824b61e1fe7c039b3e) | [#1080](https://github.com/saif-corp/forge/pull/1080))
- Suppress role-assignment scope casing drift, adding `replace_triggered_by` hardening to the casing-drift-guarded assignments and covering the remaining KV secret readers ([`bc0e6387`](https://github.com/saif-corp/forge/commit/bc0e6387d88ac11a8516c012b4f799119c59fe5b) | [#1077](https://github.com/saif-corp/forge/pull/1077), [`0693106a`](https://github.com/saif-corp/forge/commit/0693106a424676089f974b14ff96458d6ee08649) | [#1075](https://github.com/saif-corp/forge/pull/1075))
- Show available subdomain keys in the custom-subdomain check message ([`4289cd30`](https://github.com/saif-corp/forge/commit/4289cd300e733a87958526e88a25b83494f08a10) | [#1046](https://github.com/saif-corp/forge/pull/1046))
- Grant storage Blob Data Contributor to the app registration service principal ([`55dd1673`](https://github.com/saif-corp/forge/commit/55dd1673a69a88ef57d2c8ad6e9f9b7ae695fb45) | [#1027](https://github.com/saif-corp/forge/pull/1027))
- Resolve the blob storage connection string from module output instead of a stale reference, and stop passing null network rule args to `storageaccount` ([`e3ec6838`](https://github.com/saif-corp/forge/commit/e3ec683866ae89d83fb519d0f87c43c9df14edc0) | [#1005](https://github.com/saif-corp/forge/pull/1005), [`83e71f49`](https://github.com/saif-corp/forge/commit/83e71f4939c5aa6f0e278070a230d1a775c04000) | [#1004](https://github.com/saif-corp/forge/pull/1004))
- **saif-event-service** - wrap `fd_custom_domain_ids` with `nonsensitive()` before iterating, and dedupe Front Door custom domain IDs to fix a prod deploy failure ([`c868898c`](https://github.com/saif-corp/forge/commit/c868898cee4ab922e7c310d30d967aa19ea7bc97), [`3a53ff54`](https://github.com/saif-corp/forge/commit/3a53ff54a16e554be9db9188f3806930959bea34) | [#947](https://github.com/saif-corp/forge/pull/947))
- **tfe-bootstrapper-business-roles** - stop attaching the Okta corp variable set to corp-tenant workspaces ([`05d7bc10`](https://github.com/saif-corp/forge/commit/05d7bc10c94b4b9abe3cb97b58e93e163f3a4116) | [#1108](https://github.com/saif-corp/forge/pull/1108))

### Templates

- Remove the Okta provider/variables from the corp test-tools scaffold ([`5d23e80a`](https://github.com/saif-corp/forge/commit/5d23e80a80870912468fcd63b56ffa6ff0707fdb) | [#1111](https://github.com/saif-corp/forge/pull/1111))
- Fix frontend pre-commit/pre-push hooks and unit test failures ([`1915147e`](https://github.com/saif-corp/forge/commit/1915147e342a1e53c0b6630d184770d185a2d32a) | [#1030](https://github.com/saif-corp/forge/pull/1030))
- Remove a stray `infra/auth/external` folder and refresh the blob storage docs ([`a7a0c9dc`](https://github.com/saif-corp/forge/commit/a7a0c9dc4e48372f220f03dd6acf7532934dbc7c) | [#999](https://github.com/saif-corp/forge/pull/999))

### Workflows & CI

- Bump the pinned `Microsoft.Extensions.AI` package version to resolve a Smithy `NU1605` restore failure ([`563750ad`](https://github.com/saif-corp/forge/commit/563750adbf1696bf16aa8f2b0b715cc88e661a08) | [#1097](https://github.com/saif-corp/forge/pull/1097))

### Other

- **oracle** - escape Oracle connection strings via `OracleConnectionStringBuilder` so passwords containing `;` no longer corrupt the connection string ([`07917c0f`](https://github.com/saif-corp/forge/commit/07917c0f3cd3624b2cbad8d5e98f3cc06c437129) | [#962](https://github.com/saif-corp/forge/pull/962))
- **ui** - add body-scroll-padding ([`132359a6`](https://github.com/saif-corp/forge/commit/132359a65e4faa60419e0427074769e1c0dbad5b) | [#956](https://github.com/saif-corp/forge/pull/956))
- **git** - stop `Directory.Packages.props` showing as permanently modified, and renormalize its line endings per `.gitattributes` ([`bb04dc47`](https://github.com/saif-corp/forge/commit/bb04dc47de3ccaf98c146022ff0e87081fcf7d8e) | [#953](https://github.com/saif-corp/forge/pull/953), [`c07ffc64`](https://github.com/saif-corp/forge/commit/c07ffc64cdceda6401920205d3cdaf23f6b19eb7) | [#935](https://github.com/saif-corp/forge/pull/935), [`6f406999`](https://github.com/saif-corp/forge/commit/6f406999af97e62dd9ffdb98d459077aecaa383e))

---

## 📚 Documentation

### Troubleshooting Articles

New articles cover: [null `function_app_service_plan_id`](https://github.com/saif-corp/forge/commit/42dc5460b694b37006c415e1bc7e85f4c2c43bb7) ([#1109](https://github.com/saif-corp/forge/pull/1109)), a tainted-role-assignment guide and preferring the `saif` CLI for pipeline log triage ([#1104](https://github.com/saif-corp/forge/pull/1104)), [storage account `network_rules` null errors](https://github.com/saif-corp/forge/commit/42b1c07eb490154739b1039b7d113cd3188be63a) ([#1093](https://github.com/saif-corp/forge/pull/1093)), [blob storage 403 `AuthorizationPermissionMismatch`](https://github.com/saif-corp/forge/commit/7bcef34f826092d645511862ea9a5645a80d0c13) ([#1091](https://github.com/saif-corp/forge/pull/1091)), `saif publish` pipeline creation and remote URL issues ([#1090](https://github.com/saif-corp/forge/pull/1090)), a function app deploy invalid-version warning ([#1089](https://github.com/saif-corp/forge/pull/1089)), `AzureCli Authorizer az not found` ([#1088](https://github.com/saif-corp/forge/pull/1088)), an `application_permissions` inconsistent final plan ([#1086](https://github.com/saif-corp/forge/pull/1086)), and system/coding-agent Azure DevOps MCP setup ([#1084](https://github.com/saif-corp/forge/pull/1084)) — with a companion fix correcting the Azure federated identity setup for the coding agent and code-review OIDC ([#1087](https://github.com/saif-corp/forge/pull/1087)).

### Guides & Reference

- **platform-typespec** - add reference documentation for `@saif/platform-typespec` ([`5aa532c9`](https://github.com/saif-corp/forge/commit/5aa532c9bb6fdb2df4bfe1e818347aeb0aa78298) | [#1063](https://github.com/saif-corp/forge/pull/1063))
- **tutorials** - close the local-to-deployed gap in onboarding ([`fa7dd92a`](https://github.com/saif-corp/forge/commit/fa7dd92a1a43c09e8a931bdf65a9c43d29539163) | [#1041](https://github.com/saif-corp/forge/pull/1041))
- Add an on-premise API proxy strangler plan and a YARP auth anti-corruption layer one-pager for the Guidewire Cloud migration ([`321dde84`](https://github.com/saif-corp/forge/commit/321dde847df0a66551d78ef749cd02f7d38070bc) | [#972](https://github.com/saif-corp/forge/pull/972), [`a32e7ae9`](https://github.com/saif-corp/forge/commit/a32e7ae92ec7a68793d6033fac05dd918b17dd07) | [#915](https://github.com/saif-corp/forge/pull/915))
- Correct the custom subdomains guide for the cloud-foundations flow ([`f460ffd0`](https://github.com/saif-corp/forge/commit/f460ffd00c0024455e507c17e40047f09a3705fa) | [#959](https://github.com/saif-corp/forge/pull/959))
- **auth** - document the client-credentials fallback for when no incoming token is present ([`44e778a0`](https://github.com/saif-corp/forge/commit/44e778a022c901df49ebabf5a2d2ff6cb29c8ce1) | [#911](https://github.com/saif-corp/forge/pull/911))
- Warn against creating a duplicate business roles repo ([`7a4bc425`](https://github.com/saif-corp/forge/commit/7a4bc4257d36331199d91e57c17b39301c8b8a94) | [#1106](https://github.com/saif-corp/forge/pull/1106))

### Cleanup

- Retire shipped/stale planning docs, distilling durable reference content, and archive the forge-v1-to-v2 migration guide ([`bf5e47ab`](https://github.com/saif-corp/forge/commit/bf5e47abb9c4ca5cc8bba72e5e32f89038320f99) | [#990](https://github.com/saif-corp/forge/pull/990), [`12217200`](https://github.com/saif-corp/forge/commit/12217200222f7d68bd1d7af60eaf122d0ae72197) | [#1019](https://github.com/saif-corp/forge/pull/1019))
- Remove the stale platform roadmap page and its remaining bullets ([`2b8d5556`](https://github.com/saif-corp/forge/commit/2b8d55563e95910c537b5eee12dd54d2dbf3efce), [`e3f1067f`](https://github.com/saif-corp/forge/commit/e3f1067f6e94e056de7685305c4186f4790091f4))
- **storage-account** - hardcode `contributor_group_id` instead of a data source lookup ([`ca2aa93d`](https://github.com/saif-corp/forge/commit/ca2aa93d5c848fd19377cfa6246b2489ea6b88c1) | [#1009](https://github.com/saif-corp/forge/pull/1009))

---

## 📦 Dependencies

Routine dependency maintenance via Dependabot: 34 PRs across NuGet and npm/yarn workspaces, including notable manual bumps of `@typespec/http-server-csharp`, `Verify.XunitV3`, `postcss`, `fast-uri`, and `@opentelemetry/auto-instrumentations-web`. See the [full commit range](https://github.com/saif-corp/forge/compare/3.8.0...3.9.0) for the complete list.

---

## 🔄 Breaking Changes

None in this release ✅

---

## 📋 Additional Notes

- Total commits: 133
- Files changed: 1156
- Contributors: Brian Sheridan, Copilot, dependabot[bot], Emmitt Johnson, Gabe Higginbotham[C], Jason Coria Corona Yue, jasyue

---

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

---
