1.0.0
π [Major]: New PowerShell module v1.0.0 with complete YAML 1.2.2 command suite (#47)
Yaml v1.0.0 is the first functional release of the Yaml PowerShell module on the PowerShell Gallery, delivering a complete YAML 1.2.2 command suite for parsing, validating, formatting, merging, reading, and writing.
New: Complete YAML 1.2.2 command suite
The module provides end-to-end YAML handling, grouped by the task you are doing.
| Group | Command | User outcome |
|---|---|---|
| Conversion | ConvertFrom-Yaml |
Parse YAML text into PowerShell objects |
| Conversion | ConvertTo-Yaml |
Serialize PowerShell objects into YAML text |
| Files | Import-Yaml |
Read YAML files directly into PowerShell objects |
| Files | Export-Yaml |
Write PowerShell objects directly to YAML files |
| Streams | Test-Yaml |
Validate YAML syntax and structure without object construction |
| Streams | Format-Yaml |
Normalize YAML text with representation-preserving, idempotent output |
| Streams | Merge-Yaml |
Deep-merge two or more YAML streams with configurable sequence, conflict, and null policies |
New: Task-based documentation with a full object-model reference
Every command group ships an in-depth guide that is published as its own documentation section: Conversion, Files, and Streams. The Conversion guide includes a complete YAML-to-PowerShell object model reference, so you can predict the exact shape a document produces before running anything β scalar tag resolution to String, Boolean, Int32/Int64/BigInteger, Decimal/Double, DateTime/DateTimeOffset and Byte[]; PSCustomObject note-properties versus -AsHashtable ordered dictionaries; -NoEnumerate; multi-document streams; anchor and alias identity; the !!set, !!omap, !!pairs and !!binary collection tags; and the cases that deliberately fail rather than silently lose data.
New: Native YAML 1.2.2 engine with no third-party dependencies
Parsing and serialization are implemented entirely in PowerShell β no YamlDotNet or other runtime dependency. The engine enforces bounded parse, clone, merge, and emit work budgets, avoids arbitrary .NET type activation, and uses iterative graph traversal to stay stable on large or adversarial inputs. Duplicate YAML mapping keys are rejected by design to prevent ambiguous data projection.
New: YAML 1.2.2 conformance across the pipeline
The scanner, parser, constructor, serializer, and emitter are validated against the YAML 1.2.2 specification, including edge cases around BOM handling, NBSP behavior, flow scalars, and tag decoding.
Technical details
- Consolidates the full YAML draft-stack delivery into
release/v1.0.0, including prior preparatory PR slices (#37, #39, #40, #41, #42, #45) and the documentation/layout slice #53. The entry-removal slice (#46) was reverted out of this branch before release, soRemove-YamlEntryis not part of the shipped surface. - Implements a fully owned PowerShell YAML 1.2.2 pipeline (scanner -> parser/composer -> constructor -> projector -> serializer -> emitter) with no YamlDotNet dependency.
- Conformance baseline uses the 402-input
yaml-test-suitecorpus plus chapter 2 fixtures undertests/fixtures/yaml-spec-1.2.2/chapter-02/. Majoris correct on the merits and not only as release framing: the diff deletessrc/functions/public/Get-PSModuleTest.ps1, and removing a previously exported command is a breaking change under PSModule Versioning. TheMajorlabel also cutsv1.0.0for the module go-live.- Two scalar defects found during the final review pass were corrected before release: folded block scalars with keep chomping (
>+) dropped theb-chomped-lastfeed and could not round-trip trailing empty lines, and double-quoted scalars folded thel-emptylines after an escaped break into a space instead of emitting line feeds. Both have regression coverage intests/ConvertFrom-Yaml.Tests.ps1. src/manifest.psd1is removed. Build-PSModule derivesPowerShellVersionandCompatiblePSEditionsfrom the#Requiresstatements it finds in the built root module and overwrites whatever a source manifest declared, and it builds an empty manifest when none exists. The two keys were dead weight duplicatingsrc/header.ps1. The built artifact is unchanged, andtests/Packaging.Tests.ps1still asserts7.6/Coredirectly on the generated manifest.- Source layout follows PSModule domain grouping: public commands live under
src/functions/public/{Conversion,Files,Streams}/, private helpers mirror those domains with a sharedEnginegroup for helpers reachable from more than one public domain, and each public group carries a<Group>.mdoverview that Document-PSModule publishes as that section's landing page.Streamsis a behavioural domain rather than a catch-all:Test-Yaml,Format-YamlandMerge-Yamlall operate on YAML text at the representation level and never project to PowerShell objects. Grouping moves the generated command pages under their group, so all 98.LINKvalues were repointed to the canonical grouped URLs.
Validation
- The full
Process-PSModulev6.1.15 pipeline is green on6ec4321(run 30757319554): plan, build module, build docs, build site, repository lint, source-code lint and tests on Linux/Windows/macOS, module lint and test on Linux/Windows/macOS, test results, and code coverage. 66 checks, 0 failures. - Per-command Pester suites run on Linux, Windows, and macOS:
ConvertFrom-Yaml,ConvertTo-Yaml,Test-Yaml,Import-Yaml,Export-Yaml,Format-Yaml, andMerge-Yaml, plusSpecification,Conformance, andPackaging. tests/Conformance.Tests.ps1runs the pinned, hash-verifiedyaml-test-suiterelease archive: 402 inputs, 400 syntax passes, 0 failures, and exactly 2 documented policy differences (2JQS,X38W) that come from rejecting duplicate mapping keys β the stricter, safer behavior this release ships. Both cases are genuine key collisions:2JQSrepeats the empty key, andX38Wuses an alias as a second key that resolves to the same node as the first. YAML 1.2.2 Β§3.2.1.1 requires mapping keys to be unique and Β§3.3.2 lists duplicate keys as a legitimate failure point, so rejecting them is intentional and is not tracked as a defect.tests/Specification.Tests.ps1covers YAML 1.2.2 chapter-2 examples 2.01 through 2.28.tests/Packaging.Tests.ps1asserts the shipped package carries noYamlDotNetor third-party license artifacts, that the generated manifest declaresPowerShellVersion = '7.6'andCompatiblePSEditions = @('Core'), that the workflow stays pinned to Process-PSModule v6.1.15, and that every function file sits under exactly one domain folder with a<Group>.mdpresent for each public group.- The object-model reference in the Conversion guide was verified by executing every documented mapping against the built command surface rather than asserted from the source, including the widening boundaries between
Int32,Int64andBigInteger,DecimalversusDoubleselection, the YAML 1.1-only forms that intentionally stay strings, timestampKind/offset behavior, and theYamlInvalidTaggedScalarfailure for a standard tag that does not match its text. - Automated review note: GitHub Copilot declined to review this pull request three times because the diff exceeds its 20,000-line limit. A compensating automated code review was run over the shipped surface (
src/**,.github/workflows/**,.github/PSModule.yml) with a differential harness against a reference parser. It found the two scalar defects listed above, which are fixed here. A third reported divergence was investigated, prototyped, and disproven β the reference parser disagrees with the official corpus there, and the module matches the corpus (see #52). Resource guards, tag handling, atomic file writes, BOM sniffing, and emitter idempotency were all clean.
Standards and framework alignment pass (Pass A)
| Changed surface | Standards checked | Framework docs checked | Result |
|---|---|---|---|
src/functions/public/{Conversion,Files,Streams}/**, src/functions/private/** |
MSX Coding Standards: PowerShell/Functions, Naming | PSModule Standards (group by domain, mirror public and private domains, group documentation pages with source) | Fixed in this PR via #53 |
src/header.ps1 (source of the runtime constraint) |
MSX Coding Standards: PowerShell/Version-Constraints | PSModule Standards, Process-PSModule module anatomy | Aligned β #Requires -Version 7.6, #Requires -PSEdition Core; redundant src/manifest.psd1 removed |
tests/** |
MSX Coding Standards: PowerShell/Testing | PSModule Standards, PSModule Test-Specification, Process-PSModule build-test-pack-publish | Fixed in this PR |
.github/workflows/**, .github/PSModule.yml, .github/linters/** |
MSX Coding Standards: GitHub Actions | Process-PSModule repository structure and build-test-pack-publish | Aligned |
README.md, src/functions/public/*/*.md, examples/** |
MSX Coding Standards: Documentation | PSModule Repository-Defaults (relocate depth only to a published home; do not duplicate generated command documentation) | Fixed in this PR via #53 |
Repository baseline files (CONTRIBUTING.md, SECURITY.md, SUPPORT.md, CODE_OF_CONDUCT.md, AGENTS.md, CLAUDE.md) |
MSX Ways of Working: Repository Standard | PSModule Repository-Defaults (required common files, managed distribution guidance) | Fixed in this PR. .github/pull_request_template.md and .github/copilot-instructions.md are Distributor-managed shared files and are deliberately not hand-authored in this repository. |
Issue convergence sweep (Pass B)
- Sweep scope: existing PR-linked candidates (
#2, #4, #5, #7, #8, #20, #21, #22, #24, #25, #26, #27, #29, #43, #44) plus targeted open-issue searches by command names, YAML chapter-2/conformance terms, and representation-preserving file and merge terms.#50was added after its delivery slice (#53) merged into this branch. - Dedupe note:
PSModule/Yaml#1is a pull request, not an issue leaf, andPSModule/Yaml#3is already closed historical work.
Convergence evidence by closed issue
PSModule/Yaml#2β core conversion surface delivered viaConvertFrom-YamlandConvertTo-Yaml, with coverage intests/ConvertFrom-Yaml.Tests.ps1andtests/ConvertTo-Yaml.Tests.ps1.PSModule/Yaml#4βTest-Yamldelivered and covered intests/Test-Yaml.Tests.ps1.PSModule/Yaml#5β deterministic stream formatting delivered viaFormat-Yaml, covered intests/Format-Yaml.Tests.ps1.PSModule/Yaml#7andPSModule/Yaml#27β flow sequence/mapping parsing delivered and covered in parser behavior tests andtests/Specification.Tests.ps1chapter-2 examples.PSModule/Yaml#8β multiline literal/folded scalar support delivered and covered intests/ConvertFrom-Yaml.Tests.ps1and chapter-2 examples.PSModule/Yaml#20β chapter-2 compliance harness delivered intests/Specification.Tests.ps1(examples 2.01 through 2.28).PSModule/Yaml#21β multi-document stream support delivered and validated in chapter-2 stream examples and command tests.PSModule/Yaml#22β anchors/aliases support delivered and verified intests/ConvertFrom-Yaml.Tests.ps1and merge behavior suites.PSModule/Yaml#24β explicit tag and!!handling delivered and covered across conversion/specification tests.PSModule/Yaml#25β complex mapping key handling delivered (including hashtable-safe paths) and covered in conversion/specification tests.PSModule/Yaml#26β core-schema numeric forms and special floats delivered and covered intests/ConvertFrom-Yaml.Tests.ps1,tests/ConvertTo-Yaml.Tests.ps1, andtests/Specification.Tests.ps1.PSModule/Yaml#29β file I/O commands delivered viaImport-YamlandExport-Yaml, covered intests/Import-Yaml.Tests.ps1andtests/Export-Yaml.Tests.ps1.PSModule/Yaml#43β representation-preserving merge delivered viaMerge-Yaml, covered intests/Merge-Yaml.Tests.ps1.PSModule/Yaml#50β domain grouping delivered via #53, which merged into this branch: public commands grouped intoConversion,FilesandStreams, private helpers mirrored into those domains plus a sharedEnginegroup, and a<Group>.mdoverview page beside each public group. Enforced by new layout assertions intests/Packaging.Tests.ps1. The closing keyword lives here because closing keywords only fire on merge to the default branch.
Deferred (not delivered in this release)
PSModule/Yaml#44β representation-preserving entry removal is intentionally out of scope for the v1.0.0 module go-live. The module surface is parse/serialize, validate, import/export, format, and merge; entry removal remains open for a future release and is kept as a non-closing reference below.PSModule/Yaml#54β theProcess-PSModuleworkflow only triggers on pull requests targetingmain, so pull requests stacked on a release branch run no checks and are not gated by themainruleset. Found while stacking #53 on this branch; #53 was instead validated by an explicit workflow dispatch and then by this pull request's own run after merging. Fixing the trigger is repository plumbing, not release content.
Relevant issues (or links)
- Fixes #2
- Closes #4
- Closes #5
- Closes #7
- Closes #8
- Closes #20
- Closes #21
- Closes #22
- Closes #24
- Closes #25
- Closes #26
- Closes #27
- Closes #29
- Closes #43
- Closes #50
- #44 (deferred: representation-preserving entry removal is out of scope for the v1.0.0 module go-live and is not delivered in this diff)
- #54 (deferred: release-stacked pull requests run no CI; repository plumbing, not release content)
- #23 (partially convergent: explicit
!!timestamphandling is delivered; implicit core-schema timestamp resolution remains open by design) - #28 (not convergent: comment-preserving
ConvertFrom-Yaml | ConvertTo-Yamlround-trip is not delivered in this diff) - #30 (partially convergent: parser/emitter hardening and budget controls shipped, but full operator-to-.NET substitution scope remains open)
- #52 (closed as not a defect while validating this release; the module matches the official corpus and the reference parser is the outlier)