Skip to content

Extract Elastic.Documentation.Search.Contract as zero-dep library#3349

Closed
Mpdreamz wants to merge 14 commits into
mainfrom
refactor/organize-doc-namespaces
Closed

Extract Elastic.Documentation.Search.Contract as zero-dep library#3349
Mpdreamz wants to merge 14 commits into
mainfrom
refactor/organize-doc-namespaces

Conversation

@Mpdreamz
Copy link
Copy Markdown
Member

Why

website-search-data needs to depend on DocumentationDocument and the Elasticsearch mapping config to interoperate with docs-builder indices, but pulling in the full Elastic.Documentation assembly drags in YAML deserialization, AppliesTo parsing, link registries, and other heavyweight concerns. Without this extraction there is no safe, minimal target to depend on.

What

A new Elastic.Documentation.Search.Contract project contains DocumentationDocument, ParentDocument, IndexedProduct, DocumentationMappingConfig/LexicalConfig/SemanticConfig/DocumentationAnalysisFactory, and a new wire-format AppliesToEntry record. The project has zero ProjectReferences and a single NuGet dependency (Elastic.Mapping), so external consumers can reference it without inheriting anything from docs-builder itself.

Elastic.Documentation gains a ProjectReference to the contract, so every existing internal consumer (Markdown exporter, ApiExplorer, search service, Assembler, Mcp.Remote) gets the types transitively with no new project references on their end.

How

DocumentationDocument.Applies was previously typed as ApplicableTo? — a rich domain type from the AppliesTo subsystem — which would have pulled that subsystem into the contract. The property is now typed as IReadOnlyCollection<AppliesToEntry>?, where AppliesToEntry is a flat wire-format record matching the JSON shape that ApplicableToJsonConverter already produced. The conversion is centralized in ApplicableTo.ToAppliesTo(), ensuring the lifecycle/sub-type mapping lives in exactly one place. The indexed JSON shape in Elasticsearch is unchanged.

Mpdreamz and others added 13 commits May 18, 2026 12:01
Three projects (Api.Core, Api.Infrastructure, Api.App) collapsed into
Elastic.Documentation.Api. Mcp.Remote no longer references any Api.*
project — its only deps are ServiceDefaults, services/Search, and
services/Assembler.

Key moves:
- EuidSpanProcessor + EuidLogProcessor → ServiceDefaults (shared)
- AddEuidEnrichment helper added to ServiceDefaults
- Search gateway interfaces (IFullSearchGateway, INavigationSearchGateway,
  IChangesGateway) → services/Elastic.Documentation.Search
- McpToolSourceName constant inlined into Mcp.Remote

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…x-x64

Enables arm64 image builds to publish and copy the correct architecture
artifact rather than always using the amd64 binary.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…r key

- Register McpTools ActivitySource in Mcp.Remote TracerProvider so MCP
  spans are captured
- Use GetEntryAssembly() over GetCallingAssembly() for service.version so
  the host service's version is reported rather than ServiceDefaults
- OtlpProxyOptions now checks OTEL_EXPORTER_OTLP_ENDPOINT first then
  OTLP_PROXY_ENDPOINT as backward-compatible fallback, matching the
  documented priority order

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Removes the ports-and-adapters boilerplate that required three types
(interface + gateway impl + usecase orchestrator) for each feature.
Each feature now has a single interface and implementation:
- IFullSearchService / FullSearchService (was IGateway + Gateway + Usecase)
- INavigationSearchService / NavigationSearchService
- IChangesService / ChangesService
- IOtlpService / AdotOtlpService

IAskAiService/IAskAiMessageFeedbackService renamed from Gateway variants;
AddElasticDocsApiUsecases → AddElasticDocsApiServices throughout.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…oject

Create Elastic.Documentation.Tooling to hold infrastructure types (ExternalCommandExecutor,
GitCheckoutInformationFactory, Exporter, Paths, FileSystemFactory) that dragged YamlDotNet,
Proc, IniFileParser, and Nullean.Argh into the domain library. Move YAML converters
(SemVersionConverter, ApplicableToYamlConverter) into Elastic.Markdown where they are consumed.
Swap YamlMember/YamlSerializable attributes on AppliesTo types for JsonPropertyName equivalents
so the domain library no longer depends on YamlDotNet at all.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ions from Elastic.Documentation

IHostedService on IDiagnosticsCollector was vestigial — nothing registers a collector
as a hosted service; all callers use the public virtual StartAsync/StopAsync directly.
Replace the explicit IHostedService implementation with a private EnsureStarted helper
and add StartAsync/StopAsync directly to IDiagnosticsCollector. System.IO.Abstractions
is already pulled in transitively via Nullean.ScopedFileSystem so the direct reference
was redundant. Elastic.Documentation now has four direct packages: Elastic.Mapping,
Microsoft.Extensions.Logging, NetEscapades.EnumGenerators, Nullean.ScopedFileSystem.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Elastic.Documentation.Configuration now contains only YAML schema types
and deserializer wiring. Non-schema types are relocated: IEnvironmentVariables
and SymlinkValidator move to Elastic.Documentation (domain primitives);
CrossLinkEntry and DocSetRegistry move into the existing Builder/ sub-namespace;
the dead LenientStringListConverter is deleted.

Elastic.Documentation root namespace is pruned: ChangelogEntryType and
ChangelogEntrySubtype move to the existing ReleaseNotes/ sub-namespace;
SemVersion, VersionSpec, and VersionOrDate move to a new Versions/
sub-namespace; GlobalCliOptions moves to Elastic.Documentation.Tooling
(preserving the Elastic.Documentation namespace via pragma so consumers
need only a using-directive update, not a project-reference change).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…nfiguration

Centralizes all YAML file reading in Elastic.Documentation.Configuration.
The five serialization types (ChangelogConfigurationYaml, YamlLenientList,
YamlLenientListConverter, TypeEntryYamlConverter) and ChangelogConfigurationLoader
move from Elastic.Changelog into Configuration.Changelog/, registered in the
shared YamlStaticContext so the single-static-context-per-assembly constraint
is respected. Elastic.Changelog consumers drop the old using directives; no new
project references are needed since Changelog already references Configuration.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
GlobalCliOptions moved here in PR4 and carries the Argh doc-comment
shortnames/summaries that populate the CLI schema. Without
GenerateDocumentationFile=true those annotations are invisible to the
schema generator, making the schema diff fail in CI.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
website-search-data needs the DocumentationDocument shape and mapping config
without pulling in the full Elastic.Documentation assembly (YAML loading, AppliesTo
parsing, link registries, etc.). The new project has zero ProjectReferences and
a single NuGet dep (Elastic.Mapping), making it safe to take as a standalone dep.

DocumentationDocument.Applies changes from ApplicableTo? to
IReadOnlyCollection<AppliesToEntry>, eliminating the AppliesTo project dep from the
contract. ApplicableTo.ToAppliesTo() centralises the conversion so the wire-format
is defined in exactly one place.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@Mpdreamz Mpdreamz requested a review from a team as a code owner May 19, 2026 07:13
@Mpdreamz Mpdreamz added the chore label May 19, 2026
@Mpdreamz Mpdreamz requested a review from technige May 19, 2026 07:13
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@Mpdreamz
Copy link
Copy Markdown
Member Author

Reopening against correct base branch (refactor/organize-doc-namespaces)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant