Table of Contents

scripts/_deployManifest.ps1

This page is part of the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at scripts-deploymanifest-ps1.md, and llms.txt lists every page.

Part of RepoContextContainer source.

#!/usr/bin/env pwsh
<#
.SYNOPSIS
	Pure helpers that record a deployment's attribution-relevant configuration
	and name what moved since the previous run.

.DESCRIPTION
	Issue #2931. A measured movement is only evidence about a cause if no OTHER
	sufficient cause moved in the same step. The WAL replay gate's 16 -> 6 was
	lost exactly there: the gate's own knob changed, and DOTNET_PROCESSOR_COUNT
	was removed, in one deploy. Both are sufficient to produce that movement, so
	the reading attributes to neither. Nothing was mis-set; a measurement was
	destroyed.

	The remedy is NOT to restore a particular value. A pinned constant with no
	assertion is what produced this: the pin was believed to be in force for
	several runs after it had been deleted, because nothing ever read it back.
	The remedy is to make the rig incapable of changing two attribution-relevant
	variables SILENTLY in one step - deliberately is fine and is sometimes
	necessary, silently is what voids a comparison.

	So this file does three things, and the third is the one that matters:

	  1. enumerates the variables a comparison's validity depends on;
	  2. records each one's value AND where that value came from;
	  3. diffs a run against its predecessor and refuses a multi-variable step
	     that nobody acknowledged.

	DECLARED AND EFFECTIVE ARE DIFFERENT OBJECTS, and conflating them is the
	failure this epic keeps rediscovering - at a value (#2928), at a checkout
	(#2930), and at an image (the `auto` token, which the deployed binary did
	not understand while the source did). A manifest that recorded only what the
	compose file DECLARES would repeat it one layer up, so every record carries
	both and a divergence between them is itself a finding.

	CONVENTIONS, matching _tuningKnobs.ps1 and _provenance.ps1 beside it:

	- Every function is PURE. Nothing here reads a file, an environment
	  variable, a container, or a process. Assert-DeployManifest.ps1 does the
	  acquisition. The split is what makes the FAILING direction demonstrable:
	  a test can drive a two-variable step, an indeterminate provenance, or a
	  declared/effective divergence against fabricated readings, with no daemon
	  and no deploy.
	- Nothing here throws for a finding. Findings are returned; the caller
	  decides what they mean.
	- Every finding NAMES the variable, both values, and why it matters. A diff
	  that says "3 variables changed" is a scrollback entry. One that says which
	  three, from what, to what, is evidence someone who was not there can cite.
#>

Set-StrictMode -Version Latest

<#
.SYNOPSIS
	The provenance labels a resolved value can carry.

.DESCRIPTION
	Named constants rather than bare strings so a typo in a comparison is a
	missing-property error under Set-StrictMode instead of a silently false
	branch. `Indeterminate` is a first-class outcome, not an error case: the
	whole point is that "we could not tell where this came from" must be
	reportable, because the alternative is guessing and presenting the guess.
#>
$script:ProvenanceExplicit = 'ExplicitEnvironment'
$script:ProvenanceCgroup = 'CgroupDerivation'
$script:ProvenanceIndeterminate = 'Indeterminate'

<#
.SYNOPSIS
	Whether the DECLARED half was obtained, and if not, why not.

.DESCRIPTION
	Three states, because #2983 is a case of the first two being rendered
	identically. A manifest that prints `<absent>` for a key cannot, without
	this, be read to mean either "compose resolved and does not declare it" or
	"compose was never resolved, so nothing is known" - and those license
	opposite conclusions. The second is not a weaker form of the first; it is
	an absence of evidence being recorded in the notation reserved for evidence
	of absence.

	  Available     resolution succeeded. Every `<absent>` below it is a
	                positive finding: the key is genuinely not declared.
	  Unreadable    resolution was attempted and FAILED. Nothing is known about
	                any key, and the reason is recorded beside it.
	  NotAttempted  no resolution was asked for - the caller supplied a reading
	                directly, or asked for the effective half alone.

	Only `Available` licenses the divergence check. The other two suppress it,
	which is correct, but they must SAY they suppressed it: a suppressed check
	that renders as a passing one is the defect this file was written to stop,
	and #2983 is that defect occurring inside this file.
#>
$script:DeclarationAvailable = 'Available'
$script:DeclarationUnreadable = 'Unreadable'
$script:DeclarationNotAttempted = 'NotAttempted'

<#
.SYNOPSIS
	Whether the compose files a declared reading was resolved FROM are the ones
	the running deployment was actually created from.

.DESCRIPTION
	The declared half is only as good as the file set it was resolved from, and
	until #2993 that set was a hardcoded list nothing checked. It happened to be
	right. Nothing made it right, and nothing would have said so if it stopped
	being right - a deployment brought up with a different overlay would have
	been resolved from the wrong files and still reported a full
	DECLARATION_RESOLVED count.

	That is RESOLVED-BUT-WRONG, which is strictly worse than absent. An absent
	declaration is visibly unmeasured and reads as NotAttempted; a confidently
	wrong one is scored as a measurement.

	  Agreed    the container's own config_files label names exactly the files
	            the reading was resolved from, in the same order.
	  Diverged  the label and the list disagree. The declared half was resolved
	            from the wrong files and must not be scored.
	  Unknown   no label, or nothing parseable in it. Whether the set was right
	            is NOT KNOWN - which is a different claim from knowing it wrong.

	UNKNOWN IS NOT FOLDED INTO DIVERGED, for the same reason vintage
	Indeterminate is not folded into a difference: they answer different
	questions. Diverged says the file set is wrong; Unknown says no statement
	about the file set can be made. A caller that cannot tell them apart will go
	looking for an overlay mismatch that was never demonstrated.

	Unknown is also the reading for a container that is not compose-managed at
	all, which is a legitimate state rather than a fault. It is recorded rather
	than refused - but it is RECORDED, never silently treated as agreement,
	because falling back to the hardcoded list on a missing label would bypass
	the check precisely when the deployment is least standard.
#>
$script:ComposeSetAgreed = 'Agreed'
$script:ComposeSetDiverged = 'Diverged'
$script:ComposeSetUnknown = 'Unknown'

<#
.SYNOPSIS
	Which instrument version wrote a manifest, and how two of them relate.

.DESCRIPTION
	#2992. A manifest records what an instrument could READ, not only what the
	deployment WAS, and those two come apart whenever the instrument improves.
	Re-capturing the run-13 baseline after #2983 moved three keys from empty to
	a value on a rig with `RestartCount=0` on every container: nothing had
	changed except that the reader had learned to look at the embedder. The
	comparison called it configuration drift and refused.

	That direction of error is the expensive one. An artefact that reports
	success it did not earn is survivable, because nobody acts on it; an
	artefact that reports FAILURE it did not earn gets a bypass flag, and then
	gets deleted. So the vintage exists to stop a correct deployment being
	refused for a reason that is not a reason.

	The vintage tracks ACQUISITION CAPABILITY - which cells the instrument is
	able to populate - and not merely "this file changed". Bumping it for an
	edit that cannot change what is readable would manufacture incomparability
	between two manifests that agree perfectly, which is the same cry-wolf
	failure one step removed.

	Unknown is $null and never 0. A manifest written before this field existed
	has an UNKNOWN vintage, which is a different claim from vintage zero:
	zero is a value and would compare as merely older, silently asserting that
	the file's capability is known. It is not known, and the ordering below
	treats unknown as "older than any recorded vintage" without ever storing a
	number that says so.
#>
$script:ManifestVintageCurrent = 1
$script:VintageSame = 'Same'
$script:VintageBaselineOlder = 'BaselineOlder'
$script:VintageCurrentOlder = 'CurrentOlder'
$script:VintageIndeterminate = 'Indeterminate'

<#
.SYNOPSIS
	The compose files that must ALL be resolved for a declared reading to be
	complete, in overlay order.

.DESCRIPTION
	Pure on purpose, and separated from the code that runs `docker compose`, so
	the overlay requirement is assertable without a daemon. The requirement is
	not cosmetic: a bare `docker compose config` resolves only
	docker-compose.yml and docker-compose.override.yml, and EVERY
	attribution-relevant knob in Get-AttributionVariable is set by
	docker-compose.tuning.yml. Verified 2026-09-14 against the live rig - a bare
	resolution yields zero matches for LATTICE_WAL_MAX_CONCURRENT_REPLAYS, and
	the same resolution with the overlay yields "0".

	So a fix that resolved compose WITHOUT the overlay would report `<absent>`
	for every knob while now claiming to have looked, which is strictly worse
	than not looking: it converts an admitted gap into a false negative. Keeping
	the list here means a test can assert the overlay is in it without starting
	anything.
#>
function Get-DeployComposeFile {
	[CmdletBinding()]
	[OutputType([string])]
	param()

	return @('docker-compose.yml', 'docker-compose.tuning.yml')
}

<#
.SYNOPSIS
	Compares the compose files a reading was resolved from against the ones the
	container records having been created from.

.DESCRIPTION
	PURE, and deliberately takes the label as a STRING rather than a container
	name, so every branch - agreement, divergence, reordering, a missing label,
	an unparseable one - is assertable without a daemon. The impure half is the
	one line that runs `docker inspect`, and it has nothing to decide.

	ORDER IS COMPARED, NOT JUST MEMBERSHIP. A compose overlay later in the list
	overrides an earlier one, so the same two files in the opposite order can
	resolve to different values. A set difference is empty for that case and
	would pass it. This is the same shape as a count matching while the set does
	not, one level further in: here the SET matches and the ORDER does not, and
	only an ordered comparison sees it.

	PATHS ARE COMPARED BY LEAF NAME. The label holds absolute paths, and on the
	live rig they point at whichever checkout deployed the stack, which is not
	the checkout this script is being run from and legitimately differs. The
	leaf is the part that identifies the overlay. The cost is that two files of
	the same name in different directories compare equal; that is accepted,
	because the alternative - demanding the deploy checkout and the running
	script share a path - would refuse every correct deployment operated from a
	second worktree, which is how this repository is actually worked.

	KNOWN LIMITATION: docker joins the paths with a comma and does not escape
	them, so a compose file whose path CONTAINS a comma is indistinguishable
	from two files. Nothing in the label can resolve that, and inventing a
	heuristic would manufacture a confident wrong answer out of an ambiguous
	input. Such a path would surface as Diverged - visible, and refusing to
	score - rather than as a silent mis-parse.
#>
function Get-ComposeFileSetVerdict {
	[CmdletBinding()]
	[OutputType([pscustomobject])]
	param(
		[Parameter(Mandatory)] [AllowEmptyCollection()] [string[]] $Expected,
		[Parameter(Mandatory)] [AllowNull()] [AllowEmptyString()] [string] $LabelValue
	)

	$expectedLeaf = @($Expected | ForEach-Object { Split-Path -Path $_ -Leaf })

	if ([string]::IsNullOrWhiteSpace($LabelValue)) {
		return [pscustomobject]@{
			Status = $script:ComposeSetUnknown
			Expected = $expectedLeaf
			Observed = @()
			Missing = @()
			Unexpected = @()
			OrderDiffers = $false
			Reason = 'the container carries no com.docker.compose.project.config_files label, so the overlay set could not be verified'
		}
	}

	# Split on the comma docker joins with, then reduce each entry to its leaf.
	# Both separators are handled because the label is written by whichever
	# platform created the stack, not by the platform reading it.
	$observed = @(
		$LabelValue -split ',' |
			ForEach-Object { $_.Trim() } |
			Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
			ForEach-Object { ($_ -split '[\\/]')[-1] }
	)

	if ($observed.Count -eq 0) {
		return [pscustomobject]@{
			Status = $script:ComposeSetUnknown
			Expected = $expectedLeaf
			Observed = @()
			Missing = @()
			Unexpected = @()
			OrderDiffers = $false
			Reason = "the config_files label held nothing parseable ('$LabelValue'), so the overlay set could not be verified"
		}
	}

	$missing = @($expectedLeaf | Where-Object { $observed -notcontains $_ })
	$unexpected = @($observed | Where-Object { $expectedLeaf -notcontains $_ })

	# Compared as an ordered sequence. Reached only when the two sets agree, so
	# a true here is a pure reordering and nothing else.
	$orderDiffers = ($missing.Count -eq 0 -and $unexpected.Count -eq 0 -and
		(($expectedLeaf -join "`n") -ne ($observed -join "`n")))

	if ($missing.Count -eq 0 -and $unexpected.Count -eq 0 -and -not $orderDiffers) {
		return [pscustomobject]@{
			Status = $script:ComposeSetAgreed
			Expected = $expectedLeaf
			Observed = $observed
			Missing = @()
			Unexpected = @()
			OrderDiffers = $false
			Reason = "the container was created from exactly $($observed -join ', ')"
		}
	}

	$parts = @()
	if ($missing.Count -gt 0) { $parts += "expected but not used by the deployment: $($missing -join ', ')" }
	if ($unexpected.Count -gt 0) { $parts += "used by the deployment but not read: $($unexpected -join ', ')" }
	if ($orderDiffers) { $parts += "same files in a different OVERLAY ORDER - read as [$($expectedLeaf -join ', ')], deployed as [$($observed -join ', ')], and a later overlay overrides an earlier one" }

	return [pscustomobject]@{
		Status = $script:ComposeSetDiverged
		Expected = $expectedLeaf
		Observed = $observed
		Missing = $missing
		Unexpected = $unexpected
		OrderDiffers = $orderDiffers
		Reason = ($parts -join '; ')
	}
}

<#
.SYNOPSIS
	The variables whose movement invalidates a run-to-run comparison.

.DESCRIPTION
	ENUMERATED, for the same reason Get-TuningKnob is: the failure to guard
	against is not "the known variable regressed" but "a variable nobody listed
	moved too". #2931 is precisely that - DOTNET_PROCESSOR_COUNT was not a
	lattice knob, was not in anybody's list, and is the one that broke the
	attribution.

	ATTRIBUTION says what a movement in this variable is sufficient to cause, in
	the words a reader scoring a run needs. It is not decoration: a diff has to
	tell someone who was not present WHY the delta threatens their reading, or
	they will see a changed number and move on.

	CONSUMER records who finally reads the string, which is what decides whether
	a value can be validated locally at all. Where it is a runtime we do not
	own, the manifest can record the value but cannot vouch for its meaning.
#>
function Get-AttributionVariable {
	[CmdletBinding()]
	[OutputType([pscustomobject])]
	param()

	return @(
		[pscustomobject]@{
			Name = 'DOTNET_PROCESSOR_COUNT'
			Service = 'repocontext'
			Consumer = 'the CLR, and every Environment.ProcessorCount consumer in the process'
			Attribution = 'moves the thread pool, Orleans scheduling, the GC heap count where it is not pinned, AND any gate sized from ProcessorCount - so it is sufficient on its own to move almost any throughput or concurrency reading'
		},
		[pscustomobject]@{
			Name = 'LATTICE_WAL_MAX_CONCURRENT_REPLAYS'
			Service = 'repocontext'
			Consumer = 'RepoContextReplayConcurrency.ResolveMaxConcurrentReplays'
			Attribution = 'sets the WAL replay gate directly, so it is sufficient to move replay concurrency, activation-storm CPU, and the peak buffer footprint that produced the OutOfMemoryException wave in #2692'
		},
		[pscustomobject]@{
			Name = 'DOTNET_GCHeapCount'
			Service = 'repocontext'
			Consumer = 'the CLR'
			Attribution = 'sets server GC heap count, so it is sufficient to move pause distribution and peak managed footprint - the axis gate run 2 measured at 20.9% of wall-clock in stop-the-world pauses'
		},
		[pscustomobject]@{
			Name = 'DOTNET_gcServer'
			Service = 'repocontext'
			Consumer = 'the CLR'
			Attribution = 'selects the collector outright, so it is sufficient to move every latency reading taken on the service'
		},
		[pscustomobject]@{
			Name = 'EMBED_INTRA_THREADS'
			Service = 'embedder'
			Consumer = 'EmbedServerOptions.ResolveIntraOpThreads'
			Attribution = 'sizes the ONNX intra-op pool, so it is sufficient to move vectorising throughput and the kernel throttling rate under a fractional grant'
		}
	)
}

<#
.SYNOPSIS
	The resource grants whose movement invalidates a comparison just as surely.

.DESCRIPTION
	Kept apart from Get-AttributionVariable because they are read from a
	different place - the resolved service definition rather than its
	environment block - and a caller that can see one may not be able to see
	the other. Merging them would force a caller to supply both or report a
	false absence for the half it cannot reach, and a false absence is the one
	outcome this whole file exists to prevent.
#>
function Get-AttributionGrant {
	[CmdletBinding()]
	[OutputType([pscustomobject])]
	param()

	return @(
		[pscustomobject]@{
			Name = 'repocontext.cpus'
			Service = 'repocontext'
			Consumer = 'Docker'
			Attribution = 'bounds the CPU the process can obtain, and is the number the cgroup-aware derivations read when their variable is absent - so it is sufficient to move a reading BOTH directly and through every derivation downstream of it'
		},
		[pscustomobject]@{
			Name = 'repocontext.mem_limit'
			Service = 'repocontext'
			Consumer = 'Docker'
			Attribution = 'sets the .NET heap hard limit, so it is sufficient to move collection frequency, and below the working set it produces a STORAGE fault rather than a container kill - a movement here can invalidate a run without any resource event to mark it'
		},
		[pscustomobject]@{
			Name = 'embedder.cpus'
			Service = 'embedder'
			Consumer = 'Docker'
			Attribution = 'bounds embedder CPU and is the grant the intra-op pool derives from when EMBED_INTRA_THREADS is absent'
		},
		[pscustomobject]@{
			Name = 'embedder.mem_limit'
			Service = 'embedder'
			Consumer = 'Docker'
			Attribution = 'bounds embedder memory, and with repocontext.mem_limit determines whether the pair still sums to something the host can honour'
		}
	)
}

<#
.SYNOPSIS
	Decides the resolved processor count and, more importantly, where it came
	from.

.DESCRIPTION
	The PM's requirement on #2931, in his words: a loud 6 is worth more than a
	silent 16. So this returns the count AND its provenance, and treats "I
	cannot tell" as a reportable outcome rather than defaulting quietly.

	The three outcomes and why each is distinct:

	  ExplicitEnvironment  DOTNET_PROCESSOR_COUNT is set and usable. The value
	                       is whatever it says, and it OVERRIDES the cgroup - so
	                       a reader must know the quota is no longer the source.
	  CgroupDerivation     the variable is absent, so Environment.ProcessorCount
	                       resolves from the enforced quota. This is the current
	                       state of the live rig and it is CORRECT; it simply
	                       has to be visible, because it was invisible for
	                       several runs while a predicate asserted otherwise.
	  Indeterminate        the variable is present but unusable, or absent with
	                       no quota reading to derive from. FAIL CLOSED. A
	                       manifest that guessed here would be asserting
	                       provenance it does not have, which is worse than
	                       declining to, because it would be believed.

	A present-but-unusable value is Indeterminate rather than falling back to
	the cgroup on purpose. The CLR's own handling of a malformed value is not
	something this script should model and then present as fact - that is a
	claim about an artefact, made from a script, which is the exact seam this
	epic keeps losing.
#>
function Resolve-ProcessorCountProvenance {
	[CmdletBinding()]
	[OutputType([pscustomobject])]
	param(
		[AllowNull()] [AllowEmptyString()] [string] $Declared,
		[AllowNull()] [nullable[double]] $CgroupCpuQuota
	)

	$raw = if ($null -eq $Declared) { '' } else { $Declared.Trim() }

	if ($raw.Length -gt 0) {
		$parsed = 0

		if ([int]::TryParse(
				$raw,
				[Globalization.NumberStyles]::Integer,
				[Globalization.CultureInfo]::InvariantCulture,
				[ref] $parsed) -and $parsed -gt 0) {
			return [pscustomobject]@{
				Resolved = $parsed
				Source = $script:ProvenanceExplicit
				Declared = $raw
				Reason = "DOTNET_PROCESSOR_COUNT is set to '$raw', which OVERRIDES the cgroup quota process-wide."
			}
		}

		return [pscustomobject]@{
			Resolved = $null
			Source = $script:ProvenanceIndeterminate
			Declared = $raw
			Reason = "DOTNET_PROCESSOR_COUNT is set to '$raw', which is not a positive integer. " +
				'What the CLR does with it is not something this script will guess at and then report as fact.'
		}
	}

	if ($null -eq $CgroupCpuQuota) {
		return [pscustomobject]@{
			Resolved = $null
			Source = $script:ProvenanceIndeterminate
			Declared = ''
			Reason = 'DOTNET_PROCESSOR_COUNT is absent, so the count derives from the enforced CPU quota - ' +
				'but no quota reading was supplied, so the resolved count is unknown.'
		}
	}

	# Ceiling, matching what .NET itself reports for a fractional quota, so a
	# recorded count never disagrees with the runtime in the unsafe direction.
	$derived = [Math]::Max(1, [int][Math]::Ceiling($CgroupCpuQuota))

	return [pscustomobject]@{
		Resolved = $derived
		Source = $script:ProvenanceCgroup
		Declared = ''
		Reason = "DOTNET_PROCESSOR_COUNT is absent, so Environment.ProcessorCount derives from the enforced " +
			"CPU quota of $CgroupCpuQuota, giving $derived. This is the live rig's current state and it is " +
			'correct; it is recorded because it was invisible while a predicate asserted a pinned 16.'
	}
}

<#
.SYNOPSIS
	Builds an ordered manifest from declared and effective readings.

.DESCRIPTION
	`Declared` is what the resolved compose configuration says. `Effective` is
	what the running container actually carries. Both are hashtables keyed by
	variable name; a key absent from either is recorded as absent rather than
	as empty, because those are different states and #2931 is a case of exactly
	that difference going unrecorded.

	Order is the enumeration order of Get-AttributionVariable then
	Get-AttributionGrant, NOT hashtable order, so two manifests of the same
	deployment are byte-identical and a diff of the files is a diff of the
	configuration. A manifest whose line order wandered would show spurious
	deltas and train its reader to skim them.
#>
function New-DeployManifest {
	[CmdletBinding()]
	[OutputType([pscustomobject])]
	param(
		[Parameter(Mandatory)] [hashtable] $Declared,
		[Parameter(Mandatory)] [hashtable] $Effective,
		[AllowNull()] [nullable[double]] $CgroupCpuQuota,
		[AllowNull()] [AllowEmptyString()] [string] $Label,
		[ValidateSet('Available', 'Unreadable', 'NotAttempted')]
		[AllowNull()] [AllowEmptyString()] [string] $DeclarationStatus,
		[AllowNull()] [AllowEmptyString()] [string] $DeclarationReason
	)

	$records = @()

	# An omitted status is inferred, so every existing caller keeps working. The
	# inference is the OLD behaviour and is deliberately the conservative one: an
	# empty reading becomes NotAttempted, never Available, so a caller that forgot
	# to say cannot accidentally license the divergence check against nothing.
	$status = if (-not [string]::IsNullOrWhiteSpace($DeclarationStatus)) {
		$DeclarationStatus
	}
	elseif ($Declared.Keys.Count -gt 0) {
		$script:DeclarationAvailable
	}
	else {
		$script:DeclarationNotAttempted
	}

	foreach ($variable in @(Get-AttributionVariable) + @(Get-AttributionGrant)) {
		$declaredValue = if ($Declared.ContainsKey($variable.Name)) {
			$raw = $Declared[$variable.Name]
			if ($null -eq $raw) { $null } else { [string] $raw }
		}
		else { $null }

		$effectiveValue = if ($Effective.ContainsKey($variable.Name)) {
			$raw = $Effective[$variable.Name]
			if ($null -eq $raw) { $null } else { [string] $raw }
		}
		else { $null }

		$records += [pscustomobject]@{
			Name = $variable.Name
			Service = $variable.Service
			Declared = $declaredValue
			Effective = $effectiveValue
			Attribution = $variable.Attribution
			Consumer = $variable.Consumer
		}
	}

	$provenance = Resolve-ProcessorCountProvenance `
		-Declared ($(if ($Effective.ContainsKey('DOTNET_PROCESSOR_COUNT')) { [string] $Effective['DOTNET_PROCESSOR_COUNT'] } else { '' })) `
		-CgroupCpuQuota $CgroupCpuQuota

	return [pscustomobject]@{
		Label = if ([string]::IsNullOrWhiteSpace($Label)) { 'unlabelled' } else { $Label }
		Records = @($records)
		ProcessorCount = $provenance
		# Whether a DECLARED reading was obtained, and if not why not. Inferring this
		# from ($Declared.Keys.Count -gt 0) - which is what this did until #2983 -
		# cannot tell "resolved, and the file declares nothing" from "never resolved",
		# and the caller's own acquisition gap made the second case 100% of real
		# invocations while it rendered as the first. An explicit status cannot be
		# satisfied by forgetting to acquire.
		DeclarationStatus = $status
		DeclarationReason = if ([string]::IsNullOrWhiteSpace($DeclarationReason)) { '' } else { $DeclarationReason }
		# Retained so existing readers keep working. Now DERIVED from the status
		# rather than from emptiness, so it cannot disagree with it.
		DeclarationAvailable = ($status -eq $script:DeclarationAvailable)
		# Stamped by the instrument that BUILT it, so a freshly-acquired reading
		# and a read-back baseline carry the field in the same place and the
		# comparison never has to special-case which one it is holding.
		ManifestVintage = $script:ManifestVintageCurrent
	}
}

<#
.SYNOPSIS
	Reports where a manifest's declared and effective readings disagree.

.DESCRIPTION
	A divergence is not automatically a defect - a null-valued compose entry
	DECLARES nothing and correctly yields nothing - so the check is asymmetric
	and only reports the cases that can mislead:

	  declared something, effective absent    the value did not reach the
	                                          container; the deployment is not
	                                          the one the file describes
	  declared X, effective Y                 something between the file and the
	                                          container rewrote it

	The reverse - declared absent, effective present - is reported too, because
	it means the value came from somewhere this manifest cannot see, and an
	unattributable value is the thing being hunted.
#>
function Get-DeployManifestDivergence {
	[CmdletBinding()]
	[OutputType([string])]
	param(
		[Parameter(Mandatory)] [pscustomobject] $Manifest
	)

	$divergences = @()

	# Only an AVAILABLE declaration licenses this check. Without a declared half
	# there is nothing to diverge FROM, and comparing against one would report every
	# variable the container carries as unattributable - the guard accusing the
	# deployment of the guard's own missing input.
	#
	# Silence here is correct and is not a weakening: the ATTRIBUTION check
	# (Get-AttributionVerdict) runs regardless and is the half that gates a deploy.
	# But silence must be ATTRIBUTABLE, which is what #2983 was about - the caller
	# never acquired a declaration, so this returned empty on every real invocation
	# and the script printed OK. The status now says which of the two silences it
	# is, and Get-DeclarationSuppression below turns that into a line the operator
	# reads. A check that cannot fire must say so where a passing one would not.
	if ($Manifest.PSObject.Properties.Name -contains 'DeclarationStatus') {
		if ($Manifest.DeclarationStatus -ne $script:DeclarationAvailable) {
			return ,$divergences
		}
	}
	elseif ($Manifest.PSObject.Properties.Name -contains 'DeclarationAvailable' -and
		-not $Manifest.DeclarationAvailable) {
		return ,$divergences
	}

	foreach ($record in $Manifest.Records) {
		$declaredAbsent = $null -eq $record.Declared -or $record.Declared.Length -eq 0
		$effectiveAbsent = $null -eq $record.Effective -or $record.Effective.Length -eq 0

		if ($declaredAbsent -and $effectiveAbsent) {
			continue
		}

		if ($declaredAbsent) {
			$divergences += "$($record.Name) is ABSENT from the resolved configuration but PRESENT in the " +
				"container as '$($record.Effective)'. It came from somewhere this manifest cannot see, so " +
				'its value is not attributable to any tracked file.'
			continue
		}

		if ($effectiveAbsent) {
			$divergences += "$($record.Name) is DECLARED as '$($record.Declared)' but is ABSENT from the " +
				'container. The running deployment is not the one the configuration describes.'
			continue
		}

		if ($record.Declared -ne $record.Effective) {
			$divergences += "$($record.Name) is DECLARED as '$($record.Declared)' but the container carries " +
				"'$($record.Effective)'. Something between the file and the container rewrote it."
		}
	}

	return ,$divergences
}

<#
.SYNOPSIS
	Reports, in one line, that the divergence check did NOT run and why.

.DESCRIPTION
	Returns an empty string when the check ran. Otherwise it names the reason,
	so a suppressed check is visible in exactly the place a reader looks for its
	verdict.

	This exists because #2983 was not, at bottom, a missing `docker compose`
	call. It was that the absence of one was INDISTINGUISHABLE from a clean
	result: Get-DeployManifestDivergence returned zero divergences, the caller
	printed OK, and nothing anywhere said the comparison had not happened. The
	acquisition fix stops that arising; this stops it being silent if it ever
	arises again by another route - a resolution failure, a caller that supplies
	only the effective half, a future overlay that will not resolve.

	The general form is worth stating, because it recurs across this epic: a
	check that can be suppressed needs a channel for "suppressed" that is not
	the same channel as "passed". Zero findings and no findings possible are
	different facts, and rendering them identically is what makes a guard
	report success for work it never did.
#>
function Get-DeclarationSuppression {
	[CmdletBinding()]
	[OutputType([string])]
	param(
		[Parameter(Mandatory)] [pscustomobject] $Manifest
	)

	if (-not ($Manifest.PSObject.Properties.Name -contains 'DeclarationStatus')) {
		return ''
	}

	$status = $Manifest.DeclarationStatus
	$reason = if ($Manifest.PSObject.Properties.Name -contains 'DeclarationReason') { [string] $Manifest.DeclarationReason } else { '' }
	$suffix = if ([string]::IsNullOrWhiteSpace($reason)) { '' } else { " Reason: $reason" }

	switch ($status) {
		'Available' { return '' }
		'Unreadable' {
			return 'DECLARED HALF UNREADABLE: the compose configuration could not be resolved, so the ' +
				'declared/effective divergence check DID NOT RUN. Every declared value below is ' +
				"<unreadable>, which is not the same claim as <absent>.$suffix"
		}
		default {
			return 'DECLARED HALF NOT RESOLVED: no compose resolution was attempted, so the ' +
				'declared/effective divergence check DID NOT RUN. Declared values below are ' +
				"<not-resolved> and assert nothing about the configuration.$suffix"
		}
	}
}

<#
.SYNOPSIS
	Names every attribution-relevant variable that moved between two manifests.

.DESCRIPTION
	Compares EFFECTIVE values, because effective is what a measurement was taken
	under. Comparing declared values would produce a diff of intentions.

	Each delta carries the variable's Attribution string, so the diff says not
	merely that something moved but what a reader's conclusion is now exposed
	to. That is the difference between a log line and evidence.

	A variable absent from the baseline entirely - because the baseline predates
	its being recorded - is reported as Kind 'Unrecorded' rather than as a
	movement. Calling it a change would manufacture a delta out of an
	improvement to the instrument, which is its own way of voiding a comparison.
#>
function Compare-DeployManifest {
	[CmdletBinding()]
	[OutputType([pscustomobject])]
	param(
		[Parameter(Mandatory)] [pscustomobject] $Baseline,
		[Parameter(Mandatory)] [pscustomobject] $Current
	)

	$deltas = @()
	$baselineByName = @{}

	foreach ($record in $Baseline.Records) {
		$baselineByName[$record.Name] = $record
	}

	foreach ($record in $Current.Records) {
		if (-not $baselineByName.ContainsKey($record.Name)) {
			$deltas += [pscustomobject]@{
				Name = $record.Name
				Kind = 'Unrecorded'
				Was = $null
				Now = $record.Effective
				Attribution = $record.Attribution
			}
			continue
		}

		$was = $baselineByName[$record.Name].Effective
		$now = $record.Effective

		if ($was -eq $now) {
			continue
		}

		$kind = if ($null -eq $was -or $was.Length -eq 0) { 'Pinned' }
			elseif ($null -eq $now -or $now.Length -eq 0) { 'Unpinned' }
			else { 'Changed' }

		$deltas += [pscustomobject]@{
			Name = $record.Name
			Kind = $kind
			Was = $was
			Now = $now
			Attribution = $record.Attribution
		}
	}

	return ,$deltas
}

<#
.SYNOPSIS
	Orders two manifest vintages, treating unknown as older than any recorded one.

.DESCRIPTION
	Unknown is $null, never 0, so a manifest that predates the field cannot
	claim a known capability. It still ORDERS as older than any recorded
	vintage, which is the honest reading: the field was added by an instrument
	that could read strictly more than the ones before it.

	Two unknowns are Indeterminate rather than Same. They may be the same
	instrument or two different pre-field ones, and nothing in either file can
	distinguish those - so the relation says so instead of guessing. This is
	deliberately the conservative direction: Indeterminate explains no delta at
	all, so a legacy-against-legacy comparison behaves exactly as it did before
	this function existed, and no historical comparison changes verdict.
#>
function Get-VintageRelation {
	[CmdletBinding()]
	[OutputType([string])]
	param(
		[AllowNull()] [System.Nullable[int]] $BaselineVintage,
		[AllowNull()] [System.Nullable[int]] $CurrentVintage
	)

	if ($null -eq $BaselineVintage -and $null -eq $CurrentVintage) { return $script:VintageIndeterminate }
	if ($null -eq $BaselineVintage) { return $script:VintageBaselineOlder }
	if ($null -eq $CurrentVintage) { return $script:VintageCurrentOlder }

	if ($BaselineVintage -lt $CurrentVintage) { return $script:VintageBaselineOlder }
	if ($BaselineVintage -gt $CurrentVintage) { return $script:VintageCurrentOlder }

	return $script:VintageSame
}

<#
.SYNOPSIS
	Decides whether two manifests are comparable at all, before anything asks
	whether the step between them was attributable.

.DESCRIPTION
	These are different questions and the second is meaningless when the first
	answers no. #2992 is what happens when only the second is asked: three keys
	that the baseline's instrument could not read compared as three pinned
	variables, and the refusal named configuration drift on a rig where nothing
	had moved.

	A vintage difference explains exactly one class of delta, in one direction:

	  BaselineOlder   'Pinned'   (empty -> value). The newer instrument reads a
	                             cell the older one left empty.
	  CurrentOlder    'Unpinned' (value -> empty). The older instrument cannot
	                             read a cell the newer one recorded. This is not
	                             hypothetical - a deploy checkout that has not
	                             been updated runs the older script.
	  Indeterminate   nothing.
	  Same            nothing.

	'Changed' - both sides populated and different - is NEVER explained by a
	vintage difference, in either direction. Two instruments disagreeing about a
	value they can both read is drift whatever wrote them, and excusing it would
	turn this function into the silent-pass defect it exists to prevent.

	THE LOAD-BEARING PROPERTY, and the one to preserve in any future edit:
	a cross-vintage comparison that produces NO explicable delta is still
	COMPARABLE. Incomparability is reported only when the vintage difference
	actually bites. Without that, adding this field would itself refuse every
	comparison against every baseline captured before it - a guard crying wolf
	on its own installation, which is the failure mode that gets guards deleted
	and is the reason Get-AttributionVerdict already excludes 'Unrecorded'.

	KNOWN LIMITATION, deliberate and conservative. An empty cell is
	byte-indistinguishable between "the instrument could not read it" and "the
	deployment genuinely does not set it" - the same shape AMENDMENT 25 records
	for DECLARATION_STATUS, one level down. So against an UNKNOWN-vintage
	baseline this cannot tell a newly-readable cell from a newly-pinned one, and
	it refuses both.

	That is the safe direction: it declines to SCORE the comparison rather than
	silently excusing a real change, and exit 3 is not exit 0. But it does mean
	a genuine pin against a legacy baseline is refused rather than attributed.

	The remedy is to re-capture the baseline with the current instrument, after
	which the relation is Same and every delta is scored normally. The remedy is
	NOT a hand-authored list of "keys this vintage newly learned to read": such a
	list cannot be checked for completeness, and a guard whose coverage is a list
	nobody can audit is the defect family this epic exists to remove.

	Concretely, at the time of writing DOTNET_PROCESSOR_COUNT is the one cell
	carrying effective=<absent> in run-13-postfix.manifest, so a run that pins it
	against that baseline is refused as incomparable rather than attributed.
#>
function Get-ComparabilityVerdict {
	[CmdletBinding()]
	[OutputType([pscustomobject])]
	param(
		[Parameter(Mandatory)] [AllowEmptyCollection()] [array] $Deltas,
		[Parameter(Mandatory)] [string] $Relation
	)

	$explicableKind = switch ($Relation) {
		$script:VintageBaselineOlder { 'Pinned' }
		$script:VintageCurrentOlder { 'Unpinned' }
		default { '' }
	}

	$explained = @()

	if ($explicableKind) {
		$explained = @($Deltas | Where-Object { $_.Kind -eq $explicableKind })
	}

	if ($explained.Count -eq 0) {
		return [pscustomobject]@{
			Comparable = $true
			Relation = $Relation
			ExplainedCount = 0
			ExplainedNames = @()
			Summary = ''
		}
	}

	$names = ($explained | ForEach-Object { $_.Name }) -join ', '
	$direction = if ($Relation -eq $script:VintageBaselineOlder) {
		'the baseline was written by an OLDER instrument that could not populate them'
	}
	else {
		'the current reading was taken by an OLDER instrument that cannot populate them'
	}

	return [pscustomobject]@{
		Comparable = $false
		Relation = $Relation
		ExplainedCount = $explained.Count
		ExplainedNames = @($explained | ForEach-Object { $_.Name })
		Summary = "These two manifests were written by different instrument versions and are NOT " +
			"comparable on $($explained.Count) key(s): $names. Each shows as a movement because " +
			"$direction - not because the deployment changed. Re-capture the baseline with the " +
			'current instrument, or pass an explicitly comparable one, before reading any verdict ' +
			'about attribution.'
	}
}

<#
.SYNOPSIS
	Decides whether a step is attributable, and says why not when it is not.

.DESCRIPTION
	THIS IS THE POINT OF THE FILE. Everything above records; this adjudicates.

	A step that moves ONE attribution-relevant variable supports attributing a
	measured movement to it. A step that moves TWO supports attributing it to
	neither, which is what happened to the 16 -> 6 reading: the gate knob moved
	and the processor-count pin was removed together, and both are sufficient.

	'Unrecorded' deltas are excluded from the count. They are an artefact of the
	instrument improving, not of the deployment changing, and counting them
	would make the first run after any addition here permanently unattributable
	- a guard that cries wolf on its own installation is a guard that gets
	switched off.

	This never throws and never blocks by itself. It returns a verdict, and
	Assert-DeployManifest.ps1 turns a NotAttributable verdict into a non-zero
	exit UNLESS the operator acknowledged the multi-variable step. That is the
	whole mechanism: changing two variables at once stays POSSIBLE, because
	sometimes it is necessary, and stops being SILENT, which is what voids a
	comparison.
#>
function Get-AttributionVerdict {
	[CmdletBinding()]
	[OutputType([pscustomobject])]
	param(
		[Parameter(Mandatory)] [AllowEmptyCollection()] [array] $Deltas
	)

	$moved = @($Deltas | Where-Object { $_.Kind -ne 'Unrecorded' })

	if ($moved.Count -eq 0) {
		return [pscustomobject]@{
			Attributable = $true
			MovedCount = 0
			Summary = 'No attribution-relevant variable moved. A measured movement is attributable to the code under test.'
			Detail = @()
		}
	}

	if ($moved.Count -eq 1) {
		$one = $moved[0]
		return [pscustomobject]@{
			Attributable = $true
			MovedCount = 1
			Summary = "Exactly one attribution-relevant variable moved: $($one.Name) ($($one.Kind), " +
				"'$($one.Was)' -> '$($one.Now)'). A measured movement is attributable to it OR to the code " +
				'under test, and those two are separable only if one of them is held across a further run.'
			Detail = @("$($one.Name): $($one.Attribution)")
		}
	}

	$names = ($moved | ForEach-Object { $_.Name }) -join ', '

	return [pscustomobject]@{
		Attributable = $false
		MovedCount = $moved.Count
		Summary = "$($moved.Count) attribution-relevant variables moved in one step: $names. " +
			'Any measured movement now has more than one sufficient cause and is attributable to NONE of them. ' +
			'This is the defect recorded in issue #2931, where a WAL replay gate moving 16 -> 6 could not be ' +
			'attributed because a processor-count pin was removed in the same step.'
		Detail = @($moved | ForEach-Object {
			"$($_.Name) ($($_.Kind), '$($_.Was)' -> '$($_.Now)'): $($_.Attribution)"
		})
	}
}

<#
.SYNOPSIS
	Renders a manifest as the stable, citable text the run captures.

.DESCRIPTION
	Deterministic and ordered, so two manifests of the same configuration are
	byte-identical and `diff` is a meaningful operation on them. Written as a
	file rather than only to the console because the PM has to CITE it when
	scoring a run, and a scrollback is not evidence - it is not addressable, it
	is not durable, and it is not something a second reader can check.

	Absent is rendered as `<absent>` rather than as an empty field. An empty
	field beside a name reads as a value that happens to be blank, and this
	whole issue is a case of absent and empty being confused.

	DECLARATION_STATUS records whether the declared half was acquired at all,
	and DECLARATION_RESOLVED records HOW MANY keys it came back with. Both are
	written, because the first is a verdict and the second is its denominator:
	a resolution that succeeds and returns nothing still reports Available, so
	a reader given only the status cannot tell a populated declaration from an
	empty one. DECLARATION_RESOLVED renders a count only when the status is
	Available, and otherwise repeats the declared column's placeholder - `0 of
	9` is a finding when resolution ran and an artefact when it did not, and
	printing the same digits for both would rebuild the confusion.

	MANIFEST_VINTAGE records which instrument wrote the file. Without it a
	manifest says what the deployment was but not what the reader could SEE, so
	an instrument that learns to read a new cell makes every older baseline
	appear to have changed. That is #2992, and it refused a rig whose containers
	both reported RestartCount=0.
#>
function Format-DeployManifest {
	[CmdletBinding()]
	[OutputType([string])]
	param(
		[Parameter(Mandatory)] [pscustomobject] $Manifest,
		[AllowNull()] [AllowEmptyString()] [string] $GeneratedAt
	)

	$stamp = if ([string]::IsNullOrWhiteSpace($GeneratedAt)) { '<unrecorded>' } else { $GeneratedAt }
	$lines = @()

	$lines += '# DEPLOY MANIFEST - attribution-relevant configuration (issue #2931)'
	$lines += '#'
	$lines += '# Every variable below is sufficient ON ITS OWN to move a throughput,'
	$lines += '# latency or concurrency reading. Two of them moving in one step makes a'
	$lines += '# measured movement attributable to neither. Diff this file between runs'
	$lines += '# BEFORE scoring one against the other.'
	$lines += '#'
	$lines += "# label        : $($Manifest.Label)"
	$lines += "# generated at : $stamp"
	$lines += ''
	# First of the key lines because it describes the FILE, not the deployment:
	# a reader has to know which instrument wrote the rest before any of it can
	# be compared against anything. Absent in every manifest written before
	# #2992, which reads back as unknown rather than as zero.
	#
	# Taken from the manifest rather than from the constant, so re-rendering a
	# read-back legacy manifest does not silently STAMP it with the current
	# vintage. Promoting an old file to a known capability it never had is the
	# same hazard AMENDMENT 25 records for DECLARATION_STATUS, and the fix is
	# the same: carry the absence through instead of defaulting it.
	$vintage = if ($Manifest.PSObject.Properties.Name -contains 'ManifestVintage') { $Manifest.ManifestVintage } else { $null }

	if ($null -ne $vintage) {
		$lines += "MANIFEST_VINTAGE=$vintage"
	}

	$lines += "PROCESSOR_COUNT_RESOLVED=$(if ($null -eq $Manifest.ProcessorCount.Resolved) { '<indeterminate>' } else { $Manifest.ProcessorCount.Resolved })"
	$lines += "PROCESSOR_COUNT_SOURCE=$($Manifest.ProcessorCount.Source)"

	# Recorded IN the manifest, not merely on the console, because the file is what
	# gets cited when a run is scored. A reader who cannot tell from the file alone
	# whether the declared column is evidence or an unfilled gap will read it as
	# evidence - which is how #2983 survived thirteen deployments.
	$status = if ($Manifest.PSObject.Properties.Name -contains 'DeclarationStatus' -and
		-not [string]::IsNullOrWhiteSpace($Manifest.DeclarationStatus)) { $Manifest.DeclarationStatus } else { 'NotAttempted' }
	$reason = if ($Manifest.PSObject.Properties.Name -contains 'DeclarationReason') { [string] $Manifest.DeclarationReason } else { '' }
	$lines += "DECLARATION_STATUS=$status"
	$lines += "DECLARATION_REASON=$(if ([string]::IsNullOrWhiteSpace($reason)) { '<none>' } else { $reason })"

	# `<absent>` asserts the key is not declared. That is only true when the
	# declaration was actually read, so when it was not, the declared column renders
	# as `<unreadable>` or `<not-resolved>` instead. Same width, different claim.
	$declaredPlaceholder = switch ($status) {
		'Available' { '<absent>' }
		'Unreadable' { '<unreadable>' }
		default { '<not-resolved>' }
	}

	# The STATUS is a verdict; this is its denominator. A status of Available says
	# resolution was attempted and succeeded - it does NOT say how many keys came
	# back, and an empty-but-successful resolution reports Available over nine
	# `<absent>` rows. That is not hypothetical: it is exactly what the #2983
	# mutation test reproduced, where the assertion on the STATUS passed against a
	# reading that had resolved nothing and only the count caught it.
	#
	# Rendered with the same placeholder discipline as the declared column, because
	# `0 of 9` from a resolution that ran is a finding, while `0 of 9` from one that
	# never ran is an artefact of not looking. Printing the same digits for both
	# would rebuild the conflation this line exists to prevent.
	$resolvedCount = 0
	foreach ($record in $Manifest.Records) {
		if ($null -ne $record.Declared -and $record.Declared.Length -gt 0) { $resolvedCount++ }
	}
	$totalCount = @($Manifest.Records).Count
	$lines += "DECLARATION_RESOLVED=$(if ($status -eq 'Available') { "$resolvedCount of $totalCount" } else { $declaredPlaceholder })"
	$lines += ''

	foreach ($record in $Manifest.Records) {
		$declared = if ($null -eq $record.Declared -or $record.Declared.Length -eq 0) { $declaredPlaceholder } else { $record.Declared }
		$effective = if ($null -eq $record.Effective -or $record.Effective.Length -eq 0) { '<absent>' } else { $record.Effective }
		$lines += "$($record.Name)|declared=$declared|effective=$effective"
	}

	return ($lines -join "`n") + "`n"
}

<#
.SYNOPSIS
	Reads back a manifest rendered by Format-DeployManifest.

.DESCRIPTION
	The inverse of the renderer, and deliberately tolerant in exactly one
	direction: a line it does not understand is skipped, so a manifest written
	by a later version with extra fields still yields a usable baseline instead
	of refusing to compare at all. A baseline that cannot be read is a
	comparison that silently does not happen, which is the failure mode this
	file exists to remove - so the tolerant choice is the safe one HERE, though
	it would not be in the adjudicating functions above.

	Round-trip fidelity on the fields it does understand is asserted by
	Test-DeployManifest.ps1; without that the renderer and this could drift and
	every diff would be against a subtly different object.
#>
function Read-DeployManifest {
	[CmdletBinding()]
	[OutputType([pscustomobject])]
	param(
		[Parameter(Mandatory)] [AllowEmptyString()] [string] $Text
	)

	$records = @()
	$label = 'unlabelled'
	$resolved = $null
	$source = $script:ProvenanceIndeterminate
	$attribution = @{}
	# A manifest written before #2983 carries no DECLARATION_STATUS line. Defaulting
	# it to NotAttempted is the honest reading of such a file: its declared column
	# was never acquired. Defaulting to Available would retroactively promote every
	# historical `<absent>` into a positive finding it never was.
	$declarationStatus = $script:DeclarationNotAttempted
	$declarationReason = 'no DECLARATION_STATUS recorded; manifest predates #2983'
	# Deliberately $null rather than 0. A manifest that never recorded a count is
	# not a manifest that resolved nothing, and a reader that cannot distinguish
	# the two will score an unmeasured baseline as a measured-and-empty one.
	$declarationResolved = $null
	$declarationTotal = $null
	# $null, never 0. A manifest with no vintage line was written by an
	# instrument whose acquisition capability is UNKNOWN, which is a different
	# claim from "capability zero" - the latter is a value, and would let a
	# legacy file compare as merely older while asserting that what it could
	# read is known. See Get-VintageRelation.
	$manifestVintage = $null

	foreach ($variable in @(Get-AttributionVariable) + @(Get-AttributionGrant)) {
		$attribution[$variable.Name] = $variable
	}

	foreach ($line in ($Text -split "`r?`n")) {
		$trimmed = $line.Trim()

		if ($trimmed.StartsWith('# label')) {
			$separator = $trimmed.IndexOf(':')
			if ($separator -ge 0) {
				$label = $trimmed.Substring($separator + 1).Trim()
			}
			continue
		}

		if ($trimmed.Length -eq 0 -or $trimmed.StartsWith('#')) {
			continue
		}

		if ($trimmed.StartsWith('MANIFEST_VINTAGE=')) {
			$value = $trimmed.Substring('MANIFEST_VINTAGE='.Length)
			# Only a well-formed non-negative integer is a vintage. Anything else
			# leaves it unknown rather than guessing, because a malformed vintage
			# that parsed to 0 would claim comparability the file cannot support.
			if ($value -match '^\s*(\d+)\s*$') {
				$manifestVintage = [int] $Matches[1]
			}
			continue
		}

		if ($trimmed.StartsWith('PROCESSOR_COUNT_RESOLVED=')) {
			$value = $trimmed.Substring('PROCESSOR_COUNT_RESOLVED='.Length)
			$parsed = 0
			$resolved = if ([int]::TryParse($value, [ref] $parsed)) { $parsed } else { $null }
			continue
		}

		if ($trimmed.StartsWith('PROCESSOR_COUNT_SOURCE=')) {
			$source = $trimmed.Substring('PROCESSOR_COUNT_SOURCE='.Length)
			continue
		}

		if ($trimmed.StartsWith('DECLARATION_STATUS=')) {
			$declarationStatus = $trimmed.Substring('DECLARATION_STATUS='.Length)
			continue
		}

		if ($trimmed.StartsWith('DECLARATION_REASON=')) {
			$value = $trimmed.Substring('DECLARATION_REASON='.Length)
			$declarationReason = if ($value -eq '<none>') { '' } else { $value }
			continue
		}

		if ($trimmed.StartsWith('DECLARATION_RESOLVED=')) {
			$value = $trimmed.Substring('DECLARATION_RESOLVED='.Length)
			# Only an `<n> of <m>` reading is a measurement. Any placeholder leaves
			# both halves $null, so a caller asking "how many resolved" gets "not
			# measured" rather than a number it would treat as one.
			if ($value -match '^\s*(\d+)\s+of\s+(\d+)\s*$') {
				$declarationResolved = [int] $Matches[1]
				$declarationTotal = [int] $Matches[2]
			}
			continue
		}

		$parts = $trimmed -split '\|'

		if ($parts.Count -ne 3 -or -not $parts[1].StartsWith('declared=') -or -not $parts[2].StartsWith('effective=')) {
			continue
		}

		$name = $parts[0]
		$declared = $parts[1].Substring('declared='.Length)
		$effective = $parts[2].Substring('effective='.Length)

		# All three placeholders read back as $null - there is no VALUE in any of
		# them. Which of the three it was is carried by DeclarationStatus, not by
		# the per-record field, so a reader cannot get the two out of step.
		$declaredValue = if ($declared -in @('<absent>', '<unreadable>', '<not-resolved>')) { $null } else { $declared }

		$records += [pscustomobject]@{
			Name = $name
			Service = if ($attribution.ContainsKey($name)) { $attribution[$name].Service } else { '<unknown>' }
			Declared = $declaredValue
			Effective = if ($effective -eq '<absent>') { $null } else { $effective }
			Attribution = if ($attribution.ContainsKey($name)) { $attribution[$name].Attribution } else { 'not enumerated by this version of the manifest' }
			Consumer = if ($attribution.ContainsKey($name)) { $attribution[$name].Consumer } else { '<unknown>' }
		}
	}

	return [pscustomobject]@{
		Label = $label
		Records = @($records)
		DeclarationStatus = $declarationStatus
		DeclarationReason = $declarationReason
		DeclarationAvailable = ($declarationStatus -eq $script:DeclarationAvailable)
		DeclarationResolvedCount = $declarationResolved
		DeclarationRecordCount = $declarationTotal
		ManifestVintage = $manifestVintage
		ProcessorCount = [pscustomobject]@{
			Resolved = $resolved
			Source = $source
			Declared = ''
			Reason = 'read back from a recorded manifest'
		}
	}
}