Skip to content

Migrate to System.CommandLine 2.0 GA and update CLI dependencies - #183

Merged
GinoCanessa merged 75 commits into
mainfrom
dev
Aug 27, 2026
Merged

Migrate to System.CommandLine 2.0 GA and update CLI dependencies#183
GinoCanessa merged 75 commits into
mainfrom
dev

Conversation

@GinoCanessa

Copy link
Copy Markdown
Collaborator

This pull request significantly expands and clarifies the documentation for the dev-do skill, making execution rules, commit hygiene, and recovery procedures much more explicit. The changes enforce stricter controls around plan execution, commit practices, and repository cleanliness, while integrating repository-specific conventions and recovery logic. These updates are aimed at ensuring reproducibility, auditability, and alignment with repository policies.

Key changes include:

Execution Rules and Plan Lifecycle

  • The dev-do skill now enforces a strict plan execution lifecycle: it gates on the plan's top-level status, requires all owned paths to be declared and clean before edits, and mandates post-commit identity checks before marking a phase complete. Final verification is required before the plan can be considered done. ([[1]](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9L23-R25), [[2]](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9L66-R71), [[3]](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9L94-R139), [[4]](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9L126-R263))
  • The workflow section is rewritten to include detailed pre-flight checks, repository rule discovery (via AGENTS.md), and explicit handling of plan status transitions and yield conditions. ([[1]](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9L126-R263), [[2]](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9R273-R310))

Commit Hygiene and Evidence

  • Commits must follow conventions defined in AGENTS.md, with exactly one commit per phase, path-limited to the phase's owned files. Each commit is accompanied by pre- and post-commit evidence, and the Issue: #N trailer is added only when the plan binds an issue. ([.github/skills/dev-do/SKILL.mdR273-R310](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9R273-R310))
  • The documentation now strictly forbids pushing, PR creation, or history rewriting by dev-do—these are reserved for dev-pr-open. ([.github/skills/dev-do/SKILL.mdR273-R310](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9R273-R310))

Recovery and Iteration Mode

  • Recovery logic is clarified: before resuming after interruption or a blocked phase, the index must be clean, and only durable progress log entries with matching commit evidence are accepted for completion. Otherwise, the user is prompted for action rather than silently reconciling. ([.github/skills/dev-do/SKILL.mdL210-R347](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9L210-R347))

Plan and File Ownership

  • plan.md is now explicitly defined as a control file, never to be committed or staged, and is the only exception to owned-path cleanliness checks. All other paths must be declared under a phase's owned paths before edits. ([.github/skills/dev-do/SKILL.mdL94-R139](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9L94-R139))
  • The summary includes stricter rules for editing and tracking owned paths, and for updating progress logs with canonical forms. ([[1]](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9L94-R139), [[2]](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9L126-R263))

Miscellaneous and General Guidance

  • The documentation now references related skills (dev-request, dev-plan, dev-review, dev-issue, dev-pr-open) for a complete workflow, and adds a note in .github/copilot-instructions.md to never commit anything under /scratch. ([[1]](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-4d377a241b4f15ef1c5f2d19975167a6e43d5fe38d8e8c614f62fe1442c098e9L3-R3), [[2]](https://github.com/FHIR/fhir-codegen/pull/183/files#diff-227c2c26cb2ee0ce0f46a320fc48fbcbdf21801a57f59161b1d0861e8aad55f5R89-R90))

These changes together make the dev-do skill more robust, auditable, and aligned with best practices for automated and semi-automated code execution and review.

GinoCanessa and others added 30 commits April 24, 2026 15:18
Phase 1 of System.CommandLine 2.0 GA migration. Replace the obsolete
fully-qualified System.CommandLine.Parsing.ParseResult with the new
System.CommandLine.ParseResult location, and rename Option<T>.IsRequired
to its GA name Required. Build is not yet green; the remaining errors
are confined to M6/M7 Option<T> constructors and HasOption /
GetValueForOption call sites which Phase 2 addresses.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…S.CL 2.0 GA

Phase 2 of System.CommandLine 2.0 GA migration.

Constructor migration (M6/M7): every 'new System.CommandLine.Option<T>(...)'
call site (~135 across Configuration/Config*.cs and Language/**/*Options.cs)
now uses the GA shape -- a single name plus optional 'params string[]'
aliases, with the description hoisted into the object initializer as
'Description = ...'.

ConfigRoot helper rewrite (M4 + D1 shortcut): GetOpt<T>, GetOptArray<T>
and GetOptHash<T> no longer call the removed HasOption/GetValueForOption
APIs. Instead they use the GA 'parseResult.GetResult(option)' overload
plus OptionResult.GetValueOrDefault<object>(), gated on
OptionResult.Implicit so user-supplied CLI values still beat factory
defaults. The boxed object flows through the existing per-type coercion
switch unchanged. The Token branch is retained as a defensive fallback
even though OptionResult.GetValueOrDefault<object>() never returns a
Token in 2.0 GA.

Deviation: adopted the D1(b) reflection-free shortcut (ConfigurationOption
unchanged, no per-option lambdas) rather than D1(a) which would have
required introducing factory methods at every option construction site.
Documented in plan.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace beta4 Parser/CommandLineBuilder/UseDefaults/UseHelp/UseExceptionHandler chain with the GA shape: BuildCli now returns (RootCommand, ParserConfiguration, InvocationConfiguration). Help customization is wired via a new EnumAwareHelpAction : SynchronousCommandLineAction that prints per-enum option detail before delegating to the stock HelpAction (HelpBuilder is internal in 2.0 so per-symbol column customization is unavailable; emit the enum block as preamble). AddGlobalOption/AddOption/AddCommand/AddAlias swapped for opt.Recursive + Options/Subcommands/Aliases.Add. SetDefaultValue/SetDefaultValueFactory removed (D1(b)); runtime defaults remain handled in ConfigRoot.GetOpt.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace BuildParser/parser.Parse/InvokeAsync with the new BuildCli tuple plus rootCommand.Parse(args, parserConfig) and pr.InvokeAsync(invocationConfig). Wrap each invocation in an InvokeWithHandler helper that preserves the beta4 'Error: ...' + exit-1 UX previously provided by UseExceptionHandler. Replace removed SymbolResult.Symbol property access with a CommandResult pattern-match. Drop the unused System.CommandLine.NamingConventionBinder beta4 package reference. Remove leftover fhir-codegen.csproj.orig merge artifact.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Drop System.CommandLine.Builder using; replace CommandLineBuilder/UseDefaults bootstrap with ParserConfiguration + rootCommand.Parse(args, parserConfig); swap AddGlobalOption(co.CliOption) for co.CliOption.Recursive=true + rootCommand.Options.Add. All 6 ConfigTests pass under the D1(b) Implicit-vs-explicit gate.

Also fix the ExportKeys Option<HashSet<string>> ctor in ConfigRoot.cs that the Phase 2 mechanical regex skipped (nested-generic type confused the pattern), preventing the static initializer from throwing 'Names and aliases cannot contain whitespace'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add ConfigPrecedenceTests.cs covering the three reachable sources (default, env, cli) for representative int/string/bool options. The env cell uncovered that the env-var fallback in ConfigRoot.GetOpt/GetOptArray was unreachable under D1(b) (the Implicit early return short-circuited it). Refactored both helpers to consult Environment.GetEnvironmentVariable on the implicit branch via new GetEnvValueOrDefault/GetEnvValueArrayOrDefault helpers (with Convert.ChangeType + Enum.Parse + try/catch). 17/17 config tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The same Option<T> instance is added to root + every language subcommand by BuildCommand, so it shows up multiple times in _optsWithEnums and the enum help block was rendered repeatedly. Dedup by reference in the ctor. Filtered test suite passes 218/218; --help / generate --help / generate OpenApi --help all render the enum block exactly once per option.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Filter options by CLI alias string against the excluded type's option set
instead of building a dead inheritedPropNames set. Enables Phase 2/3 to
strip root/generate options out of language subcommand walks.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pass excludeFromType: typeof(ConfigGenerate) to BuildCliOptions for the
language subcommand so the language config does not re-emit root and
generate options. Reduces help-text duplication from 4x to 3x;
remaining redundancy lives in the explicit re-add removed in Phase 3.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Recursive=true on the root and generate options already propagates them
downward to leaf language subcommands; the explicit re-add caused each
generate option to render in --help output multiple times. Each option
now appears exactly once in the help block.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the EnumAwareHelpAction preamble with idempotent in-place
mutation of Option.Description in TrackIfEnum, appending an 'Allowed
values: ...' line and any per-value [Description] text. The standard
HelpAction now renders the allowed-values text in the description
column without a custom help action. Removes the unlabeled enum dump
that previously appeared above the standard --help layout.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
New test project src/fhir-codegen.Tests/ imports the shared projitems
to exercise LaunchUtils.BuildCommand / BuildCli / ParseConfig directly.
Pins:
* No duplicate option aliases reachable from root, generate, every
  generate <Language>, xver, or xver load.
* Language subcommands locally own only language-specific options
  (no overlap with ConfigRoot or ConfigGenerate).
* Parse round-trip populates root, generate, and language options
  regardless of where the inherited recursive options sit on the
  command line.
* Enum option Description is augmented with 'Allowed values: ...'
  exactly once across repeated BuildCommand invocations.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The main->dev merge at 3ed6717 reconciled the fhir-codegen.Tests
project header and ProjectConfigurationPlatforms block to main's GUID
{43486BFA-06AE-4AB8-BC83-AEF2C5BAA3B4} but left two trailing
references to dev's pre-merge GUID {02FCEADC-4A76-4269-9DF4-7E410063C434},
causing MSBuild to reject the solution at parse time with MSB5023.

- NestedProjects: delete the stale {02FCEADC...} entry. Line 162 already
  nests the test project under the src solution folder via the canonical
  GUID, so deletion (vs. GUID replacement) avoids a duplicate mapping.
- SharedMSBuildProjectFiles: replace {02fceadc...} with {43486bfa...}
  (lowercase, matching the section's existing casing) so the test
  project keeps its fhir-codegen-shared.projitems consumer record.

Verified: dotnet build fhir-codegen.sln -c Release no longer emits
MSB5023; the solution parses and projects begin restoring/building.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ConfigDocs.cs slipped through the merge from main without the matching
S.CL 2.0 GA updates the rest of Configuration/ already received. The
Parse override referenced System.CommandLine.Parsing.ParseResult (the
type was lifted to System.CommandLine in 2.0), the Option<string>
positional ctor passed a description string in the alias slot, and the
initializer used the renamed IsRequired property.

Bring the file in line with the sibling pattern in ConfigRoot.cs:
- Change Parse(...) parameter to System.CommandLine.ParseResult.
- Drop the description from the Option<string> positional ctor and
  set it via the Description initializer.
- Rename IsRequired = false to Required = false.

Restores the Release build to 0 Error(s).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add two regression Facts to LaunchUtilsParseTests covering the
'docs cli' subcommand:
- ParseConfig_DocsCli_PopulatesOutputPath asserts that
  '--output <path>' flows through LaunchUtils.BuildCli ->
  ConfigDocs.Parse -> ConfigDocs.OutputPath. Would have caught
  the prior CS0234 (suite would fail to build) and a silent
  regression where the override stops being invoked.
- ParseConfig_DocsCli_DefaultsOutputPathWhenOmitted asserts that
  OutputPath falls back to ConfigDocs.DefaultOutputPath when the
  user omits --output.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three LaunchUtilsParseTests passed the literal C:/tmp/cache to
--fhir-cache, which is rooted on Windows but not on macOS/Linux. On
non-Windows hosts ConfigRoot.Parse therefore treated it as relative,
walked up via FileSystemUtils.FindRelativeDir, and threw
DirectoryNotFoundException.

Make the test class IDisposable, allocate a per-instance rooted temp
directory under Path.GetTempPath()/fhir-codegen-tests/launch-utils-parse-<guid>
in the constructor, and remove it (best-effort) in Dispose. Replace
the three offending --fhir-cache literals and matching ShouldBe
assertions with that field. The two ParseConfig_DocsCli_* tests are
unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Phase 1 of System.CommandLine 2.0 GA migration. Replace the obsolete
fully-qualified System.CommandLine.Parsing.ParseResult with the new
System.CommandLine.ParseResult location, and rename Option<T>.IsRequired
to its GA name Required. Build is not yet green; the remaining errors
are confined to M6/M7 Option<T> constructors and HasOption /
GetValueForOption call sites which Phase 2 addresses.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…S.CL 2.0 GA

Phase 2 of System.CommandLine 2.0 GA migration.

Constructor migration (M6/M7): every 'new System.CommandLine.Option<T>(...)'
call site (~135 across Configuration/Config*.cs and Language/**/*Options.cs)
now uses the GA shape -- a single name plus optional 'params string[]'
aliases, with the description hoisted into the object initializer as
'Description = ...'.

ConfigRoot helper rewrite (M4 + D1 shortcut): GetOpt<T>, GetOptArray<T>
and GetOptHash<T> no longer call the removed HasOption/GetValueForOption
APIs. Instead they use the GA 'parseResult.GetResult(option)' overload
plus OptionResult.GetValueOrDefault<object>(), gated on
OptionResult.Implicit so user-supplied CLI values still beat factory
defaults. The boxed object flows through the existing per-type coercion
switch unchanged. The Token branch is retained as a defensive fallback
even though OptionResult.GetValueOrDefault<object>() never returns a
Token in 2.0 GA.

Deviation: adopted the D1(b) reflection-free shortcut (ConfigurationOption
unchanged, no per-option lambdas) rather than D1(a) which would have
required introducing factory methods at every option construction site.
Documented in plan.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace beta4 Parser/CommandLineBuilder/UseDefaults/UseHelp/UseExceptionHandler chain with the GA shape: BuildCli now returns (RootCommand, ParserConfiguration, InvocationConfiguration). Help customization is wired via a new EnumAwareHelpAction : SynchronousCommandLineAction that prints per-enum option detail before delegating to the stock HelpAction (HelpBuilder is internal in 2.0 so per-symbol column customization is unavailable; emit the enum block as preamble). AddGlobalOption/AddOption/AddCommand/AddAlias swapped for opt.Recursive + Options/Subcommands/Aliases.Add. SetDefaultValue/SetDefaultValueFactory removed (D1(b)); runtime defaults remain handled in ConfigRoot.GetOpt.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace BuildParser/parser.Parse/InvokeAsync with the new BuildCli tuple plus rootCommand.Parse(args, parserConfig) and pr.InvokeAsync(invocationConfig). Wrap each invocation in an InvokeWithHandler helper that preserves the beta4 'Error: ...' + exit-1 UX previously provided by UseExceptionHandler. Replace removed SymbolResult.Symbol property access with a CommandResult pattern-match. Drop the unused System.CommandLine.NamingConventionBinder beta4 package reference. Remove leftover fhir-codegen.csproj.orig merge artifact.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Drop System.CommandLine.Builder using; replace CommandLineBuilder/UseDefaults bootstrap with ParserConfiguration + rootCommand.Parse(args, parserConfig); swap AddGlobalOption(co.CliOption) for co.CliOption.Recursive=true + rootCommand.Options.Add. All 6 ConfigTests pass under the D1(b) Implicit-vs-explicit gate.

Also fix the ExportKeys Option<HashSet<string>> ctor in ConfigRoot.cs that the Phase 2 mechanical regex skipped (nested-generic type confused the pattern), preventing the static initializer from throwing 'Names and aliases cannot contain whitespace'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
GinoCanessa and others added 29 commits May 28, 2026 13:22
Replace the bare `No direct target type` text in the type lookup index with a linked `[{target} Extension](extensibility.html#Extension)` cell mirroring the resource-side Basic link. Update the per-detail prose accordingly; render the inline `Extension` token as a link so the page is self-contained even when the per-element extension pass produces no entries. Rename XVerUnmappedTypeLookupDoesNotLinkBasic to XVerUnmappedTypeLookupLinksExtension and add XVerTypeLookupIndexLinksExtensionForUnmapped.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…,types,vs}.md

Rename the three top-level cross-version index pages so they are visually distinct from the per-artifact lookup-sd-{id}.md / lookup-vs-{id}.md detail pages. Per-artifact filenames are unchanged. Updated all four IgExporter skipPages sets and the IG nav template; refreshed both test files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ith a suitable target but additional cardinality requirements.
Phase 1 of the cross-version documentation effort: lock the per-step
spec template, the AI Guess discipline, and the freshness footer by
creating seven empty skeleton specs in docs/specs/xver-*.md and an
appended seven-step narrative skeleton in docs/articles/cross-version.md
(fenced under an HTML comment; legacy DRAFT four-phase prose is
preserved here and will be swapped out wholesale in Phase 4 of the
plan). No prose content yet.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Phase 2 of the cross-version documentation effort.

* fhirdb-comparer-compare.md: replaced the obsolete
  Compare(artifactFilter, comparisonPairFilterSet, allowUpdates)
  signature with the current Compare(processValueSets, processStructures,
  maxStepSize, specificPairs); rewrote the algorithm and mermaid to
  reflect the drop/create-tables + delegate-to-ValueSetComparer/
  StructureComparer flow.

* fhirdb-comparer-do-structure.md, fhirdb-comparer-do-valueset.md:
  rewrote algorithms and diagrams to match the current cache+DB merge
  shape; added a prominent status banner noting that the entire
  FhirDbComparerStructures.cs / FhirDbComparerValueSets.cs (and the
  three sibling partial files) are currently wrapped in #if false and
  not compiled. Live equivalents live in StructureComparer.cs /
  ValueSetComparer.cs.

* xver-processor-write-fhir.md: wholesale rewrite. The old
  XVerProcessor.WriteFhirFromDatabase method has been removed; the
  equivalent entry point is now XVerExporter.Export, called by
  XVerProcessor.ExportOutcomes. Spec now describes XVerExporter.Export
  and its five component exporters (IgExporter, VocabularyFhirExporter,
  VocabularyPageExporter, StructureFhirExporter, StructurePageExporter).
  TOC entry renamed from XVerProcessor.WriteFhirFromDatabase to
  XVerExporter.Export in docs/specs/toc.yml.

All four files end with a freshness footer; none contain AI Guess
markers (Phase 2 specs are not allowed any).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Phase 3 batch 1: replace skeletons with deep-dive specs for the first
three load steps of the cross-version pipeline.

* xver-load-database.md: XVerProcessor.LoadDatabase. Surfaces the
  `_exclusionSet` / `_escapeValveCodes` constants, the R5
  `hl7.terminology@5.1.0` add-on, the existing-DB reuse rule, and the
  apparently-inverted `PackageIsFhirCore` check in
  loadDefinitionCollections (flagged AI Guess + TODO reviewer).

* xver-load-fhir-cross-version-maps.md: XVerProcessor.LoadFhirCrossVersionMaps
  and the loaders in CrossVersionSource/.

* xver-load-extension-substitutions.md: XVerProcessor.LoadExtensionSubstitutions
  and ComparisonDatabase.TryLoadExtensionSubstitutions. This is the
  decision-dense load step; substitutions encode SME judgment that
  overrides the algorithmic mapper downstream.

Also tightens the "Cross-Version Mapping Outcome Categories" section in
xver-processor-write-fhir.md: drops the inline table (which still
referenced the commented-out UseOneOfElements category) and defers
authoritatively to xver-generate-outcomes.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Phase 3 batch 2 (plus the export spec): replace the remaining skeletons
with deep-dive specs for the last four steps of the cross-version
pipeline.

* xver-load-fhir-type-valuesets.md: XVerProcessor.LoadFhirTypeValueSets
  and ComparisonDatabase.TryLoadFhirTypeValueSets. Surfaces the
  hand-curated FHIR-type ValueSet URL list and how
  ValueSetComparer.CompareValueSets consumes it.

* xver-compare-in-database.md: orchestration view of CompareInDatabase.
  Documents the artifact-filter -> (processValueSets, processStructures)
  dispatch, the destructive table-reset behavior of FhirDbComparer.Compare,
  the Up/Down traversal in the delegated comparers, and the apparently
  vestigial _directions constant.

* xver-generate-outcomes.md: the decision-dense classifier. Documents
  the OutcomeGenerator pipeline, the ValueSetOutcomeGenerator and
  StructureOutcomeGenerator stepped per-pair runs, and ElementOutcomeGenerator's
  classifier (extension-substitution precedence, ancestor extension reuse,
  Basic fallback, etc.). Surfaces the important finding that the
  Outcome*ActionCodes enums exist for documentation but are not directly
  assigned to row fields - categories are encoded via flags like
  RequiresXVerDefinition, IsRenamed, ExtensionSubstitutionKey, BasicElementId.

* xver-export-outcomes.md: orchestration view of ExportOutcomes.
  Documents the artifact-filter -> (processVocabulary, processStructures)
  dispatch, the includeIgScripts resolution chain, _crossDefinitionVersion
  layered precedence (config -> on-disk xver-package-config.json -> 0.1.0),
  _canonicalRootCrossVersion, the per-pair packaging model (no comprehensive
  packages), and the wip-subcommand scratchpad caveats. Defers to
  xver-processor-write-fhir.md for XVerExporter.Export internals.

All four files end with freshness footers; AI Guess markers are used
heavily in xver-generate-outcomes.md (decision-densest spec) per the
plan's expectation. DocFX build succeeds with only the pre-existing
cli.md warnings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Phase 4 of the cross-version documentation effort: replace the legacy
DRAFT four-phase prose in docs/articles/cross-version.md with the
authoritative seven-step narrative.

The page is now organized around the seven public entry points on
XVerProcessor (LoadDatabase, LoadFhirCrossVersionMaps,
LoadExtensionSubstitutions, LoadFhirTypeValueSets, CompareInDatabase,
GenerateOutcomes, ExportOutcomes) and includes:

* A high-level overview of what the pipeline produces, who consumes
  it, and the CLI entry point chain.
* A seven-step mermaid flow diagram.
* A subcommand -> step matrix covering every ProcessCommand branch
  (wip, update-vs-maps, load, load-base, load-maps, load-substitutions,
  compare, compare-vs, compare-sd, outcomes, outcomes-vs, outcomes-sd,
  export, default) using the locked cell vocabulary.
* One H2 summary per pipeline step, each linking to its deep-dive spec
  under docs/specs/xver-*.md.
* A glossary covering cross-version map, extension substitution,
  FHIR-type ValueSet, escape-valve code, _exclusionSet, comparison
  direction Up/Down, comparison pair, maxStepSize, specificPairs,
  Basic-path fallback, and inherited-from-ancestor extension.
* A freshness footer.

The DRAFT banner and the HTML comment fence used during Phase 1 are
gone; the legacy four-phase prose is removed wholesale. DocFX with
--warningsAsErrors succeeds with only the pre-existing cli.md
warnings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Phase 5 of the cross-version documentation effort: add the seven new
per-step deep-dive specs to docs/specs/toc.yml in pipeline order,
after the four existing entries (the existing entries were already
brought current in Phase 2 -- xver-processor-write-fhir.md was renamed
from XVerProcessor.WriteFhirFromDatabase to XVerExporter.Export in the
same Phase-2 commit).

The TOC now lists 11 entries total. DocFX --warningsAsErrors succeeds
with only the pre-existing cli.md warnings. Freshness footers are
present on all twelve touched docs (4 updated existing specs + 7 new
specs + the rewritten narrative). The placeholder SHA from Phase 1
remains accurate because no src/** files have been touched across the
entire effort.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Trim the cross-version docs to describe the current state of the
project only. Concretely:

* Delete docs/specs/fhirdb-comparer-do-structure.md and
  docs/specs/fhirdb-comparer-do-valueset.md. Both files described
  FhirDbComparerStructures.doStructureComparisons and
  FhirDbComparerValueSets.doValueSetComparisons, which are inside
  #if false ... #endif blocks (along with the rest of those partial
  files plus FhirDbComparerElements.cs,
  FhirDbComparerElementTypes.cs, and FhirDbComparerValueSetConcepts.cs)
  and are not compiled. The live per-family comparison code is in
  ValueSetComparer.cs and StructureComparer.cs and is already covered
  by fhirdb-comparer-compare.md.

* Rename docs/specs/xver-processor-write-fhir.md to
  docs/specs/xver-exporter-export.md and drop the top-of-file note
  about the old XVerProcessor.WriteFhirFromDatabase method. The
  filename was a stable-link compatibility artifact; the H1 and
  content have always described the current XVerExporter.Export.

* Update docs/specs/toc.yml to drop the two removed entries and
  rename the XVerExporter.Export href.

* Update docs/specs/fhirdb-comparer-compare.md, xver-compare-in-database.md,
  xver-generate-outcomes.md, xver-export-outcomes.md, and
  docs/articles/cross-version.md to remove references to the deleted
  specs, to the renamed spec's old filename, to the commented-out
  FhirMappingComparerVs lines, to the vestigial _directions constant,
  and to the commented-out UseOneOf / unassigned IsElementId /
  MappedElsewhere enum values.

* Update affected rationale tallies:
  - xver-compare-in-database.md: 7/4/3/0 -> 6/4/2/0
  - xver-generate-outcomes.md: 52/35/16/1 -> 49/35/14/0

docs/specs/toc.yml now lists 9 entries (1 existing kept + 1 renamed +
7 new from this effort). DocFX --warningsAsErrors succeeds with only
the pre-existing cli.md warnings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Re-derive ElementOutcomeGenerator.cs / DbOutcomeClasses.cs citations to
HEAD after the cross-version cardinality-extension rewrite, document the
new cardinality-only outcome category (RequiresCardinalityDefinition /
RequiresCardinalitySlice, CardinalityExtensionContexts, per-target
CardinalityContext* fields, GetCombinedContexts), correct the Rationale
Coverage tally to the actual rule count, and re-stamp the verified footer
to e36315a (2026-06-12).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a Cross-Version Cardinality Extensions section covering exportExtensions
cardinality pass, GetCombinedContexts-built context, the xvpc-* profile
constraint, the element ConceptMap second target, and StructurePageExporter
page content. Document Basic.code profiling and per-IG .gitignore seeding,
re-derive the StructureFhirExporter / StructurePageExporter / IgExporter
citations and line-count mentions to HEAD, and re-stamp the verified footer
to e36315a (2026-06-12).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add an Outputs pointer to the new cross-version cardinality-extension
category (data shape in generate-outcomes, emission in exporter-export) and
a one-line note that IgExporter seeds a per-IG .gitignore from the ig-support
directory. Re-verify the XVerProcessor / IgExporter citations (unchanged) and
re-stamp the verified footer to e36315a (2026-06-12).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@GinoCanessa
GinoCanessa merged commit b5f97c7 into main Aug 27, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant