AppSurface Search
API Reference

Release

Type

ReleaseTaggedProjectionResolver

Source

Resolves prepared release artifacts into a tagged projection bound to an annotated Git tag.

Remarks

This is the single authority for the prepared-to-tagged transition. It reads tag objects and artifact blobs through Git, validates the checked-in evidence bundle and canonical tag trailers, then returns an in-memory sidecar projection. It never mutates repository files, creates tags, or calls GitHub.

Method

GenerateTagMessageAsync

Task<string> GenerateTagMessageAsync(SemVer version, CancellationToken cancellationToken)

Generates canonical annotated-tag trailers from the prepared artifacts at HEAD.

Parameters

  • version
    Release version whose prepared artifacts are read from HEAD.
  • cancellationToken
    Cancellation token.

Returns

Canonical trailer block with a trailing newline.

Method

ResolveAsync

Task<ReleaseTaggedProjection> ResolveAsync(ReleaseOptions options, CancellationToken cancellationToken)

Resolves and validates the tag-bound tagged projection for inspect and publish.

Parameters

  • options
    Release command options containing the canonical version, tag, and base ref.
  • cancellationToken
    Cancellation token.

Returns

Validated immutable tag details and transient tagged sidecar YAML.

Type

ReleaseTagArtifacts

Source

Exact release artifacts read from one Git revision.

Type

ReleaseTaggedProjection

Source

Result of a successful prepared-to-tagged projection resolution.

Type

ReleaseEvidenceV2

Source

Schema-v2 release evidence implementation for frozen coordinated release pointers.

Remarks

This type deliberately has its own JSON shape and reader. A v2 bundle must never be deserialized as the v1 shape: v1 could silently omit the current-pointer fields that make a versioned documentation tree historically honest.

Method

RefreshSubject

ReleaseEvidenceBundleV2 RefreshSubject(ReleaseEvidenceBundleV2 bundle)

Recomputes the v2 subject after a maintainer or workflow supplies catalog-bound docs archive fields.

Remarks

The release-preparation draft intentionally leaves stable docs archive proof unconfigured until the staged exact tree exists. Callers that add that proof must refresh the subject rather than hand-editing its digest.

Type

ReleaseEvidenceBundleV2

Source
Method

ToCompatibilityBundle

ReleaseEvidenceBundle ToCompatibilityBundle()

Adapts already-parsed v2 docs archive fields for the existing archive gate; this is not JSON deserialization.

Type

ReleaseEvidenceSubjectCommitsV2

Source

The immutable commit identity included in the V2 evidence subject digest.

Remarks

The reviewed preparation source is stable release evidence. Later preparation, tag, and workflow identities are intentionally excluded because they are supplied after the preparation artifact set is generated.

Type

ReleaseCommandBase

Source

Shared CliFx option surface and diagnostic handling for release commands.

Method

ExecuteWithDiagnosticsAsync

ValueTask ExecuteWithDiagnosticsAsync(IConsole console, Func<ReleaseOptions, CancellationToken, Task<int>> executeAsync)

Runs command logic with release diagnostic rendering.

Parameters

  • console
    CliFx console.
  • executeAsync
    Command implementation.

Returns

A task that completes after command execution.

Method

CreateServices

ReleaseServices CreateServices(ReleaseOptions options)

Creates service objects for the resolved repository root.

Parameters

  • options
    Resolved command options.

Returns

Workspace, checker, preparation, tagged projection resolver, and publishing services.

Method

ResolveTag

string? ResolveTag(SemVer version)

Resolves the command tag, when relevant.

Parameters

  • version
    Parsed release version.

Returns

The tag value, or null for commands that do not use a tag.

Method

ResolveGitHubOutputPath

string? ResolveGitHubOutputPath(string repoRoot)

Resolves the GitHub Actions output path, when relevant.

Parameters

  • repoRoot
    Resolved repository root.

Returns

The output path, or null for commands that do not write workflow outputs.

Method

ResolveDocsCatalogPath

string? ResolveDocsCatalogPath(string repoRoot)

Resolves the AppSurface Docs version catalog path, when the command supports stable docs evidence verification.

Parameters

  • repoRoot
    Resolved repository root.

Returns

The catalog path, or null when the command does not accept docs catalog input.

Remarks

Overrides should resolve relative option values from repoRoot instead of the process working directory so local shells, CI jobs, and generated reports all describe the same artifact. Return null for commands that do not verify stable docs evidence, and for check when callers want the local dist/docs/versions.json fallback. Stable publish callers should prefer an explicit staged catalog path because checkout-local docs may not be the artifact being published.

Method

ResolveDocsTrustedReleaseRootPath

string? ResolveDocsTrustedReleaseRootPath(string repoRoot)

Resolves the trusted release root path used to interpret docs catalog exact-tree paths.

Parameters

  • repoRoot
    Resolved repository root.

Returns

The trusted release root, or null to default to the catalog directory.

Remarks

Overrides should resolve relative option values from repoRoot . Returning null tells the verifier to derive the trusted root from the catalog directory, which is the right default for colocated review artifacts. Pass an explicit root when the catalog is staged beside, but not above, the exact release trees; otherwise catalog exactTreePath values may resolve as missing or unsafe.

Method

ResolveBaseRef

string ResolveBaseRef()

Resolves the branch name used for publish-time reachability and source workflow checks.

Returns

The base branch name for release validation. Commands default to main ; publish accepts branch-ish inputs such as release/0.1.0 , origin/release/0.1.0 , refs/heads/release/0.1.0 , or refs/remotes/origin/release/0.1.0 and normalizes them before validators query origin/<branch> . Tags and commit SHAs are not valid base refs because publish validation must prove protected branch reachability.

Method

WriteReportAsync

Task WriteReportAsync(ReleaseOptions options, string rendered, TextWriter standardOut, CancellationToken cancellationToken)

Writes the rendered command report to stdout and to the optional report path.

Parameters

  • options
    Resolved command options.
  • rendered
    Rendered Markdown report.
  • standardOut
    Standard output writer.
  • cancellationToken
    Cancellation token.

Returns

A task that completes after the report is written.

Property

VersionText

string? VersionText { get; set; } Source

Gets the SemVer 2.0 release version without a leading v .

Property

DateText

string? DateText { get; set; } Source

Gets the release date for prepare, formatted as YYYY-MM-DD .

Property

DryRun

bool DryRun { get; set; } Source

Gets a value indicating whether the command should avoid repository mutations or publishing.

Property

RepositoryRoot

string? RepositoryRoot { get; set; } Source

Gets the repository root. Defaults to the current directory.

Property

ReportPath

string? ReportPath { get; set; } Source

Gets an optional readiness report output path.

Property

CommandName

string CommandName { get; } Source

Gets the command name used by release validation logic.

Property

FailOnWarnings

bool FailOnWarnings { get; } Source

Gets whether this command should turn warning diagnostics into a failing exit code.

Property

AllowExistingTargets

bool AllowExistingTargets { get; } Source

Gets whether this command may review already-generated release artifacts.

Type

ReleaseServices

Source

Command services bound to a resolved workspace.

Parameters

  • Workspace
    Workspace path helper.
  • Checker
    Readiness checker.
  • Preparation
    Release preparation workflow.
  • TaggedProjectionResolver
    Prepared-to-tagged projection resolver.
  • Publishing
    Release publishing workflow.
Type

ChangelogEditor

Source
Method

RollForward

string RollForward(string changelog, SemVer version, DateOnly date, string releasePath)

Resets the compact Unreleased ledger and inserts a tagged changelog section after it.

Parameters

  • changelog
    Existing changelog content. Canonical input contains a single ## Unreleased heading.
  • version
    Release version inserted as ## {version} - yyyy-MM-dd .
  • date
    Release date rendered with invariant yyyy-MM-dd formatting.
  • releasePath
    Repository-relative release note path linked from the new section.

Returns

Updated changelog content with a reset Unreleased section and the tagged section inserted or appended.

Remarks

The algorithm is intentionally text-based to preserve surrounding Markdown. The detailed release narrative lives in releases/unreleased.md before preparation and releases/v{version}.md after preparation; the changelog keeps only the durable compact ledger. If ## Unreleased is missing, the canonical compact section is appended before the new tagged section. If the first-release placeholder follows ## Unreleased , that placeholder block is replaced. Duplicate release sections are not de-duplicated; callers should run readiness checks before calling this method. Malformed heading hierarchies and concurrent changelog edits can therefore produce surprising placement, so this helper should only be used on the repository's canonical changelog shape.

Type

ICommandRunner

Source

Command runner abstraction for git and GitHub CLI calls.

Method

RunAsync

Task<CommandResult> RunAsync(CommandInvocation invocation, CancellationToken cancellationToken)

Runs a process and captures stdout and stderr.

Parameters

  • invocation
    Command invocation.
  • cancellationToken
    Cancellation token.

Returns

Command result.

Type

ProcessCommandRunner

Source

Process command runner used by the default CLI.

Type

IReleaseClock

Source

Clock abstraction used by tests to make generated release dates deterministic.

Method

TodayUtc

DateOnly TodayUtc()

Gets today's UTC date.

Returns

UTC date.

Type

SystemReleaseClock

Source

System clock used by the default CLI.

Type

ReleaseManifestV2Validator

Source

Dispatches and validates the schema-v2 release-manifest contract before evidence consumes it.

Remarks

This deliberately performs raw JSON validation before typed deserialization. System.Text.Json otherwise ignores unknown fields, which would make an accidental V1/V2 hybrid look valid even though the checked-in JSON schemas forbid it.

Method

TryValidatePackageSet

bool TryValidatePackageSet(ReleaseManifestV2 manifest, IReadOnlyList<PackageIndexEntry> packages, out string issue)

Confirms that a V2 manifest attests to exactly the release surface declared by the package index.

Parameters

  • manifest
    The already validated V2 manifest.
  • packages
    Public publish package rows from the same release tree.
  • issue
    The mismatch explanation when validation fails.

Returns

true when the manifest and package index describe the same release surface.

Type

ReleaseCliModule

Source

AppSurface Console root module for the release cockpit.

Type

ReleaseExecutionContext

Source

Per-invocation execution context supplied by the CLI entry point.

Parameters

  • CurrentDirectory
    Directory used to resolve default repository-relative paths.
Type

ReleaseNoteBuilder

Source
Method

EnsureAppSurfaceUnreleasedEntryMarkers

void EnsureAppSurfaceUnreleasedEntryMarkers(string unreleasedTemplate)

Verifies the repository-owned living-note layout before generic entry composition begins.

Parameters

  • unreleasedTemplate
    Raw AppSurface living-note template.

Exceptions

  • UnreleasedEntryException
    Thrown when an AppSurface-required section marker is absent or repeated.

Remarks

The public composer intentionally lets consumer templates define their own sections. AppSurface release preparation has a stricter contract because its reset placeholders, sidecar narrative, and release review guidance own the taking-shape , included , and migration-watch sections. Keep that repository policy here rather than constraining consumer projects through the public command.

Method

StripResetOnlyTemplatePlaceholders

string StripResetOnlyTemplatePlaceholders(string unreleasedTemplate)

Removes reset-only template bullets directly before their canonical entry markers.

Parameters

  • unreleasedTemplate
    The raw unreleased template, before append-only entries are composed.

Returns

The template with canonical reset-only bullets removed while preserving source line endings.

Remarks

This must run before UnreleasedEntryComposer.Compose , because composition replaces the markers that identify canonical template bullets. The narrow structural match deliberately skips fenced code and HTML blocks so examples or embedded markup can use the same text without being rewritten.

Method

Build

string Build(SemVer version, DateOnly date, string unreleased)

Converts the living unreleased note into a tagged release note.

Parameters

  • version
    Release version rendered in the heading and generated comment.
  • date
    Release date rendered with invariant yyyy-MM-dd formatting.
  • unreleased
    Unreleased Markdown content. Canonical input starts with an exact # Unreleased heading.

Returns

Tagged release Markdown with a generated comment header and a trailing newline.

Remarks

The method first parses Markdown to catch syntax problems, but it does not use the returned syntax tree to rewrite content. It then replaces only the exact top-level # Unreleased heading without consuming its following blank line and two known narrative phrases using ordinal matching. Release preparation removes reset-only placeholders from the raw template before composing entries. Variants in casing or wording are left unchanged. Output is deterministic apart from the supplied version and date, uses Environment.NewLine for generated sections, and trims trailing whitespace from the source body. Callers should run release readiness checks first because duplicate headings, missing phrases, or concurrently edited Markdown are not treated as errors.

Method

ResetUnreleased

string ResetUnreleased(SemVer previousVersion)

Creates the next-cycle unreleased proof artifact.

Parameters

  • previousVersion
    Version that just moved into tagged release files.

Returns

Canonical unreleased Markdown for the next cycle, including the previous version reference and a trailing newline.

Remarks

This reset intentionally discards the prior living-release body after it has been copied into a tagged release note. It preserves the expected section order for future checks: overview, shaping work, included changes, and migration watch.

Method

BuildCurrentReleasePointer

string BuildCurrentReleasePointer(SemVer version)

Builds the tree-local pointer used by coordinated package and documentation links.

Parameters

  • version
    The immutable tagged release selected by this pointer.

Returns

Deterministic Markdown that links to the exact release note.

Remarks

Do not replace this link with a global release lookup. Release archives copy this file into their immutable exact trees; a historical current route must therefore point to the release that was current when that tree was published.

Property

UnreleasedTemplatePlaceholders

IReadOnlyList<string> UnreleasedTemplatePlaceholders { get; } Source

Gets the reset-only placeholder bullets that must not appear in a tagged release note.

Type

ReleaseWorkspace

Source

Repository path helper for release-owned files.

Remarks

Paths are rooted under RepositoryRoot and accept slash-separated repository-relative inputs. PathFor rejects rooted paths and traversal that would escape the repository. Use IsUnderPath when checking paths that come from command-line input, temporary files, or other untrusted sources.

Method

ReleaseNotePath

string ReleaseNotePath(SemVer version)

Gets the absolute path for a release note file.

Parameters

  • version
    Release version.

Returns

Absolute release note path.

Method

ReleaseSidecarPath

string ReleaseSidecarPath(SemVer version)

Gets the absolute path for a release note sidecar file.

Parameters

  • version
    Release version.

Returns

Absolute sidecar path.

Method

ReleaseManifestPath

string ReleaseManifestPath(SemVer version)

Gets the absolute path for a release manifest file.

Parameters

  • version
    Release version.

Returns

Absolute manifest path.

Method

ReleaseEvidencePath

string ReleaseEvidencePath(SemVer version)

Gets the absolute path for a release evidence bundle file.

Parameters

  • version
    Release version.

Returns

Absolute release evidence bundle path.

Method

PathFor

string PathFor(string relativePath)

Resolves a repository-relative path and verifies that the result stays inside the repository root.

Parameters

  • relativePath
    Repository-relative path using slash separators and no leading root.

Returns

Absolute path under RepositoryRoot .

Exceptions

  • ArgumentException
    Thrown when relativePath is rooted or traverses outside the repository.
Method

DisplayPath

string DisplayPath(string path)

Formats an absolute path as a slash-normalized repository-relative path.

Parameters

  • path
    Absolute path.

Returns

Repository-relative path when possible.

Method

IsUnderPath

bool IsUnderPath(string root, string path)

Determines whether a path is under the supplied root.

Parameters

  • root
    Root path.
  • path
    Candidate path.

Returns

true when the path is equal to or below the root.

Property

RepositoryRoot

string RepositoryRoot { get; } Source

Gets the absolute repository root.

Property

ChangelogPath

string ChangelogPath { get; } Source

Gets the absolute changelog path.

Property

UnreleasedPath

string UnreleasedPath { get; } Source

Gets the absolute unreleased note path.

Property

UnreleasedEntriesDirectory

string UnreleasedEntriesDirectory { get; } Source

Gets the absolute append-only unreleased-entry directory.

Remarks

Feature pull requests add independently named Markdown entries here instead of editing the living-note template. Release preparation composes and archives the entries, then removes only the entries it consumed.

Property

UnreleasedSidecarPath

string UnreleasedSidecarPath { get; } Source

Gets the absolute unreleased sidecar path.

Property

CurrentReleasePath

string CurrentReleasePath { get; } Source

Gets the absolute current coordinated release pointer path.

Remarks

This pointer is overwritten only by release preparation. Once docs are exported, its bytes live inside that exact tree, so the same releases/current.md route stays frozen to the release represented by the tree.

Property

CurrentReleaseSidecarPath

string CurrentReleaseSidecarPath { get; } Source

Gets the absolute permanent current coordinated release pointer metadata sidecar path.

Property

PackageIndexPath

string PackageIndexPath { get; } Source

Gets the absolute package index manifest path.

Property

TemplatePath

string TemplatePath { get; } Source

Gets the absolute tagged-release template path.

Type

ReleasePreparationChange

Source

A single entry from git diff --name-status .

Parameters

  • Status
    The Git status code, such as A , M , D , or R100 .
  • Path
    The current path reported by Git.
  • OriginalPath
    The original path for a rename, when Git reported one.
Type

ReleasePreparationChangePolicyResult

Source

Result of validating the exact release-preparation change set.

Property

IsValid

bool IsValid { get; } Source

Gets whether the diff is exactly the generated release artifacts and next-cycle rollover files for the requested version.

Type

ReleasePreparationChangePolicy

Source

Enforces the narrow change contract for a release-preparation pull request.

Remarks

The policy applies to the complete Git diff between the pull request base and head. It intentionally excludes releases/current.md.yml : that sidecar is permanent, version-independent metadata and must never be regenerated or changed by release preparation.

Method

Validate

ReleasePreparationChangePolicyResult Validate(string version, IEnumerable<ReleasePreparationChange> changes, IEnumerable<string>? consumedUnreleasedEntryPaths = null)

Validates that the diff contains the versioned release artifacts, frozen current pointer, changelog, and next-cycle files for version .

Parameters

  • version
    Release version without a leading v .
  • changes
    Complete Git name-status diff.
  • consumedUnreleasedEntryPaths
    The exact entry paths the versioned release manifest declares as composed and archived.

Returns

Validation errors, or an empty result when the diff is valid.

Method

ParseNameStatus

IReadOnlyList<ReleasePreparationChange> ParseNameStatus(string nameStatusOutput)

Parses tab-delimited output from git diff --name-status --find-renames .

Parameters

  • nameStatusOutput
    Git name-status output.

Returns

Parsed change entries.

Type

ReleaseOptions

Source

Parsed release CLI options shared by every command.

Parameters

  • Command
    Release command name controlling command-specific validation.
  • RepositoryRoot
    Canonical repository root used to resolve relative paths.
  • Version
    SemVer release identity without a leading v .
  • Tag
    Optional annotated tag used by publish.
  • Date
    Optional release date used by prepare.
  • DryRun
    Whether the command should validate without mutating repository or GitHub state.
  • ReportPath
    Optional Markdown report output path.
  • GitHubOutputPath
    Optional GitHub Actions output file used by publish.
  • FailOnWarnings
    Whether check should fail when warning diagnostics are present.
  • AllowExistingTargets
    Whether check may review already-generated release artifacts.
  • BaseRef
    Publish branch that must contain the release tag commit.
  • DocsCatalogPath
    Optional staged AppSurface Docs versions.json used for stable docs evidence verification. check may leave this null to use the local dist/docs/versions.json fallback; release publication should use the docs-publication command for the public archive/catalog path.
  • DocsTrustedReleaseRootPath
    Optional trusted release root for catalog exact-tree paths. When null, verification defaults to the catalog directory; callers should pass it when the staged exact trees live elsewhere.
Type

SemVer

Source

Minimal SemVer 2.0 model used by release automation.

Method

Parse

SemVer Parse(string value)

Parses a release version and rejects leading-v tags, build metadata, and invalid SemVer shapes.

Parameters

  • value
    Version string supplied by the user.

Returns

The parsed version.

Method

TryParse

bool TryParse(string value, out SemVer? version)

Tries to parse a SemVer value without producing a command-line diagnostic.

Parameters

  • value
    Version text without the tag prefix.
  • version
    Parsed version when the input is valid.

Returns

true when the input is a supported SemVer value.

Method

CompareTo

int CompareTo(SemVer? other)

Compares two versions with SemVer 2.0 precedence.

Parameters

  • other
    The version to compare.

Returns

A negative value, zero, or a positive value according to SemVer precedence.

Property

IsStable

bool IsStable { get; } Source

Gets whether the version is a stable SemVer identity.

Property

IsProtectedPrereleaseWorkflowCompatible

bool IsProtectedPrereleaseWorkflowCompatible { get; } Source

Gets whether this prerelease version can trigger the protected prerelease package workflow.

Property

TagName

string TagName { get; } Source

Gets the annotated git tag expected for this version.

Type

Program

Source

CLI entry point for AppSurface release preparation and publishing validation.

Method

Main

Task<int> Main(string[] args)

Launches the release CLI with process IO streams.

Parameters

  • args
    Command-line arguments supplied to the process.

Returns

Process exit code where 0 indicates success.

Method

RunAsync

Task<int> RunAsync(string[] args, TextWriter standardOut, TextWriter standardError, string currentDirectory, CancellationToken cancellationToken = default, ICommandRunner? commandRunner = null, IReleaseClock? clock = null)

Runs the release CLI against supplied IO streams and an explicit working directory.

Parameters

  • args
    Command-line arguments, including command and options.
  • standardOut
    Writer that receives reports, structured output, and help.
  • standardError
    Writer that receives diagnostic envelopes and invalid usage.
  • currentDirectory
    Directory used to resolve repository-relative defaults.
  • cancellationToken
    Cancellation token for file and process work.
  • commandRunner
    Optional command runner seam used by tests.
  • clock
    Optional clock seam used by tests.

Returns

0 for success; otherwise a non-zero exit code.

Type

ReleaseTagBinding

Source

Canonical annotated-tag binding for one prepared AppSurface release.

Remarks

The binding repeats the prepared sidecar and manifest digests alongside the release evidence subject so a maintainer can identify the mismatched artifact directly. It is not a replacement for the checked-in evidence bundle; the resolver validates both sources and uses the tag object as the immutable state-transition record.

Method

Render

string Render()

Renders the exact trailing message block accepted by the resolver.

Returns

Canonical four-line trailer block with a trailing newline.

Method

ParseAndValidate

void ParseAndValidate(string tag, string tagObject, ReleaseTagBinding expected)

Parses a Git tag object and validates its final AppSurface release trailer block.

Parameters

  • tag
    Annotated tag name used in diagnostics.
  • tagObject
    Raw output from git cat-file -p.
  • expected
    Expected binding computed from tagged artifact bytes.
Method

ParseTaggerTimestamp

DateTimeOffset ParseTaggerTimestamp(string tag, string tagObject)

Reads the tagger timestamp from a raw annotated Git tag object.

Parameters

  • tag
    Annotated tag name used in diagnostics.
  • tagObject
    Raw output from git cat-file -p.

Returns

Timestamp and offset recorded by the annotated tagger.

Property

RequiredKeyCount

int RequiredKeyCount { get; } Source

Gets the number of canonical trailers required to bind a tagged release.

Type

CoverageAnchor

Source

Prevents trimming coverage from depending on generated process-start wiring.

Type

ReleasePreparation

Source

Creates release artifacts from the living unreleased note.

Method

PrepareAsync

Task<ReleasePreparationResult> PrepareAsync(ReleaseOptions options, CancellationToken cancellationToken)

Generates release files or, in dry-run mode, returns the planned edits.

Parameters

  • options
    Release command options. Date defaults to the injected clock when omitted.
  • cancellationToken
    Cancellation token.

Returns

Preparation result containing readiness diagnostics and planned or written repository-relative paths.

Remarks

Preparation is a deterministic repository-file rewrite: it runs readiness checks, reads the unreleased note and sidecar, builds versioned release artifacts, refreshes the frozen tree-local current pointer, rolls CHANGELOG.md , resets unreleased files, removes consumed append-only unreleased entries, and records diagnostics in the release manifest. Coordinated package rows are intentionally not rewritten: each docs export freezes the current pointer that was generated for its release. Dry-run mode performs all reads and rendering but does not write files. The method does not create git branches, tags, commits, package artifacts, or GitHub Releases; workflows own those operations. Callers should treat any readiness errors as blocking and should avoid running against a dirty or concurrently modified tree. Writes are sequential rather than transactional. The current pointer is written last, so a partial write cannot advance the visible coordinated alias before the matching versioned artifacts and living-note roll-forward exist. If the local process fails, rerun git status and remove or revert the partial generated artifacts before retrying so create-only target checks do not stop the next run.

Method

ArchiveUnreleasedEntryAsync

Task ArchiveUnreleasedEntryAsync(UnreleasedEntrySnapshot snapshot, CancellationToken cancellationToken)

Removes one consumed entry without deleting a concurrently replaced file.

Remarks

Filesystem deletion is pathname-based, so a digest check immediately followed by File.Delete(string) could delete a replacement written in the intervening window. The guarded handoff atomically moves the current pathname to a private recovery location, verifies the moved bytes, and deletes only that verified private file. When the bytes differ, it restores the candidate without overwrite; if another writer already recreated the source pathname, the changed candidate remains in the recovery location for manual reconciliation instead of being lost.

Type

CommandInvocation

Source

Immutable command invocation for release-owned external processes.

Parameters

  • Executable
    Executable name or absolute path.
  • Arguments
    Argument list passed without shell evaluation.
  • WorkingDirectory
    Working directory used for the process.
  • Timeout
    Optional wall-clock timeout. When omitted, release commands use the default bounded timeout.
Type

CommandResult

Source

Captured command result.

Type

ReleaseCheckResult

Source

Release readiness result.

Property

HasErrors

bool HasErrors { get; } Source

Gets whether the report contains errors.

Type

ReleasePreparationResult

Source

Release preparation result.

Property

ArchivedUnreleasedEntryPaths

IReadOnlyList<string> ArchivedUnreleasedEntryPaths { get; init; } Source

Gets the append-only unreleased entries that preparation plans to archive or archived during a real run.

Remarks

These paths are intentionally separate from generated artifacts: recovery must restore them to their pre-run state, whereas generated files may be removed or restored before a retry.

Type

ReleaseManifest

Source

Machine-readable release manifest.

Type

ReleaseManifestV2

Source

Machine-readable schema-v2 release manifest for frozen coordinated release links.

Remarks

V2 deliberately retains V1 as a separate type so checked-in historical manifests are never deserialized through a newer contract. Its package resolutions record the tree-local alias and the immutable tagged note it resolves to at preparation time.

Property

ConsumedUnreleasedEntryPaths

IReadOnlyList<string> ConsumedUnreleasedEntryPaths { get; init; } Source

Gets the append-only unreleased-entry paths composed into this release and removed during preparation.

Remarks

The V2 evidence bundle digests this manifest, so this ordered list is the proof that a release-preparation pull request may delete precisely these source entries and no others.

Type

CoordinatedPackageReleaseNoteResolution

Source

Records how a public package's coordinated release alias resolves in the prepared documentation tree.

Parameters

  • Project
    Repository-relative project path for the public package.
  • Source
    Resolution source. Schema V2 accepts only coordinated .
  • AliasPath
    Tree-local alias path used by coordinated package documentation.
  • ResolvedPath
    Immutable versioned release-note path selected by the alias in this documentation tree.
  • ReleaseTag
    Annotated release tag for the immutable note.
  • PreparationBaseCommit
    Preparation base commit; null only while a draft has not yet been bound to a concrete repository commit.
Type

PackagePathUpdate

Source

Package release note path update recorded in the release manifest.

Type

ReleaseDiagnosticRecord

Source

Serializable diagnostic record for release manifests.

Method

FromDiagnostic

ReleaseDiagnosticRecord FromDiagnostic(ReleaseDiagnostic diagnostic)

Creates a serializable diagnostic record.

Parameters

  • diagnostic
    Source diagnostic.

Returns

Serializable record.

Type

PublishOutputs

Source

Structured publish outputs for GitHub Actions.

Type

ReleaseEvidenceSummary

Source

Maintainer-facing release evidence summary rendered in command reports and workflow outputs.

Parameters

  • Path
    Repository-relative evidence bundle path.
  • Schema
    Evidence bundle schema.
  • Status
    Draft or tag-bound validation status.
  • SubjectSha256
    Stable subject digest for the evidence bundle.
  • DocsReleaseManifestSha256
    Optional AppSurface Docs archive manifest digest referenced by the evidence bundle.
  • CatalogExactTreePath
    Optional catalog exact tree path referenced by the evidence bundle.
  • DocsArchiveVerificationState
    Stable docs archive verification state from the checked catalog/archive inputs.
  • DocsCatalogPath
    Physical catalog input used to verify stable docs evidence.
  • DocsTrustedReleaseRootPath
    Physical trusted release root used to resolve catalog exact-tree paths.
  • DocsPhysicalExactTreePath
    Physical exact-tree path verified against the catalog pin.
  • DocsVerifiedFileCount
    Number of archive files verified from the release manifest.
  • TagCommit
    Optional tag commit validated at publish time.
  • Attestation
    Attestation requirement state.
Type

ReleaseVerifyPreparationDiffCommand

Source

Verifies the complete release-preparation pull-request diff from a base ref to the checked-out HEAD.

Remarks

This command is the supported local and CI entry point for release-preparation provenance. Normal callers should use ./eng/release verify-prep-diff --base-ref main ; --witness exists only as a controlled test/CI seam.

Property

RepositoryRoot

string? RepositoryRoot { get; set; } Source

Gets the repository root. Defaults to the command invocation directory.

Property

BaseRef

string? BaseRef { get; set; } Source

Gets the base branch or ref. The default is main , fetched as origin/main .

Property

NoFetch

bool NoFetch { get; set; } Source

Gets whether to skip the base-ref refresh for an intentionally offline, already-current checkout.

Property

WitnessPath

string? WitnessPath { get; set; } Source

Gets an optional pre-created PackageIndex witness path used only by controlled CI/test integrations.

Property

ReportPath

string? ReportPath { get; set; } Source

Gets an optional Markdown report destination.

Type

ReleasePreparationDiffReportRenderer

Source

Markdown renderer for ReleasePreparationDiffResult .

Method

Render

string Render(ReleasePreparationDiffResult result)

Renders the full-diff identity, changes, and structured diagnostics without allowing diff content to alter the table shape.

Parameters

  • result
    Classified release-preparation diff.

Returns

Stable Markdown report suitable for the GitHub step summary.

Type

ReleaseProjectionOutputWriter

Source

Writes tagged release projections through retained directory handles.

Remarks

Every directory component is opened without following links and remains open until the temporary file is atomically renamed. Unix uses openat and renameat relative to the retained descriptor. Windows retains non-delete-sharing directory handles, which pins the traversed path while the temporary file is created, and uses a relative FILE_RENAME_INFO target for replacement.

Method

WriteAsync

Task WriteAsync(string outputPath, string yaml, CancellationToken cancellationToken)

Creates the output directory securely and atomically replaces the target projection.

Parameters

  • outputPath
    Absolute logical path to the output file.
  • yaml
    UTF-8 YAML content to write.
  • cancellationToken
    Token that cancels before the replacement is committed.
Method

UseDirectoryOpenedHookForTesting

IDisposable UseDirectoryOpenedHookForTesting(Action<string> callback)

Runs a callback after the target directory is safely opened and before the temporary file is created.

Parameters

  • callback
    Callback used by tests to simulate a parent-directory replacement race.

Returns

A scope that restores the previous callback.

Remarks

The callback is async-flow-local so concurrent tests cannot alter another write. Production code leaves the callback unset.

Method

UseTemporaryFileOpenedHookForTesting

IDisposable UseTemporaryFileOpenedHookForTesting(Action callback)

Runs a callback after the temporary output file is created and before its content is written.

Parameters

  • callback
    Callback used by tests to deterministically cancel a write after temporary-file creation.

Returns

A scope that restores the previous callback.

Remarks

The callback is async-flow-local so concurrent tests cannot alter another write. Production code leaves the callback unset.

Method

UseUnixFChmodFailureForTesting

IDisposable UseUnixFChmodFailureForTesting(int error)

Forces Unix temporary-file permission hardening to fail with a specified native error code.

Parameters

  • error
    Non-zero native error code returned by the test-only failure seam.

Returns

A scope that restores the previous failure seam.

Remarks

The seam is async-flow-local so tests can verify cleanup after a permission-hardening failure without depending on host filesystem behavior. Production code leaves the seam unset and calls fchmod directly.

Method

NormalizePlatformPath

string NormalizePlatformPath(string path, bool? isMacOs = null)

Canonicalizes fixed macOS temporary-directory aliases before no-follow traversal.

Parameters

  • path
    Absolute path to canonicalize.
  • isMacOs
    Optional platform override used by focused tests.

Returns

The physical macOS temporary path or the original path on other platforms.

Type

ReleaseDocsPublication

Source

Creates deterministic AppSurface Docs release archives, version catalogs, Pages staging payloads, and maintainer recovery summaries.

Remarks

This planner is the release-tool owned boundary between a tag-local AppSurface Docs export and the public publication workflow. It does not deploy Pages or mutate GitHub Releases directly; instead it emits deterministic local artifacts that GitHub Actions uploads, deploys, verifies, and promotes in separate jobs. Callers must provide an already-exported exact tree for the tag, a disposable Pages staging root, and output paths that do not overlap the exact tree. Supplying DocsPublicationRequest.ExistingPagesRoot means prior Pages content is required and will be copied before the new immutable releases/{version}/ tree is staged. The staging root is deleted and recreated during planning, so it must never point at the repository, an exact tree, or any durable artifact directory.

Method

CreateAsync

Task<DocsPublicationPlan> CreateAsync(DocsPublicationRequest request, CancellationToken cancellationToken)

Produces the release docs publication plan and all local artifacts the publish workflow transports.

Parameters

  • request
    Publication request from the release workflow, including exact-tree input, output paths, optional existing Pages content, and promotion policy.
  • cancellationToken
    Cancellation token for file reads, writes, and hash computation.

Returns

The completed publication plan that names every generated artifact and the recovery summary path.

Remarks

The method validates the tag/version pairing, verifies the exact-tree release manifest digest against release evidence when supplied, writes a deterministic .tar.gz plus .sha256 , resets the Pages staging directory, copies existing Pages content when requested, writes the merged catalog, and emits a recovery summary. It rejects missing existing Pages roots, output paths under the exact tree, and reparse-point entries so a release archive cannot accidentally include generated output or follow a symlink outside the trusted tree.

Method

WriteOutputsAsync

Task WriteOutputsAsync(DocsPublicationPlan plan, string? githubOutputPath, CancellationToken cancellationToken)

Writes GitHub Actions outputs for the generated publication plan.

Parameters

  • plan
    Completed docs publication plan.
  • githubOutputPath
    Optional GitHub Actions output path.
  • cancellationToken
    Cancellation token.
Type

DocsPublicationRequest

Source

Request for creating docs publication artifacts.

Parameters

  • Version
    Release version without a leading v . Stable versions may become recommendedVersion .
  • Tag
    Annotated tag name that must equal v{Version} .
  • ExactTreePath
    Exported AppSurface Docs exact tree for this tag. It must already contain the release manifest.
  • ExistingPagesRoot
    Optional existing Pages payload to preserve. When supplied, the directory must exist.
  • ArchivePath
    Output path for the deterministic docs archive. The sibling temporary .tar path must also be outside the exact tree.
  • PagesStagingRoot
    Disposable output directory for the merged Pages payload. It is deleted and recreated.
  • PlanPath
    Output path for the machine-readable publication plan.
  • SummaryPath
    Optional output path for the maintainer recovery summary.
  • ExpectedReleaseManifestSha256
    Optional release evidence digest that the exact-tree manifest must match.
  • PromoteRecommended
    Whether stable publication should update the public recommended docs pointer.
Type

DocsPublicationPlan

Source

Machine-readable release docs publication plan.

Parameters

  • Schema
    Plan schema identifier.
  • Version
    Release version described by the plan.
  • Tag
    Annotated release tag.
  • PlanPath
    Path where this plan was written.
  • ArchiveAssetName
    GitHub Release asset name for the docs archive.
  • ArchivePath
    Local docs archive path.
  • ArchiveSha256
    SHA-256 digest of the archive bytes.
  • Sha256Path
    Local path of the paired digest ledger file.
  • ExactTreePath
    Catalog exact-tree path, relative to the Pages release root.
  • ReleaseManifestSha256
    SHA-256 digest of the exact-tree release manifest.
  • PagesStagingRoot
    Local staged Pages payload root.
  • CatalogPath
    Local staged versions.json path.
  • RecommendedVersion
    Recommended public docs version after catalog generation, if any.
  • CatalogEntry
    Catalog entry generated for this release.
  • RetryPolicy
    Policy for draft/public asset replacement during recovery.
  • Recovery
    Recovery summary metadata.
Type

DocsPublicationCatalogEntry

Source

Version catalog entry produced for the released docs tree.

Parameters

  • Version
    Catalog version value.
  • Label
    Human-readable catalog label.
  • Summary
    Short release summary for docs navigation.
  • SupportState
    Support state, usually Current for promoted stable releases or Maintained .
  • Visibility
    Catalog visibility. Release publication emits public entries.
  • AdvisoryState
    Advisory state for the docs version.
  • ExactTreePath
    Release-root-relative exact tree path.
  • ReleaseManifestSha256
    Pinned release manifest digest for the exact tree.
Type

DocsPublicationRetryPolicy

Source

Draft/public asset retry policy emitted with the publication plan.

Parameters

  • DraftAssetReplaceAllowed
    Whether recovery may replace assets while the GitHub Release is still a draft.
  • PublicAssetReplaceAllowed
    Whether recovery may replace assets after the GitHub Release is public.
Type

DocsPublicationRecovery

Source

Maintainer recovery summary metadata.

Parameters

  • SummaryPath
    Path to the human-readable recovery summary with resume, publish, and abort commands.
Type

ReleaseReportRenderer

Source
Method

RenderCheck

string RenderCheck(ReleaseCheckResult result)

Renders a check report.

Parameters

  • result
    Check result.

Returns

Markdown report.

Remarks

The report shape is stable for workflow comments and maintainer review: # Release readiness report , a summary bullet list, ## Generated files , optional ## Release evidence bundle , ## Errors , then ## Warnings . Empty diagnostics render as - None . Each diagnostic renders its complete severity/code/problem/cause/fix/docs envelope. Generated file paths and diagnostic codes are wrapped in inline code; diagnostic text is not escaped beyond normal Markdown rendering. Consumers should key off headings and diagnostic codes rather than line numbers.

Method

RenderPreparation

string RenderPreparation(ReleasePreparationResult result)

Renders a prepare report.

Parameters

  • result
    Preparation result.

Returns

Markdown report.

Remarks

Preparation reports begin with the check report contract, then append a manual review gate, optional evidence summary, either ## Dry-run plan or ## Files written based on ReleasePreparationResult.DryRun , a separate append-only entry archive section, and structured recovery guidance. Paths are repository-relative bullets. This distinction is the only dry-run marker in the report, so callers that publish the report should preserve that heading.

Type

PackageIndexSummary

Source
Method

LoadAsync

Task<PackageIndexSummary> LoadAsync(string path, CancellationToken cancellationToken)

Loads a package index summary from YAML.

Parameters

  • path
    Package index path.
  • cancellationToken
    Cancellation token.

Returns

Package index summary.

Method

Load

PackageIndexSummary Load(string content)

Parses a package-index document into the release-owned public package summary.

Parameters

  • content
    The YAML document to parse.

Returns

The public publish package rows and their release-link contracts.

Property

PublicPublishedPackages

IReadOnlyList<PackageIndexEntry> PublicPublishedPackages { get; } Source

Gets public package rows whose publish decision is publish.

Type

PackageIndexManifest

Source

Package manifest root shape used by the release tool.

Property

Packages

List<PackageIndexYamlEntry> Packages { get; init; } Source

Gets the package rows.

Type

PackageIndexYamlEntry

Source

Package manifest row shape used by the release tool.

Property

Project

string Project { get; init; } Source

Gets the project path.

Property

Classification

string Classification { get; init; } Source

Gets the classification string.

Property

PublishDecision

string? PublishDecision { get; init; } Source

Gets the publish decision string.

Property

ReleaseTrack

string? ReleaseTrack { get; init; } Source

Gets the release-link policy.

Property

ReleaseNotesPath

string? ReleaseNotesPath { get; init; } Source

Gets the explicit release notes path when the package uses an explicit link.

Property

ReadinessBlocker

string? ReadinessBlocker { get; init; } Source

Gets the same-repository issue or pull request that blocks publication, when one remains unresolved.

Type

PackageIndexEntry

Source

Package row included in a release manifest.

Parameters

  • Project
    Repository-relative package project path. The package index supplies a non-empty path for every row.
  • ReleaseLink
    Resolved package release-link policy.
  • ReadinessBlocker
    Optional same-repository issue or pull-request reference. A non-empty value blocks publication until the package is held or the blocker is cleared.
Property

ReleaseNotesPath

string ReleaseNotesPath { get; } Source

Gets the repository-relative release note path after applying the package release-link policy.

Type

ReleaseDocsArchiveGate

Source

Verifies stable release evidence against a staged AppSurface Docs version catalog and exact archive tree.

Remarks

Runtime docs catalog loading is deliberately lenient so one bad version cannot break unrelated docs. Stable release publishing is the opposite boundary: the selected release version must be present, public, catalog-pinned, and byte verified before the release tool allows the stable GitHub Release path to continue.

Method

ValidateStableAsync

Task<ReleaseDocsArchiveGateResult> ValidateStableAsync(ReleaseWorkspace workspace, ReleaseOptions options, ReleaseEvidenceBundle bundle, CancellationToken cancellationToken)

Validates the stable release docs archive contract using command-supplied catalog inputs.

Method

TryValidateNoReparseSegments

bool TryValidateNoReparseSegments(string rootPath, string candidatePath, out string? detail)

Validates that a physical directory candidate stays below an ordinary trusted root without crossing reparse segments.

Parameters

  • rootPath
    Trusted exact-tree root or trusted release root to contain candidatePath .
  • candidatePath
    Physical directory path to validate after canonicalization.
  • detail
    Receives diagnostic detail when the candidate escapes the root or crosses a symlink, junction, or reparse point.

Returns

true when the candidate equals or descends from the root and every directory segment is ordinary.

Remarks

This test seam validates directory ancestors. File leaves still need a separate FileInfo check before hashing or reading bytes so a manifest entry cannot point at a symlinked file inside an otherwise ordinary directory.

Method

TryResolveExactTreePath

bool TryResolveExactTreePath(string trustedReleaseRoot, string exactTreePath, out string? physicalExactTreePath, out string? issue)

Resolves a catalog exactTreePath into a physical path beneath the trusted release root.

Parameters

  • trustedReleaseRoot
    Canonical trusted release root that contains staged exact-tree archives.
  • exactTreePath
    Catalog-authored exact-tree path. It must be relative and must avoid parent or hidden segments.
  • physicalExactTreePath
    Receives the canonical physical exact-tree path when resolution succeeds; otherwise null unless containment fails after normalization.
  • issue
    Receives a maintainer-facing reason when the catalog path is empty, rooted, unsafe, escaping, or invalid.

Returns

true when the authored path can be safely resolved under trustedReleaseRoot .

Remarks

The trusted root is supplied by release operators or defaults from the catalog directory. Callers should validate the returned directory exists and has no reparse segments before reading archive content.

Method

CreatePhysicalManifestPathSet

IReadOnlySet<string> CreatePhysicalManifestPathSet(IEnumerable<string> manifestPaths, StringComparer pathComparer)

Creates the physical-path coverage set for a release manifest under the filesystem's casing rules.

Parameters

  • manifestPaths
    Logical paths recorded by the release manifest.
  • pathComparer
    Comparer matching the physical filesystem's case behavior.

Returns

A set used to match paths returned by physical archive enumeration.

Method

ResolvePhysicalPathComparer

StringComparer ResolvePhysicalPathComparer(string rootPath, Func<string, bool> fileExists, Func<string, IEnumerable<string>> enumerateFileSystemEntries)

Resolves physical filesystem casing behavior without writing probe files into an immutable archive.

Parameters

  • rootPath
    Existing exact release tree.
  • fileExists
    File existence operation used for the read-only case-variant probe.
  • enumerateFileSystemEntries
    Filesystem enumeration used to reject ambiguous case-variant siblings.

Returns

An ordinal comparer matching the archive root's case behavior.

Method

UseFileSystemInspectorForTesting

IDisposable UseFileSystemInspectorForTesting(IFileSystemInspector inspector)

Overrides release docs archive filesystem inspection for the current async test flow.

Parameters

  • inspector
    Inspector used to read filesystem metadata until the returned scope is disposed.

Returns

A disposable scope that restores the previous inspector.

Remarks

Production code uses the default physical inspector. Tests use this seam to force deterministic metadata and enumeration failures that operating systems otherwise expose only through race-prone permission or reparse-point behavior.

Type

IFileSystemInspector

Source

Reads filesystem metadata used by stable docs archive validation.

Remarks

The interface is intentionally narrow and internal: callers should not use it to virtualize archive bytes, only metadata operations whose real filesystem failures are difficult to trigger deterministically in tests.

Method

DirectoryExists

bool DirectoryExists(DirectoryInfo directory)

Returns whether the directory currently exists.

Method

GetDirectoryAttributes

FileAttributes GetDirectoryAttributes(DirectoryInfo directory)

Reads directory attributes, throwing the same filesystem exceptions as FileSystemInfo.Attributes .

Method

EnumerateFileSystemInfos

FileSystemInfo[] EnumerateFileSystemInfos(DirectoryInfo directory)

Enumerates immediate entries in a directory.

Method

GetFileSystemInfoAttributes

FileAttributes GetFileSystemInfoAttributes(FileSystemInfo entry)

Reads attributes for a file or directory entry discovered during archive traversal.

Method

FileExists

bool FileExists(FileInfo file)

Returns whether the file currently exists.

Method

GetFileAttributes

FileAttributes GetFileAttributes(FileInfo file)

Reads file attributes, throwing the same filesystem exceptions as FileSystemInfo.Attributes .

Type

ReleaseDocsArchiveGateResult

Source

Result of stable docs archive verification.

Parameters

  • Proof
    Verification proof when the catalog entry, exact tree, manifest, and serveable files matched; otherwise null .
  • Diagnostics
    Blocking diagnostics explaining why stable docs archive verification could not produce proof.

Remarks

Successful results have a non-null proof and no diagnostics. Failure results keep proof null so check and publish callers cannot accidentally treat a partially inspected archive as verified.

Type

ReleaseDocsArchiveVerificationProof

Source

Immutable proof that the stable release docs catalog entry and staged exact tree were verified.

Parameters

  • State
    Verification state written into release reports. Successful verification uses ReleaseDocsArchiveGate.VerifiedState .
  • CatalogPath
    Physical path to the staged AppSurface Docs versions.json that supplied the selected catalog entry.
  • TrustedReleaseRootPath
    Canonical trusted release root used to resolve the catalog exact tree path.
  • CatalogExactTreePath
    Catalog-authored exact tree path reviewed by maintainers.
  • CatalogReleaseManifestSha256
    Catalog-pinned release manifest digest that matched the staged manifest bytes.
  • PhysicalExactTreePath
    Canonical physical exact tree path that was inspected for ordinary directories and verified content.
  • VerifiedFileCount
    Number of release manifest entries that were byte-verified.

Remarks

The proof intentionally carries both authored catalog values and resolved physical paths. Maintainers should review the authored values for release identity and the physical values for staging provenance.

Type

ReleaseSidecar

Source

Mutable YAML sidecar metadata for release-note documentation pages.

Remarks

Sidecars are dictionary-backed so unknown fields are preserved. The committed release artifact remains in the prepared state; only a tag-bound resolver creates the transient tagged projection used by docs and publishing.

Method

LoadAsync

Task<ReleaseSidecar> LoadAsync(string path, CancellationToken cancellationToken)

Loads sidecar metadata from YAML.

Parameters

  • path
    Sidecar path. Expected content is a YAML mapping at the document root.
  • cancellationToken
    Cancellation token honored during file I/O.

Returns

Loaded sidecar whose unknown keys are preserved for later serialization.

Remarks

The current release flow expects the unreleased sidecar to contain documentation keys such as title , summary , page_type , nav_group , order , breadcrumbs , and trust . Missing keys are tolerated because ToPreparedRelease writes the release-owned fields. Malformed YAML is wrapped in ReleaseToolException with release-sidecar-invalid ; I/O and cancellation failures bubble to the shared command diagnostic layer.

Method

ToPreparedRelease

string ToPreparedRelease(SemVer version, DateOnly date)

Converts unreleased metadata into a committed prepared-release sidecar.

Parameters

  • version
    Prepared release version.
  • date
    Preparation date.

Returns

Prepared release sidecar YAML using underscored key naming for generated CLR-backed values.

Remarks

This method mutates the loaded dictionary before serializing. It replaces release-owned metadata with provisional prepared-release values and preserves unrelated keys from the source sidecar. The result deliberately makes no tag-derived or GitHub Release existence claim.

Method

Parse

ReleaseSidecar Parse(string content, string source)

Parses a sidecar YAML payload that was read from a tag or another explicit source.

Parameters

  • content
    YAML document content.
  • source
    Human-readable source identifier used in diagnostics.

Returns

Parsed release sidecar with unknown fields preserved.

Method

EnsurePrepared

void EnsurePrepared(SemVer version, string source)

Ensures that this sidecar is an explicit prepared artifact for the requested version.

Parameters

  • version
    Release version that owns the sidecar.
  • source
    Human-readable source identifier used in diagnostics.

Remarks

Missing state is treated as a legacy artifact rather than being silently interpreted as prepared. This keeps new release publication deterministic while leaving historical docs and archive reads independent of the new resolver.

Method

ToTaggedProjection

string ToTaggedProjection(SemVer version, DateTimeOffset taggerTimestamp, string source)

Creates the transient tagged sidecar projection after a resolver has verified the annotated tag.

Parameters

  • version
    Release version that owns the sidecar.
  • taggerTimestamp
    Timestamp recorded in the annotated tag object.
  • source
    Human-readable source identifier used for prepared-state validation.

Returns

Rendered tagged sidecar YAML. The caller owns any temporary output path.

Remarks

This method mutates and consumes the loaded metadata. After projection, the instance declares release.state: tagged and final trust wording, so it no longer passes EnsurePrepared . Parse a fresh ReleaseSidecar for each projection.

Method

UnreleasedTemplate

string UnreleasedTemplate()

Creates reset unreleased metadata for the next release cycle.

Returns

Canonical unreleased sidecar YAML with title, navigation, trust metadata, and source guidance.

Remarks

The template is complete enough for docs harvesting without requiring the previous sidecar. It intentionally resets release-specific trust metadata back to provisional language.

Type

ReleaseJson

Source

JSON serializer configuration for release artifacts.

Property

Options

JsonSerializerOptions Options { get; } Source

Gets indented camel-case JSON options.

Type

ReleaseEvidence

Source

Creates and validates checked-in release evidence bundles.

Remarks

Release evidence is repository consistency evidence, not a signature or hosted-build attestation. The bundle ties together release-owned files, package release-note paths, optional docs archive catalog fields, and split commit identities so release preparation can be reviewed in a pull request and publishing can validate the same bundle at the annotated tag commit.

Method

BuildDraft

ReleaseEvidenceBundle BuildDraft(ReleaseWorkspace workspace, SemVer version, string releaseClassification, DateOnly date, string? contentSourceCommit, string releaseNoteContent, string releaseSidecarContent, string releaseManifestContent, IReadOnlyList<PackagePathUpdate> packagePathUpdates)

Builds a draft release evidence bundle for release preparation.

Method

BuildDraftV2

ReleaseEvidenceBundleV2 BuildDraftV2(ReleaseWorkspace workspace, SemVer version, string releaseClassification, DateOnly date, string? contentSourceCommit, string releaseNoteContent, string releaseSidecarContent, string releaseManifestContent, string currentReleaseContent, string currentReleaseSidecarContent, IReadOnlyList<CoordinatedPackageReleaseNoteResolution> coordinatedPackageReleaseNoteResolutions)

Builds schema-v2 evidence for a release whose package links use the frozen coordinated current pointer.

Parameters

  • workspace
    Repository workspace that supplies the canonical artifact paths.
  • version
    Version represented by the generated evidence.
  • releaseClassification
    Release channel, either prerelease or stable .
  • date
    Release date recorded in the manifest and evidence.
  • contentSourceCommit
    Preparation base commit, when it is available.
  • releaseNoteContent
    Versioned release-note bytes included in the evidence digest set.
  • releaseSidecarContent
    Versioned release-note metadata bytes included in the evidence digest set.
  • releaseManifestContent
    Versioned V2 manifest bytes included in the evidence digest set.
  • currentReleaseContent
    Frozen tree-local current pointer bytes. Required for schema V2; schema V1 does not use this artifact.
  • currentReleaseSidecarContent
    Frozen tree-local current pointer metadata bytes. Required for schema V2; schema V1 does not use this artifact.
  • coordinatedPackageReleaseNoteResolutions
    Coordinated package links resolved through the frozen current pointer.
Method

ValidatePreparedAsync

Task<ReleaseEvidenceValidationResult> ValidatePreparedAsync(ReleaseWorkspace workspace, SemVer version, string releaseClassification, string? contentSourceCommit, CancellationToken cancellationToken)

Validates a checked-in release evidence bundle in the current worktree.

Method

ValidateTag

ReleaseEvidenceValidationResult ValidateTag(SemVer version, string releaseClassification, string tag, string tagCommit, string releaseNoteJson, string releaseSidecarJson, string releaseManifestJson, string evidenceJson, string? currentReleaseContent = null, string? currentReleaseSidecarContent = null)

Validates release evidence read from an annotated tag.

Parameters

  • version
    Version claimed by the annotated tag.
  • releaseClassification
    Release channel expected for the tagged evidence.
  • tag
    Annotated tag name.
  • tagCommit
    Commit resolved from the annotated tag.
  • releaseNoteJson
    Tagged release-note content.
  • releaseSidecarJson
    Tagged release-note metadata content.
  • releaseManifestJson
    Tagged release-manifest content.
  • evidenceJson
    Tagged release-evidence content.
  • currentReleaseContent
    Optional frozen current-pointer content for schema V1; required with the sidecar for schema V2.
  • currentReleaseSidecarContent
    Optional frozen current-pointer metadata for schema V1; required with the pointer for schema V2.
Method

Serialize

string Serialize(ReleaseEvidenceBundleV2 bundle)

Serializes a schema-v2 coordinated release evidence bundle.

Method

IsV2

bool IsV2(string evidenceJson)

Determines whether a raw evidence document declares schema v2 without deserializing it as a v1 object.

Type

ReleaseEvidenceValidationResult

Source

Describes the outcome of release evidence validation.

Parameters

  • Summary
    Structured summary when the evidence shape was readable enough to summarize; otherwise null .
  • Diagnostics
    Errors or warnings discovered while validating the release evidence bundle.
  • Bundle
    Deserialized evidence bundle when parsing and top-level shape validation reached the bundle. This can be null for unreadable evidence and can be non-null while Diagnostics contains errors.

Remarks

Stable docs archive verification depends on Bundle only after callers have checked diagnostics. Do not treat a non-null bundle as proof that the evidence is publishable.

Type

ReleaseCheckCommand

Source

Validates release readiness without mutating repository files.

Property

FailOnWarningsOption

bool FailOnWarningsOption { get; set; } Source

Gets a value indicating whether check should fail on warning diagnostics.

Property

AllowExistingTargetsOption

bool AllowExistingTargetsOption { get; set; } Source

Gets a value indicating whether check may review already-generated release artifacts.

Property

DocsCatalogPath

string? DocsCatalogPath { get; set; } Source

Gets the AppSurface Docs version catalog used to verify stable release evidence.

Remarks

check may omit this value to use dist/docs/versions.json when that local review fallback exists. Stable checks that review prepared artifacts should pass the staged catalog explicitly when possible. Relative paths are resolved from the repository root, and invalid or missing catalogs surface release diagnostics rather than mutating release files.

Property

DocsTrustedReleaseRootPath

string? DocsTrustedReleaseRootPath { get; set; } Source

Gets the trusted release root used to resolve catalog exactTreePath values.

Remarks

When omitted, the verifier uses the catalog directory as the trusted release root. Pass this option when the catalog is staged outside the directory that contains the exact tree paths. The root must be an ordinary directory, and catalog exactTreePath values must stay relative to it without hidden or parent segments.

Type

ReleasePrepareCommand

Source

Generates the coordinated release pull request payload.

Type

ReleaseTagMessageCommand

Source

Renders canonical annotated-tag trailers from the prepared release artifacts at HEAD.

Type

ReleaseInspectCommand

Source

Inspects a local annotated release tag and renders the validated tagged projection.

Property

Tag

string? Tag { get; set; } Source

Gets the annotated release tag to inspect.

Property

BaseRef

string? BaseRef { get; set; } Source

Gets the branch that must contain the tag commit.

Property

OutputPath

string? OutputPath { get; set; } Source

Gets an optional explicit output path for the tagged sidecar projection.

Remarks

The command validates all tag-bound inputs before writing this path, then opens each parent directory without following links and atomically replaces the output through that retained directory object. The release-publish docs job uses a runner-temporary file and explicitly overlays it only in its disposable detached checkout. The path must resolve outside the repository source tree so inspection cannot overwrite a prepared release artifact.

Type

ReleasePublishCommand

Source

Validates tag state and emits GitHub Release workflow outputs.

Property

Tag

string? Tag { get; set; } Source

Gets the annotated release tag to publish.

Property

GitHubOutputPath

string? GitHubOutputPath { get; set; } Source

Gets an optional GitHub Actions output file.

Property

BaseRef

string? BaseRef { get; set; } Source

Gets the branch that must contain the annotated tag commit.

Remarks

Publish defaults to main . Use this option when a maintained release branch, such as release/0.1.0 , owns the tag provenance for a release. The command accepts branch names and branch refs shaped as origin/<branch> , refs/heads/<branch> , or refs/remotes/origin/<branch> , then normalizes them before validation fetches and checks origin/<branch> . Tags, SHAs, empty branch names, and unsupported refs such as refs/tags/v1.2.3 are invalid because publish validation must prove protected branch reachability.

Property

DocsCatalogPath

string? DocsCatalogPath { get; set; } Source

Gets the staged AppSurface Docs version catalog used to verify stable release evidence.

Remarks

Stable publish accepts this path for local diagnostics, but the public release workflow creates its staged docs artifact through docs-publication . Relative paths are resolved from the repository root. Prerelease publish accepts the option but does not require docs archive proof.

Property

DocsTrustedReleaseRootPath

string? DocsTrustedReleaseRootPath { get; set; } Source

Gets the trusted release root used to resolve catalog exactTreePath values.

Remarks

When omitted, stable publish resolves exact trees relative to the staged catalog directory. Supply this option when the artifact layout stores versions.json separately from the exact release trees; the path must resolve under the repository root when relative and must point at the ordinary directory that owns the catalog exact-tree paths.

Type

ReleaseDocsPublicationCommand

Source

Creates AppSurface Docs publication artifacts for the release publish workflow.

Remarks

This command is the maintainer-facing CLI seam for the public release docs trust path. It expects docs to have already been exported for the annotated tag commit and produces the deterministic archive, digest ledger, Pages staging payload, catalog entry, publication plan, and recovery summary consumed by release-publish.yml . Use it when the release workflow needs a durable GitHub Release asset and a Pages catalog update from the same tag-bound exact tree. Do not use it to publish arbitrary local docs: the tag must match --version , --docs-exact-tree must be an ordinary exported tree with the release manifest, and --pages-staging-root is deleted before the merged payload is written. Disable --promote-recommended only for a documented recovery or prerelease-style staging run where the current stable recommendation must remain unchanged.

Property

Tag

string? Tag { get; set; } Source

Gets the annotated release tag that owns the docs publication.

Remarks

This option is required and must be the canonical v{version} tag. A mismatch fails before any staging directory is reset.

Property

DocsExactTreePath

string? DocsExactTreePath { get; set; } Source

Gets the exported docs exact tree for the tag.

Remarks

The exact tree must be a completed AppSurface Docs export for the tag commit and must contain .appsurface-docs-release-manifest.json . The planner rejects hidden repository-relative paths, generated output paths under this tree, and reparse-point entries so archive bytes come only from ordinary exported files.

Property

ExistingPagesRootPath

string? ExistingPagesRootPath { get; set; } Source

Gets the optional current Pages payload to copy before adding the immutable release tree.

Remarks

When supplied, this directory must exist. Use it to preserve existing versions.json , /docs , and prior releases/* content before the new release exact tree is copied into the staging root.

Property

ArchiveOutputPath

string? ArchiveOutputPath { get; set; } Source

Gets the tar.gz archive output path.

Remarks

The command writes this file and a sibling .sha256 file. The path and its temporary .tar sibling must be outside the exact tree so the archive cannot include its own generated bytes.

Property

PagesStagingRootPath

string? PagesStagingRootPath { get; set; } Source

Gets the Pages staging root output path.

Remarks

This directory is destructive scratch space: it is deleted and recreated before existing Pages content and the new releases/{version}/ tree are copied. It must not overlap the repository, exact tree, existing Pages root, archive, publication plan, or recovery summary paths.

Property

PlanOutputPath

string? PlanOutputPath { get; set; } Source

Gets the publication plan JSON output path.

Remarks

The plan is the machine-readable artifact handoff between docs archive creation, Pages deployment, public verification, and release promotion. Store it outside the exact tree and staging root.

Property

SummaryOutputPath

string? SummaryOutputPath { get; set; } Source

Gets the optional recovery summary output path.

Remarks

The summary contains exact resume, publish, and abort commands for partial failures. Store it outside the exact tree and staging root so it cannot be served as release docs content.

Property

ExpectedReleaseManifestSha256

string? ExpectedReleaseManifestSha256 { get; set; } Source

Gets the optional release evidence docs manifest digest that the exact tree must match.

Remarks

Stable release workflows pass this from tag-bound release evidence. A mismatch means the exported docs tree does not match the reviewed evidence and must be regenerated from the annotated tag commit.

Property

PromoteRecommendedText

string PromoteRecommendedText { get; set; } Source

Gets whether stable docs publication should promote the version to recommendedVersion.

Remarks

Defaults to true . The command rejects values other than true or false . Passing false keeps the existing recommendation and is intended for prereleases or explicit recovery where maintainers do not want to change the stable docs pointer.

Property

GitHubOutputPath

string? GitHubOutputPath { get; set; } Source

Gets an optional GitHub Actions output file.

Remarks

When supplied, the command appends scalar outputs such as archive name, digest, catalog path, exact tree path, and recovery summary path using GitHub Actions output-file syntax. The option must name a file, not a root directory.

Type

ReleaseCurrentPointer

Source

Parses and renders the frozen tree-local coordinated release pointer.

Remarks

The current pointer deliberately has a very small, byte-stable surface. Exact documentation trees copy this file, so accepting free-form prose would allow a historical current route to silently stop identifying the release represented by its tree.

Method

BuildNone

string BuildNone()

Builds the initial pointer used before the repository has a reachable coordinated tag.

Method

Build

string Build(SemVer version)

Builds the canonical pointer for a tagged coordinated release.

Method

TryParse

bool TryParse(string content, out SemVer? version)

Validates canonical pointer bytes and returns its optional referenced tag version.

Type

ReleaseCurrentPointerGate

Source

Finds annotated, reachable coordinated release tags and enforces the current-pointer advancement rule.

Type

ReleaseDiagnostic

Source

Diagnostic envelope with a stable code and reader-actionable context.

Method

Error

ReleaseDiagnostic Error(string code, string problem, string cause, string fix, string docs)

Creates an error diagnostic.

Method

Warning

ReleaseDiagnostic Warning(string code, string problem, string cause, string fix, string docs)

Creates a warning diagnostic.

Method

InvalidUnreleasedEntry

ReleaseDiagnostic InvalidUnreleasedEntry(string cause)

Creates the diagnostic emitted when append-only unreleased entries cannot be composed.

Parameters

  • cause
    Specific entry or template validation failure.

Returns

Stable diagnostic for callers of release check and preparation.

Method

Render

string Render()

Renders the diagnostic envelope for CLI stderr.

Returns

Human-readable diagnostic envelope.

Type

ReleaseToolException

Source

Exception that carries a structured release diagnostic.

Property

Diagnostic

ReleaseDiagnostic Diagnostic { get; } Source

Gets the structured diagnostic.

Type

ReleaseCliApp

Source

DI-backed execution runtime for release CliFx commands.

Method

RunAsync

Task RunAsync(string[] args, Action<ConsoleOptions>? configureOptions = null)

Runs release commands through the shared AppSurface command-service primitive.

Parameters

  • args
    Command-line arguments.
  • configureOptions
    Optional console configuration.

Returns

A task that completes when command execution finishes.

Type

ReleasePreparationDiffVerifier

Source

Classifies the complete release-preparation pull-request diff and admits generated package documentation only with a matching PackageIndex provenance witness.

Remarks

This is a maintainer-integrity gate for repository-owned release preparation. It is not a hostile-fork security boundary: the evaluator and witness generator run from the checked-out pull-request tree. See tools/ForgeTrust.AppSurface.Release/README.md#verify-prep-diff for the exact local and CI workflow.

Method

VerifyAsync

Task<ReleasePreparationDiffResult> VerifyAsync(string repositoryRoot, string baseRef, bool noFetch, string? witnessPath, CancellationToken cancellationToken)

Verifies a release-preparation diff from an explicit base branch or ref to HEAD.

Parameters

  • repositoryRoot
    Checked-out repository root.
  • baseRef
    Base branch/ref; when omitted callers should pass main .
  • noFetch
    Whether the caller explicitly accepts offline base-ref diagnostics instead of fetching.
  • witnessPath
    Optional advanced seam for a pre-created PackageIndex witness.
  • cancellationToken
    Cancellation token for Git and witness operations.

Returns

Identity, changed-path, and typed diagnostic report.

Method

TryParseNameStatus

bool TryParseNameStatus(string output, out IReadOnlyList<ReleasePreparationChange> changes, out string issue)

Strictly parses NUL-delimited git diff --name-status -z --find-renames output.

Parameters

  • output
    Raw Git stdout.
  • changes
    Parsed changes on success.
  • issue
    Failure reason on malformed input.

Returns

Whether the stream was unambiguous and safe to classify.

Method

ValidateReleaseArtifactChanges

void ValidateReleaseArtifactChanges(string version, IReadOnlyList<ReleasePreparationChange> changes, IReadOnlyList<string> consumedEntryPaths, List<ReleaseDiagnostic> diagnostics)

Appends diagnostics when the complete diff does not contain the exact artifact statuses required for a versioned release.

Parameters

  • version
    Version segment without the leading v , used to derive required release artifact paths.
  • changes
    Complete, parsed Git diff to classify against the release-preparation contract.
  • consumedEntryPaths
    Unreleased entry paths declared by the validated release manifest; each must be deleted.
  • diagnostics
    Mutable result collection that receives validation errors instead of expected contract failures throwing.
Method

ValidateWitnessAsync

Task ValidateWitnessAsync(ReleasePreparationWitnessDocument witness, IReadOnlyList<ReleasePreparationChange> changes, string repositoryRoot, string baseRef, string baseTip, string mergeBase, string head, List<ReleaseDiagnostic> diagnostics, CancellationToken cancellationToken)

Validates a parsed PackageIndex witness against the complete diff and appends diagnostics for every provenance mismatch.

Parameters

  • witness
    Strictly parsed witness emitted from the same checked-out release-preparation candidate.
  • changes
    Complete, parsed Git diff whose package inputs and generated outputs the witness must authorize.
  • repositoryRoot
    Checked-out repository root used to read generated surfaces and their merge-base content.
  • baseRef
    Normalized origin-tracking base ref retained for diagnostic context.
  • baseTip
    Resolved lowercase full Git object ID for the fetched base tip; it must match both witness base identity fields.
  • mergeBase
    Resolved lowercase full Git object ID for the sole merge base that supplies expected prior surface content.
  • head
    Resolved lowercase full Git object ID for the candidate HEAD that the witness must bind.
  • diagnostics
    Mutable result collection that receives contract failures instead of expected witness mismatches throwing.
  • cancellationToken
    Cancellation token for merge-base file reads and Git content inspection.

Remarks

Direct callers should first parse the witness with TryParseWitness and resolve the exact identities from the same complete diff. This method treats invalid provenance as diagnostics so the CLI can render a complete report; ordinary I/O cancellation and unexpected filesystem failures still propagate.

Type

ReleasePreparationDiffResult

Source

Typed report produced by ReleasePreparationDiffVerifier .

Property

IsValid

bool IsValid { get; } Source

Gets whether no blocking diff diagnostic was produced.

Type

ReleasePreparationWitnessDocument

Source

Parsed PackageIndex provenance witness that binds changed semantic inputs and generated output hashes to Git identities.

Parameters

  • Schema
    Exact witness schema identifier.
  • BaseRef
    Resolved lowercase full Git object ID for the fetched base tip.
  • BaseTipCommit
    Resolved lowercase full Git object ID for the fetched base tip.
  • MergeBaseCommit
    Resolved lowercase full Git object ID for the sole merge base.
  • HeadCommit
    Resolved lowercase full Git object ID for the candidate HEAD.
  • Verification
    Verification mode emitted by PackageIndex; accepted witnesses use verified .
  • ChangedInputs
    Ordered semantic source inputs that authorize generated surfaces.
  • Surfaces
    Ordered generated surfaces and their expected SHA-256 digests.
Type

ReleasePreparationWitnessInputDocument

Source

One changed semantic input and the ordered generated surfaces it authorizes.

Parameters

  • Kind
    Supported input kind: package-index-manifest or release-guidance-template .
  • Path
    Safe repository-relative input path.
  • Surfaces
    Ordered safe repository-relative output paths authorized by the input.
Type

ReleasePreparationWitnessSurfaceDocument

Source

One generated package documentation surface and the canonical SHA-256 digest it must match at HEAD.

Parameters

  • Kind
    Supported surface kind: chooser , readiness , or managed-readme .
  • Path
    Safe repository-relative generated output path.
  • Sha256
    Lowercase 64-character SHA-256 digest of the required output or managed README body.
Type

ReleasePublishing

Source

Validates tag state and produces GitHub Release workflow outputs.

Method

PublishAsync

Task<PublishOutputs> PublishAsync(ReleaseOptions options, CancellationToken cancellationToken)

Validates an existing annotated tag and extracts release notes from the tag commit.

Parameters

  • options
    Publish command options. The version and tag must match, and stable versions require protected stable package publishing proof.
  • cancellationToken
    Cancellation token.

Returns

Structured workflow outputs for GitHub Release creation.

Remarks

PublishAsync verifies annotated tag shape, reachability from the configured base ref, package publication, draft-safe GitHub Release state, and presence of releases/v{version}.md in the tag commit. The tag commit must also contain the release sidecar, release manifest, and release evidence bundle; missing or invalid tag-bound artifacts fail fast before a GitHub Release is created or promoted. The method writes the tag's release note to a temporary file so workflows can pass a stable notes path to GitHub's release action.

Method

WriteOutputsAsync

Task WriteOutputsAsync(PublishOutputs outputs, ReleaseOptions options, CancellationToken cancellationToken)

Writes publish outputs to a GitHub Actions output file when requested.

Parameters

  • outputs
    Publish outputs.
  • options
    Release command options. ReleaseOptions.GitHubOutputPath must be a file path, not a root directory.
  • cancellationToken
    Cancellation token.

Remarks

Scalar outputs use name=value . Multiline outputs use GitHub's delimiter form. Existing files are appended to match GITHUB_OUTPUT behavior.

Type

ReleaseChecker

Source

Validates release inputs and computes release readiness diagnostics.

Method

CheckAsync

Task<ReleaseCheckResult> CheckAsync(ReleaseOptions options, CancellationToken cancellationToken)

Runs local release readiness checks.

Parameters

  • options
    Release command options.
  • cancellationToken
    Cancellation token.

Returns

Readiness result with errors, warnings, and generated paths.