Repository navigation
Tracking: coordinated changes to the capability-map generator and schema (#71, #82, #83, contextScope) #84
Description
Activity
juemerson-at-purestorage commented
on Aug 2, 2026 CollaboratorAuthorMore actionsCross-link: #85 is a workflow-enablement blocker that sits ahead of both PRs planned here.
The report generators emit records in filesystem-enumeration order, so regenerating on the
Linux CI runner instead of a Windows workstation produces a 10,218-line diff in
Reports/PfbFieldCmdletMap.jsoncontaining zero semantic change (2015 entries both sides,
canonical diffs 0, all 2015 moved).Relevance to this tracker specifically:
Data/PfbCapabilityMap.json— the artifact this issue coordinates — is not affected.
tools/Build-PfbCapabilityMap.ps1never walksPublic//Private/; its onlyGet-ChildItem
is over$SpecsDirectory(:86) and every spec enumeration is explicitly sorted (:91-95).
Same forReports/PfbValueEnumMap.json.- But both PR 1 and PR 2 regenerate the derived reports too, so either one will drag the
phantom diff along with it unless Report generators emit in filesystem order: a 10k-line phantom diff blocks the capability-map auto-PR #85 lands first. That would bury PR 1'"'"'s genuinely
interesting diff — the 23 newly-visible body fields from Capability map records no body fields for array-bodied endpoints (schema walk never descends throughitems) #82 and the 5introducedVersion
corrections from Capability map records 5 body fields with introducedVersion one release too late (MaxDepth=8 truncation in fb2.12-2.16) #71 — inside ~11k lines of reordering.
Also relevant to the assumption corrections already recorded here: the regeneration path is
currently broken.update-api-capability-map.ymlhas failed on every run since 2026-07-24,
always at the finalOpen pull requeststep (GitHub Actions is not permitted to create or approve pull requests— a repo setting, not a code fault). Generation and the full test suite
pass, and the branch is still force-pushed, soorigin/automated/update-api-capability-map
holds regenerations thatmainhas never received. Fixing that needs repo-admin access.Suggested order: #85 (sort) → permission toggle → PR 1 → PR 2. Unblocking the permission
before the sort lands means the first auto-PR arrives as an unreviewable 11k-line diff.juemerson-at-purestorage commented
on Aug 4, 2026 CollaboratorAuthorMore actionscontextScopeis leaving PR 2 — the sharedschemaVersion 2pairing is dissolvedThis tracker plans PR 2 as #83 (array cardinality) + the Fusion
contextScopefield from
#25, sharing oneschemaVersion 2bump. That pairing is dissolved. Recording it here so the
plan above does not mislead whoever picks this up.What changed
Before Now contextScope(#25)PR 2, shared bump Fusion Phase 0 PR, takes schemaVersion 2#83 array cardinality PR 2, shared bump Stays with this tracker; increments from whatever it finds #71 + #82 PR 1, no schema change Unchanged The Fusion work is now split into a Phase 0 (prerequisites) and Phase 1 (injection), spec'd on
feat/fusion-context-phase-0.contextScopeis a Phase 0 item because kind-vs-scope validation
and every scope-aware error message in Phase 1 are map lookups and cannot be written before the
field exists.Why not just absorb all of this into Phase 0 instead
That was the alternative considered, and it would have preserved the one-bump intent. It was
rejected for a structural reason rather than a size one: #71, #82 and #83 all land in
Add-PfbSchemaPropertyNodes(tools/lib/PfbSpecTools.ps1:191) — a recursive schema walker
whoseMaxDepththreads through five call sites and which feeds both
Data/PfbCapabilityMap.jsonandData/PfbResponseShapeMap.json, plus every derived report.
Changing it perturbs two runtime artifacts at once.It also has a downstream consumer with nothing to do with Fusion: #44 is blocked on PR 1,
since its four endpoints are exactly the ones #82 makes visible. That is an argument for this
work standing on its own regardless of what Fusion does.contextScope, by contrast, reads operation-levelx-pure-*extensions and never touches the
body-schema walk. The two changes are genuinely independent in code — they collide only on
the generated artifact.Consequences
-
Two sequential regenerations of
Data/PfbCapabilityMap.json. Accepted. Whichever PR lands
second regenerates and resolves the conflict that way — a 632-endpoint generated file should
never be hand-merged. -
schemaVersionnumbers are not pre-assigned. Phase 0 intends 2, but if Capability map cannot record array-body cardinality constraints (minItems/maxItems/uniqueItems) — needs schemaVersion 2 #83 lands first it
takes 2 and Phase 0 takes 3. The number carries no meaning; only "newer than what I read"
does. Confirmed: nothing inPrivate/orPublic/readsschemaVersionat all, and it is
per-artifact — five generators each write their own independent value, all currently1:Artifact Generator Data/PfbCapabilityMap.jsonBuild-PfbCapabilityMap.ps1:317Data/PfbResponseShapeMap.jsonBuild-PfbResponseShapeMap.ps1:173Reports/PfbApiDriftReport.jsonBuild-PfbApiDriftReport.ps1:637Reports/PfbFieldCmdletMap.jsonBuild-PfbFieldCmdletMap.ps1:98Reports/PfbValueEnumMap.jsonBuild-PfbValueEnumMap.ps1:153So the bump is a maintainer label, not a migration gate, and bumping one does not implicate the
other four.
Two notes on the regeneration path, still open
#85 is closed, so the 10k-line phantom-diff hazard is gone — that was the blocker most likely
to bury either PR's real diff.But the auto-PR step is still failing.
update-api-capability-map.ymlhas failed on every run
since 2026-07-24 atOpen pull request
(GitHub Actions is not permitted to create or approve pull requests— a repo setting, not a
code fault). Generation and the full suite pass and the branch is still force-pushed, so
origin/automated/update-api-capability-mapholds regenerationsmainhas never received.
Anyone about to regenerate by hand — for either PR — should diff against that branch first rather
than re-deriving work that already exists. Fixing the workflow needs repo-admin access.Sequencing between this tracker's PR 1 and the Fusion Phase 0 PR is still being decided; this
comment only records that they are no longer one unit.-
juemerson-at-purestorage commented
on Aug 5, 2026 CollaboratorAuthorMore actionsSequencing decided: Fusion Phase 0 first, then PR 1
My earlier comment
dissolved thecontextScope+ #83 pairing but left the order between this tracker's
PR 1 (#71 + #82) and the Fusion Phase 0 PR open. Recording the decision here
before either PR opens, so both arrive with their context already stated.Order: Phase 0 lands first and takes
schemaVersion 2. PR 1 follows immediately,
rebases onto it, and regenerates once on the stable base.Why this order and not the reverse
Both PRs regenerate
Data/PfbCapabilityMap.json, and — as recorded above — there is
no CI gate comparing the committed artifact against what the generator would produce.
cross-platform-tests.ymlnever fetches the gitignoredtools/specs/, so every
real-artifact assertion skips silently in PR CI. That makes the human-readable artifact
diff the only verification either PR has.The two PRs are not symmetric in how much they depend on that diff:
- Phase 0's claim is "one additive field per operation, nothing else moved." That is
only checkable against an unmoved base. Regenerating it on top of PR 1's 23 recovered
bodyPropertiesand 5introducedVersioncorrections destroys the evidence. - PR 1's claim is backed by unit fixtures that fail before the fix and pass after,
plus a diff characterised in advance down to the specific endpoints and field counts.
That survives being re-derived on a moved base.
So the PR whose verification is fragile goes first. Reversing it would cost Phase 0 its
primary evidence and gain nothing.What this means in practice
- Two consecutive regenerations of
Data/PfbCapabilityMap.jsonare expected and
deliberate — not churn, and not one PR undoing the other. Each PR body says so. - PR 1 will open carrying a not-yet-regenerated artifact. That is deliberate and it
is what the missing CI gate makes viable: the branch will not go red for it. The
regeneration lands as its own reviewable commits after Phase 0 merges. If it is easier
to review that way, PR 1 can sit as a draft until then. schemaVersion2 goes to Phase 0. Capability map cannot record array-body cardinality constraints (minItems/maxItems/uniqueItems) — needs schemaVersion 2 #83 increments from whatever it finds — 3 if
Phase 0 has landed. As established above, the number is a per-artifact maintainer
label that nothing inPrivate/orPublic/reads, so this costs nothing.- Whichever PR regenerates second resolves the JSON conflict by regenerating, never by
hand. A 632-endpoint generated file should not be hand-merged. - Batch-operation cmdlets (nodes, resource-accesses, workload-tags, fleet-members) #44 is unblocked by PR 1, unchanged by this ordering — it just arrives one merge later.
Unchanged and still open
The auto-PR step of
update-api-capability-map.ymlis still failing at
Open pull request(GitHub Actions is not permitted to create or approve pull requests)
on every run since 2026-07-24, soorigin/automated/update-api-capability-mapstill holds
aReports/-only regenerationmainhas never received. It is currently 1 ahead / 1 behind
main. PR 1 will diff its regenerated reports against that branch rather than re-deriving
the work. Fixing the workflow needs repo-admin access.- Phase 0's claim is "one additive field per operation, nothing else moved." That is
- added 5 commits that reference this issue
on Aug 5, 2026 juemerson-at-purestorage commented
on Aug 5, 2026 CollaboratorAuthorMore actionsStatus: three of the four are done, #83 is the only one left
# Change Landed in State #25 / #72 contextScopefrom thex-pure-*extensions plus the curated table#96 done #71 MaxDepth=8truncation#97 done #82 Walk never descends items#97 done at map/reporting scope; runtime half is #95 #83 bodyConstraintsforminItems/maxItems/uniqueItems— outstanding Both PRs were stacked on
integration/capability-map-2026-08and come tomaintogether in
#98, which carries the closing keywords for #71, #74 and #82. They were deliberately not
merged tomainone at a time: since both regenerateData/PfbCapabilityMap.json, merging in
parallel would have made each one's artifact diff unreadable. Stacking kept each diff clean and
let the combined state be built and tested before anything reachedmain.The two-PR plan this issue called for held up exactly as written.
Four things this issue got right, confirmed in practice
- No byte-identical regeneration gate exists. Confirmed. Because of it, the map had to be
verified by hand: reverting onlytools/lib/PfbSpecTools.ps1to the base reproduces the prior
map byte-identically, which proves the generator deterministic and attributes 100% of the
diff to the intended code rather than drift or staleness. - The
schemaVersionbump really is just a label. Nothing inPrivate/orPublic/reads
it. Cost was a handful of fixtures, as predicted. - The "nothing vanishes" invariant is the requirement none of the child issues carried, and
it bit exactly as described — Capability map records no body fields for array-bodied endpoints (schema walk never descends throughitems) #82's 23 new fields had to be accounted for in the drift report
in the same change. - It silently skips without
tools/specs/. Also confirmed, and worse than it sounds: a
scoped run reporting0 skippedstill does not prove the real-artifactDescribeblocks
executed. They had to be checked explicitly (they did — 10 ran/0 skip and 14 ran/0 skip). See
CI silently skips ~23% of the test suite, including the absolute-path regression guards #63.
Two corrections for whoever does #83
- Expect two order-only records, not one. Alongside the predicted
PATCH /ssh-certificate-authority-policies,PATCH /file-systemsalso moved — top-level key
order only,contextScopeandreadOnlyBodyPropertiesswapping position, all values identical.
Deterministic across three regenerations. Diagnose an unexpected order-only diff rather than
assuming it is noise, but know that two are normal here. bodyPropertieswas never{}on the Capability map records no body fields for array-bodied endpoints (schema walk never descends throughitems) #82 endpoints. Each held one entry keyed by the
empty string. Anyone grepping for{}to find affected endpoints will come up empty.
#83 will inherit
schemaVersion2, not 1, and increments from there.- No byte-identical regeneration gate exists. Confirmed. Because of it, the map had to be
- added a commit that references this issue
on Aug 13, 2026 juemerson-at-purestorage commented
on Aug 20, 2026 CollaboratorAuthorMore actionsClosing: the coordination this issue existed for is done
Three of the four changes landed as planned —
contextScope(#96), #71 and #82 (both #97,
reachingmaintogether via #98). #83 is the only one outstanding, and it now collides with
nothing but #95. Two issues that already cross-reference each other do not need a third place to
keep in sync, so this closes rather than being retitled.The two-PR plan held up as written, and the four assumption-corrections recorded above were all
confirmed in practice. What follows is the part that has not aged well, stated plainly because
this issue's body reads the other way and would mislead whoever picks up #83.Three recorded facts have since been inverted
This issue says Now Consequence There is no byte-identical regeneration gate on Data/PfbCapabilityMap.json— and the sequencing plan explicitly allowed a PR to "open carrying a not-yet-regenerated artifact"A gate exists. PR #130 added scripts/Assert-PfbDerivedArtifacts.ps1andverify-derived-artifacts.yml, regenerating all eleven derived artifacts onpull_requestand diffing against the committed copies#83 must regenerate in-PR. A stale artifact now fails the build instead of being caught by eye The real-artifact assertions "skip silently in a fresh clone or worktree and only bite in CI" They execute in CI. The prepare-specsjob added for #63 publishes the spec cache as artifactpfb-specsto both test jobs, andTests/coverage-baseline.psd1names those blocks underRequiredDescribesThe "artifact diff is the only verification either PR has" premise is gone. A green local run without a spec cache is still not evidence — that half stands The auto-PR step fails on a repo permission, so origin/automated/update-api-capability-mapholds regenerationsmainnever received — diff against it rather than re-deriving (said in two comments)Both halves are stale. update-api-capability-map.ymlhas been succeeding since at least 2026-08-14. That branch is 1 ahead / 186 behindmain, its one commitReports/-only and dated 2026-08-04Following the instruction would reintroduce months of stale reports. Regenerate from mainThe gate in #130 is worth one more note, because it is the thing this issue asked for and
assumed impossible. The reason a hard gate is safe now, where the advisory check in
update-api-capability-map.ymlwas not: it pins the spec set to the committed map's own
generatedFromlist, which separates PR-caused drift from spec-publication drift.What was transplanted, and where
Nothing here is lost, but it is no longer here:
- The "nothing vanishes" invariant (
Tests/Build-PfbApiDriftReport.Tests.ps1:707) — the
requirement this issue correctly noted "appears in none of the individual issues" — is now
recorded on Capability map cannot record array-body cardinality constraints (minItems/maxItems/uniqueItems) — needs schemaVersion 2 #83, along with the current per-endpoint key set for all four array-bodied
endpoints and the two regeneration gotchas confirmed on fix(tools): walk array item schemas and raise MaxDepth (#71, #82) #97 (two order-only records, not one;
bodyPropertieswas keyed by the empty string pre-Capability map records no body fields for array-bodied endpoints (schema walk never descends throughitems) #82, never{}). schemaVersion3, not 2.contextScopetook 2, andmaincarries"schemaVersion": 2
today, so Capability map cannot record array-body cardinality constraints (minItems/maxItems/uniqueItems) — needs schemaVersion 2 #83 increments from there. Recorded on Capability map cannot record array-body cardinality constraints (minItems/maxItems/uniqueItems) — needs schemaVersion 2 #83, which still says otherwise in its body.- The Capability map cannot record array-body cardinality constraints (minItems/maxItems/uniqueItems) — needs schemaVersion 2 #83 + Assert-PfbApiCapability cannot field-gate array bodies: the IDictionary guard outlives its premise once #82 lands #95 pairing. This issue's title and body list
#71, #82, #83, contextScopeand
never mention Assert-PfbApiCapability cannot field-gate array bodies: the IDictionary guard outlives its premise once #82 lands #95, so the pairing existed only in Assert-PfbApiCapability cannot field-gate array bodies: the IDictionary guard outlives its premise once #82 lands #95's own text. It is now recorded on both.
The remaining decision
One question, answered once for both halves: does the runtime consume what the map records, and
how — record only, warn, or throw? #95 gates per-element field versions, #83 gates per-element
cardinality; same function, same only-affected cmdlet (Set-PfbWorkloadTag), same nil blast
radius until #44 lands callers for the other three array-bodied endpoints.- The "nothing vanishes" invariant (
Tracking issue. No work of its own — it exists so the four pending changes to
Data/PfbCapabilityMap.jsonland in a coherent order instead of colliding.Why one issue
Four open changes converge on the same three things:
Add-PfbSchemaPropertyNodes/Get-PfbSchemaPropertyNamesintools/lib/PfbSpecTools.ps1Data/PfbCapabilityMap.json, which has a live runtimeconsumer in
Private/Assert-PfbApiCapability.ps1Tests/Build-PfbApiDriftReport.Tests.ps1Sequenced independently they mean four regenerations of the same file, four diffs to
review, and near-certain conflicts between the branches. Sequenced together they are two
PRs with two reviewable diffs.
The four changes
MaxDepth=8truncates deepallOfchains in fb2.12–2.16introducedVersionvalues move 2.17 → 2.16itemsbodyProperties(23 fields), plusreadOnlyBodyPropertiesminItems/maxItems/uniqueItemsbodyConstraintscontextScope, from thex-pure-*extensions plus a curated tableTwo are data corrections to existing fields; two need a new field.
The schema bump is cheaper than it sounds
Worth stating up front, because it drove the original grouping instinct and turns out not
to be the hard part:
Private/orPublic/readsschemaVersion. The runtime loader does notvalidate it.
Build-PfbCapabilityMap,Build-PfbApiDriftReport,Build-PfbFieldCmdletMap,Build-PfbValueEnumMap— each write their own independent1. The version is per-artifact, not global.So bumping to
2is a label. The cost is a few fixtures inTests/Get-PfbCapabilityMap.Tests.ps1, not a migration. The real coordination cost is theshared data-file diff and the invariant below.
The requirement none of the child issues carry
Tests/Build-PfbApiDriftReport.Tests.ps1asserts that every query parameter and bodyproperty the committed map lists, for an endpoint an existing cmdlet calls, lands in
exactly one of the drift report's
missingQueryParameters/missingBodyProperties/readOnlyFields, or the phantom-exclusion set.Any change that adds fields to the map must account for them there in the same commit or
that test goes red. #82 adds 23 fields and is the immediate case. This requirement appears
in none of the individual issues, which is exactly the kind of thing a tracking issue is
for.
Note this test is guarded on the presence of
tools/specs/, which is gitignored — itsilently skips in a fresh clone or worktree and only bites in CI. Do not read a green local
run as evidence.
What CI actually does
Correcting a plausible-sounding assumption: there is no byte-identical regeneration gate
on
Data/PfbCapabilityMap.json..github/workflows/update-api-capability-map.ymlregenerates all four artifacts weeklyand on
pushtomaintouchingPublic/**, then opens a PR ifData/Reportschanged. It does not fail on drift.
.github/workflows/cross-platform-tests.ymlruns the full suite on every push and PRacross four OS/edition combinations, which is where the invariant above is enforced.
Practical consequence: a hand-edit or an out-of-band regeneration will not be rejected — it
will quietly reappear as a conflicting auto-PR later. Regenerate via the tool, never by
hand.
Proposed sequencing
PR 1 — walker fixes, no schema change. #71 + #82.
Both are bugs in the same function with concrete, checkable expected diffs. They interact:
descending through
itemsconsumes a depth level, and #71's fix (an explicit-MaxDepth 32at the
Get-PfbSpecCapabilitiescall sites) supplies the headroom #82 needs. Landing #82alone risks re-truncating on the historical specs where
introducedVersionis determined.Ships with the drift-report accounting for the 23 new fields, and a synthetic fixture whose
body is an array of an
allOf-composed element schema.PR 2 —
schemaVersion 2. #83 + thecontextScopehalf of #25.Both add optional per-endpoint keys, absent where not applicable. One bump, one fixture
update, one diff.
contextScopeadditionally needs the generator to read thex-pure-*extensions and to carry the curated table at build time — see rev 3 §12 in #72 for that
design, which is the larger part of this PR.
Ordering matters: PR 2 rebuilds the map, so landing it on top of a not-yet-fixed walker
would bake the #71/#82 defects into a diff that also contains the schema change, making
both harder to review.
Downstream
#44 (batch-operation cmdlets for nodes, resource-accesses, workload-tags, fleet-members)
is scoped to exactly the four endpoints #82 makes visible. Until PR 1 lands, the drift
report shows zero addable body fields for all four, so it cannot inform the parameter design
of the cmdlets #44 proposes. #44 should wait on PR 1 rather than hand-transcribing the field
lists from the spec.
Explicit non-goals
MaxDepthsemantics or making the walk depth-unbounded. Capability map records 5 body fields with introducedVersion one release too late (MaxDepth=8 truncation in fb2.12-2.16) #71's explicit value issufficient; unbounded recursion over a spec with cyclic
$refis a different problem.maxLength,pattern, numeric bounds) on ordinary object bodies —see the out-of-scope note on Capability map cannot record array-body cardinality constraints (minItems/maxItems/uniqueItems) — needs schemaVersion 2 #83.
Reports/PfbValueEnumMap.jsonalready owns those.Reports/PfbApiDriftReport.json's own schema. Separate artifact, separateschemaVersion; see API drift report: systemicGaps/conventionStrength only aggregate over high-confidence endpoints, undercounting some field names #59 for the open work there.