Phase B: per-phase memory instrumentation (ADR-029)#27
Merged
Conversation
…vents
Add Get-RuntimeMemorySnapshot helper returning managedHeapMB,
workingSetMB, privateBytesMB (all 1dp), and gen0/1/2 collection counts.
GC.GetTotalMemory($false) so no GC pass is forced.
Snapshot embedded in data.memory for:
- Every PhaseStart and PhaseEnd event (Phases 1-6 = 12 boundaries).
- Every Phase 2 EnumerationProgress event (~5000-object cadence).
- New MidEnumerationDrain events emitted only when a productive
drain pass freed >=1 completed handle, so post-run analysis can
correlate drain bursts with managed-heap movement.
Cheap: no allocations beyond the returned hashtable, no I/O. Produces
a runtime memory time-series in the JSONL log without changing
script behavior. Prepares for the next live-environment diagnostic run
against the work-computer 30k-object domain that hit a memory ceiling
even after the Phase A drain/Item-pinning fixes.
ADR-029 captures the rationale.
Records Get-RuntimeMemorySnapshot helper + the events it rides on (12 phase boundaries + Phase 2 EnumerationProgress + new MidEnumerationDrain). The ADR itself lives in the vault project notebook at ../decisions.md.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase B — Memory instrumentation
Phase B of the reconciliation plan (
plans/polished-inventing-whisper.md). PR #26 ported six categories of work-computer platform fixes onto trunk, but the underlying 8+ GB working-set ceiling on the ~30k-object live run is undiagnosed (no JSONL retained). Before another live run, add structured memory measurement so the next run produces data we can reason from.What changed
scripts/Invoke-ADPermissionAnalysis.ps1Get-RuntimeMemorySnapshothelper. Returns a 6-field hashtable:managedHeapMB—GC.GetTotalMemory($false)/ 1MB, 1dp (no forced collection)workingSetMB—Process.WorkingSet64/ 1MB, 1dpprivateBytesMB—Process.PrivateMemorySize64/ 1MB, 1dpgen0Collections,gen1Collections,gen2Collections—GC.CollectionCount(n)data.memoryfor:PhaseStart/PhaseEndevent (Phases 1-6, 12 boundaries).EnumerationProgressevent (~5000-object cadence).MidEnumerationDrainevents emitted only when a drain pass freed >=1 completed handle (so post-run analysis can correlate drain bursts with managed-heap movement).The helper lives in the entry script. Runspaces don't call it — the orchestrator's drain block already sees per-batch boundaries.
CHANGELOG.mdEntry under
[Unreleased] / Added.Why this and not a speculative memory fix
Phase A already shipped the obvious memory mitigations (Item-pinning removal, mid-enumeration drain, incremental
$aceRecords). Those weren't enough. Without per-phase telemetry we don't know:Speculate-fixing into that unknown is how engineering teams build the wrong solution well. Measure first.
ADR-029 in the vault project notebook captures the rationale.
Verification
Invoke-Build -Configuration Release— clean, 150 tests pass / 0 failed / 1 skipped, coverage 93.01% (gate 86% per ADR-026).unreachable.invalid(LDAP bind fails as expected, exit 1) — firstPhaseStartevent in the JSONL carriesdata.memorywith all 6 fields populated.Follow-up
Phase C of the reconciliation plan: controlled re-run protocol on the work computer using this instrumentation. Phase D selects targeted optimisations from the captured data.
Notes
GC.Collect, noProcess.Refresh, no side effects.System.GCandSystem.Diagnostics.Processare already loaded.../decisions.md) under the dual-track workflow, not in this repo.