diff --git a/packages/std/__tests__/_matrix/results.json b/packages/std/__tests__/_matrix/results.json
index 2a68cdd..5c94f4e 100644
--- a/packages/std/__tests__/_matrix/results.json
+++ b/packages/std/__tests__/_matrix/results.json
@@ -1,5 +1,5 @@
{
- "generatedAt": "2026-07-29",
+ "generatedAt": "2026-08-01",
"package": "@opentf/std",
"version": "0.16.0",
"runtimes": [
@@ -8,9 +8,9 @@
"label": "Node.js 20",
"version": "20.20.2",
"status": "partial",
- "passed": 1149,
+ "passed": 1501,
"failed": 1,
- "total": 1150,
+ "total": 1502,
"percent": 99.9,
"capabilities": {
"Intl.Segmenter": true,
@@ -45,9 +45,9 @@
"label": "Node.js 22",
"version": "22.23.1",
"status": "partial",
- "passed": 1149,
+ "passed": 1501,
"failed": 1,
- "total": 1150,
+ "total": 1502,
"percent": 99.9,
"capabilities": {
"Intl.Segmenter": true,
@@ -82,9 +82,9 @@
"label": "Node.js 24",
"version": "24.18.0",
"status": "pass",
- "passed": 1150,
+ "passed": 1502,
"failed": 0,
- "total": 1150,
+ "total": 1502,
"percent": 100,
"capabilities": {
"Intl.Segmenter": true,
@@ -108,11 +108,11 @@
{
"id": "node26",
"label": "Node.js 26",
- "version": "26.5.0",
+ "version": "26.5.1",
"status": "pass",
- "passed": 1207,
+ "passed": 1559,
"failed": 0,
- "total": 1207,
+ "total": 1559,
"percent": 100,
"capabilities": {
"Intl.Segmenter": true,
@@ -138,9 +138,9 @@
"label": "Bun",
"version": "1.3.14",
"status": "pass",
- "passed": 1150,
+ "passed": 1502,
"failed": 0,
- "total": 1150,
+ "total": 1502,
"percent": 100,
"capabilities": {
"Intl.Segmenter": true,
@@ -166,9 +166,9 @@
"label": "Deno",
"version": "2.9.4",
"status": "pass",
- "passed": 1207,
+ "passed": 1559,
"failed": 0,
- "total": 1207,
+ "total": 1559,
"percent": 100,
"capabilities": {
"Intl.Segmenter": true,
@@ -192,11 +192,11 @@
{
"id": "esrun",
"label": "ES-Runtime",
- "version": "0.12.0",
+ "version": "0.13.0",
"status": "pass",
- "passed": 1207,
+ "passed": 1559,
"failed": 0,
- "total": 1207,
+ "total": 1559,
"percent": 100,
"capabilities": {
"Intl.Segmenter": true,
@@ -222,10 +222,10 @@
"label": "LLRT",
"version": "0.8.0-beta",
"status": "partial",
- "passed": 1118,
- "failed": 32,
- "total": 1150,
- "percent": 97.2,
+ "passed": 1462,
+ "failed": 40,
+ "total": 1502,
+ "percent": 97.3,
"capabilities": {
"Intl.Segmenter": false,
"Intl.DateTimeFormat names": false,
@@ -298,23 +298,79 @@
"category": "runtime-deviation",
"reason": "Runtime does not perform `IteratorClose` when a `for await...of` loop exits early, so a `finally` block in an async generator never runs. Required by ECMA-262; the equivalent sync `for...of` path is handled correctly. The fix belongs in the runtime. For `streamToIter` this means a `break` neither cancels the stream nor releases the reader lock, so the stream stays locked — drain it rather than exiting early on this runtime.",
"requires": null,
- "affects": ["fromIterAsync", "streamToIter"]
+ "affects": ["fromIterAsync", "streamToIter", "zipIterAsync"]
+ },
+ {
+ "title": "Iter > zipIterAsync > closes the sources when the consumer stops early",
+ "message": "expected false to be true // Object.is equality",
+ "category": "runtime-deviation",
+ "reason": "Runtime does not perform `IteratorClose` when a `for await...of` loop exits early, so a `finally` block in an async generator never runs. Required by ECMA-262; the equivalent sync `for...of` path is handled correctly. The fix belongs in the runtime. For `streamToIter` this means a `break` neither cancels the stream nor releases the reader lock, so the stream stays locked — drain it rather than exiting early on this runtime.",
+ "requires": null,
+ "affects": ["fromIterAsync", "streamToIter", "zipIterAsync"]
},
{
"title": "Number > formatCompact",
"message": "not a function",
"category": "missing-capability",
- "reason": "Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation or currencies.",
+ "reason": "Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation, currencies, or a plain number with grouping separators.",
"requires": "Intl.NumberFormat",
- "affects": ["formatCompact", "formatCurrency"]
+ "affects": ["formatCompact", "formatCurrency", "formatNumber"]
},
{
"title": "Number > formatCurrency",
"message": "not a function",
"category": "missing-capability",
- "reason": "Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation or currencies.",
+ "reason": "Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation, currencies, or a plain number with grouping separators.",
+ "requires": "Intl.NumberFormat",
+ "affects": ["formatCompact", "formatCurrency", "formatNumber"]
+ },
+ {
+ "title": "Number > formatNumber > groups the thousands",
+ "message": "not a function",
+ "category": "missing-capability",
+ "reason": "Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation, currencies, or a plain number with grouping separators.",
+ "requires": "Intl.NumberFormat",
+ "affects": ["formatCompact", "formatCurrency", "formatNumber"]
+ },
+ {
+ "title": "Number > formatNumber > follows the locale for the separators",
+ "message": "not a function",
+ "category": "missing-capability",
+ "reason": "Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation, currencies, or a plain number with grouping separators.",
"requires": "Intl.NumberFormat",
- "affects": ["formatCompact", "formatCurrency"]
+ "affects": ["formatCompact", "formatCurrency", "formatNumber"]
+ },
+ {
+ "title": "Number > formatNumber > turns off grouping",
+ "message": "not a function",
+ "category": "missing-capability",
+ "reason": "Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation, currencies, or a plain number with grouping separators.",
+ "requires": "Intl.NumberFormat",
+ "affects": ["formatCompact", "formatCurrency", "formatNumber"]
+ },
+ {
+ "title": "Number > formatNumber > applies the fraction bounds",
+ "message": "not a function",
+ "category": "missing-capability",
+ "reason": "Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation, currencies, or a plain number with grouping separators.",
+ "requires": "Intl.NumberFormat",
+ "affects": ["formatCompact", "formatCurrency", "formatNumber"]
+ },
+ {
+ "title": "Number > formatNumber > formats a ratio as a percentage",
+ "message": "not a function",
+ "category": "missing-capability",
+ "reason": "Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation, currencies, or a plain number with grouping separators.",
+ "requires": "Intl.NumberFormat",
+ "affects": ["formatCompact", "formatCurrency", "formatNumber"]
+ },
+ {
+ "title": "Number > formatNumber > handles the awkward numbers",
+ "message": "not a function",
+ "category": "missing-capability",
+ "reason": "Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation, currencies, or a plain number with grouping separators.",
+ "requires": "Intl.NumberFormat",
+ "affects": ["formatCompact", "formatCurrency", "formatNumber"]
},
{
"title": "streamToText > splits every byte into its own chunk",
@@ -330,7 +386,7 @@
"category": "runtime-deviation",
"reason": "Runtime does not perform `IteratorClose` when a `for await...of` loop exits early, so a `finally` block in an async generator never runs. Required by ECMA-262; the equivalent sync `for...of` path is handled correctly. The fix belongs in the runtime. For `streamToIter` this means a `break` neither cancels the stream nor releases the reader lock, so the stream stays locked — drain it rather than exiting early on this runtime.",
"requires": null,
- "affects": ["fromIterAsync", "streamToIter"]
+ "affects": ["fromIterAsync", "streamToIter", "zipIterAsync"]
},
{
"title": "streamToIter > leaves the stream open under preventCancel",
@@ -338,7 +394,15 @@
"category": "runtime-deviation",
"reason": "Runtime does not perform `IteratorClose` when a `for await...of` loop exits early, so a `finally` block in an async generator never runs. Required by ECMA-262; the equivalent sync `for...of` path is handled correctly. The fix belongs in the runtime. For `streamToIter` this means a `break` neither cancels the stream nor releases the reader lock, so the stream stays locked — drain it rather than exiting early on this runtime.",
"requires": null,
- "affects": ["fromIterAsync", "streamToIter"]
+ "affects": ["fromIterAsync", "streamToIter", "zipIterAsync"]
+ },
+ {
+ "title": "String > formatList > follows the locale",
+ "message": "expected 'a, b, and c' to be 'a, b und c' // Object.is equality",
+ "category": "missing-capability",
+ "reason": "Localised list joining needs `Intl.ListFormat`. Where it is absent `formatList` falls back to the English forms rather than throwing, so only the language differs and the shape of the output is unchanged — every other `formatList` test passes on such a runtime. Only this one asserts a non-English result.",
+ "requires": "Intl.ListFormat",
+ "affects": ["formatList"]
},
{
"title": "String > stringReverse > basic reversal",
diff --git a/website/app/docs/env-support/page.mdx b/website/app/docs/env-support/page.mdx
index d06babc..f9af3c0 100644
--- a/website/app/docs/env-support/page.mdx
+++ b/website/app/docs/env-support/page.mdx
@@ -21,18 +21,18 @@ Where a runtime falls short, the cause is listed so you can tell the difference
{/* MATRIX:START */}
-_Measured on 2026-07-29 against `@opentf/std@0.16.0`, running the full suite of 1150 tests on each runtime._
+_Measured on 2026-08-01 against `@opentf/std@0.16.0`, running the full suite of 1502 tests on each runtime._
| Runtime | Version | Tests passing | Status |
| --- | --- | --- | --- |
-| Node.js 20 | `20.20.2` | 1149 / 1150 (99.9%) | ⚠️ Partial |
-| Node.js 22 | `22.23.1` | 1149 / 1150 (99.9%) | ⚠️ Partial |
-| Node.js 24 | `24.18.0` | 1150 / 1150 (100%) | Fully supported |
-| Node.js 26 | `26.5.0` | 1207 / 1207 (100%) | Fully supported |
-| Bun | `1.3.14` | 1150 / 1150 (100%) | Fully supported |
-| Deno | `2.9.4` | 1207 / 1207 (100%) | Fully supported |
-| ES-Runtime | `0.12.0` | 1207 / 1207 (100%) | Fully supported |
-| LLRT | `0.8.0-beta` | 1118 / 1150 (97.2%) | ⚠️ Partial |
+| Node.js 20 | `20.20.2` | 1501 / 1502 (99.9%) | ⚠️ Partial |
+| Node.js 22 | `22.23.1` | 1501 / 1502 (99.9%) | ⚠️ Partial |
+| Node.js 24 | `24.18.0` | 1502 / 1502 (100%) | ✅ Fully supported |
+| Node.js 26 | `26.5.1` | 1559 / 1559 (100%) | ✅ Fully supported |
+| Bun | `1.3.14` | 1502 / 1502 (100%) | ✅ Fully supported |
+| Deno | `2.9.4` | 1559 / 1559 (100%) | ✅ Fully supported |
+| ES-Runtime | `0.13.0` | 1559 / 1559 (100%) | ✅ Fully supported |
+| LLRT | `0.8.0-beta` | 1462 / 1502 (97.3%) | ⚠️ Partial |
### Node.js 20 20.20.2
@@ -64,17 +64,17 @@ Localised duration text needs `Intl.DurationFormat` and `Intl.RelativeTimeFormat
Affected utilities: `Duration`. Everything else works as expected.
-**Runtime spec deviation** (3 tests)
+**Runtime spec deviation** (4 tests)
Runtime does not perform `IteratorClose` when a `for await...of` loop exits early, so a `finally` block in an async generator never runs. Required by ECMA-262; the equivalent sync `for...of` path is handled correctly. The fix belongs in the runtime. For `streamToIter` this means a `break` neither cancels the stream nor releases the reader lock, so the stream stays locked — drain it rather than exiting early on this runtime.
-Affected utilities: `fromIterAsync`, `streamToIter`. Everything else works as expected.
+Affected utilities: `fromIterAsync`, `streamToIter`, `zipIterAsync`. Everything else works as expected.
-**Missing platform API — `Intl.NumberFormat` unavailable** (2 tests)
+**Missing platform API — `Intl.NumberFormat` unavailable** (8 tests)
-Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation or currencies.
+Number formatting needs `Intl.NumberFormat`. Runtimes built without ICU cannot format compact notation, currencies, or a plain number with grouping separators.
-Affected utilities: `formatCompact`, `formatCurrency`. Everything else works as expected.
+Affected utilities: `formatCompact`, `formatCurrency`, `formatNumber`. Everything else works as expected.
**Runtime spec deviation — `TextDecoder stream: true` unavailable** (1 test)
@@ -82,6 +82,12 @@ Runtime `TextDecoder` ignores the `stream: true` option, so the trailing bytes o
Affected utilities: `streamToText`, `streamToLines`. Everything else works as expected.
+**Missing platform API — `Intl.ListFormat` unavailable** (1 test)
+
+Localised list joining needs `Intl.ListFormat`. Where it is absent `formatList` falls back to the English forms rather than throwing, so only the language differs and the shape of the output is unchanged — every other `formatList` test passes on such a runtime. Only this one asserts a non-English result.
+
+Affected utilities: `formatList`. Everything else works as expected.
+
**Missing platform API — `Intl.Segmenter` unavailable** (20 tests)
Grapheme segmentation needs `Intl.Segmenter`. Runtimes built without full ICU cannot count, reverse or wrap multi-codepoint characters correctly. Text that is entirely printable ASCII is measured without segmenting and works everywhere.