Full-Lifecycle Documentation
"One
dotnet build. Five documentation domains. Unlimited cross-references. The Artifact Graph connects them all."
The Five Documentation Domains
With dev-side DSLs (Part II) and Ops DSLs (Parts IV–V), plus the Document DSL (Part III), one dotnet build generates documentation across five domains:
| Domain | Source DSLs | Generated Artifacts |
|---|---|---|
| Requirements | Requirements, Testing | Traceability matrix, AC coverage, gap analysis |
| Architecture | DDD | Entity diagrams, bounded context maps, event catalogs |
| API | API, Requirements | Endpoint docs, OpenAPI fragments, authorization matrix |
| Deployment | Ops.Deployment, Migration, Configuration, Resilience | Runbook, DAG, rollback playbook, env matrix |
| Observability | Ops.Observability | Grafana dashboard JSON, Prometheus alerts, K8s probes |
Each domain is documented by its own IDocumentStrategy<T>. DocumentSuite<T> composes them all for a single target.
Cross-Referencing via the Artifact Graph
The Artifact Graph (Part II) connects every DSL artifact to every other. The Document DSL uses these connections to generate cross-references — links between documents that update automatically when the graph changes.
// The graph knows:
// OrderProcessingFeature → implemented by → Order (aggregate)
// Order → exposed via → CreateOrderEndpoint (API)
// CreateOrderEndpoint → tested by → Order_can_be_created_with_valid_lines
// Order → deployed by → OrderServiceV24Deployment (migration steps)
// OrderServiceV24Deployment → observed by → VerifyPaymentEndpoint (health check)
// Generated cross-references in requirements.md:
// "See also: [Architecture](architecture.md) · [API](api.md) · [Deployment](deployment/runbook.md)"
// Generated cross-references in runbook.md:
// "This deployment covers: [OrderProcessingFeature](../requirements.md)"
// "Affected aggregates: [Order](../architecture.md)"// The graph knows:
// OrderProcessingFeature → implemented by → Order (aggregate)
// Order → exposed via → CreateOrderEndpoint (API)
// CreateOrderEndpoint → tested by → Order_can_be_created_with_valid_lines
// Order → deployed by → OrderServiceV24Deployment (migration steps)
// OrderServiceV24Deployment → observed by → VerifyPaymentEndpoint (health check)
// Generated cross-references in requirements.md:
// "See also: [Architecture](architecture.md) · [API](api.md) · [Deployment](deployment/runbook.md)"
// Generated cross-references in runbook.md:
// "This deployment covers: [OrderProcessingFeature](../requirements.md)"
// "Affected aggregates: [Order](../architecture.md)"Every document links to every related document. When an endpoint is added, the API doc updates AND the requirements doc's cross-reference section updates. When a health check is added, the runbook updates AND the observability doc updates.
DocumentSuite<Order> — The Complete Picture
[assembly: DocumentSuite<Order>(
Title = "Order Aggregate — Complete Documentation",
Formats = [DocumentFormat.Markdown, DocumentFormat.Json],
CrossReference = true)][assembly: DocumentSuite<Order>(
Title = "Order Aggregate — Complete Documentation",
Formats = [DocumentFormat.Markdown, DocumentFormat.Json],
CrossReference = true)]Generated output:
docs/Order/
├── index.md ← Cross-referenced hub
├── architecture.md ← Entity diagram, compositions, events
├── architecture.mermaid ← Mermaid class diagram
├── requirements.md ← Feature → AC → Test traceability
├── api.md ← Endpoints, auth matrix, request/response
├── tests.md ← Test coverage per AC, gaps highlighted
├── deployment/
│ ├── runbook.md ← Step-by-step deployment procedure
│ ├── dag.mermaid ← Execution DAG
│ ├── grafana-dashboard.json ← Import-ready Grafana dashboard
│ ├── prometheus-alerts.yaml ← Prometheus alert rules
│ ├── k8s-probes.yaml ← Kubernetes readiness/liveness
│ ├── helm-values.yaml ← Helm chart values
│ ├── rollback-playbook.md ← Ordered reverse procedure
│ └── env-matrix.md ← Config/secret per environment
├── Order.json ← Machine-readable: all data combined
└── cross-references.json ← All links for CI validationdocs/Order/
├── index.md ← Cross-referenced hub
├── architecture.md ← Entity diagram, compositions, events
├── architecture.mermaid ← Mermaid class diagram
├── requirements.md ← Feature → AC → Test traceability
├── api.md ← Endpoints, auth matrix, request/response
├── tests.md ← Test coverage per AC, gaps highlighted
├── deployment/
│ ├── runbook.md ← Step-by-step deployment procedure
│ ├── dag.mermaid ← Execution DAG
│ ├── grafana-dashboard.json ← Import-ready Grafana dashboard
│ ├── prometheus-alerts.yaml ← Prometheus alert rules
│ ├── k8s-probes.yaml ← Kubernetes readiness/liveness
│ ├── helm-values.yaml ← Helm chart values
│ ├── rollback-playbook.md ← Ordered reverse procedure
│ └── env-matrix.md ← Config/secret per environment
├── Order.json ← Machine-readable: all data combined
└── cross-references.json ← All links for CI validationThe Release Notes Generator
The Document DSL includes a release notes strategy that compares the current build to the previous tagged release:
[assembly: Document<Release<Order>>(
Format = DocumentFormat.Markdown,
OutputPath = "docs/releases")][assembly: Document<Release<Order>>(
Format = DocumentFormat.Markdown,
OutputPath = "docs/releases")]The ReleaseDocumentStrategy uses git diff between the current commit and the previous v* tag to find which typed artifacts changed:
[DocumentStrategy<ReleaseAttribute>(typeof(ReleaseDocumentStrategy))]
public sealed class ReleaseDocumentStrategy : IDocumentStrategy<ReleaseAttribute>
{
public DocumentOutput Generate(DslConceptInfo<ReleaseAttribute> concept, DocumentContext ctx)
{
var previousTag = ctx.Git.GetPreviousTag("v*");
var changedFiles = ctx.Git.GetChangedFilesSince(previousTag);
// Find which typed artifacts were modified
var changedFeatures = ctx.FindChangedArtifacts<FeatureBase>(changedFiles);
var changedAggregates = ctx.FindChangedArtifacts<AggregateRootAttribute>(changedFiles);
var changedEndpoints = ctx.FindChangedArtifacts<TypedEndpointAttribute>(changedFiles);
var changedDeployments = ctx.FindChangedArtifacts<DeploymentOrchestratorAttribute>(changedFiles);
var sb = new StringBuilder();
sb.AppendLine($"# Release Notes — {concept.AttributeProperties["Version"]}");
sb.AppendLine($"> Compared to: {previousTag}");
sb.AppendLine();
if (changedFeatures.Any())
{
sb.AppendLine("## Requirements Changes");
foreach (var f in changedFeatures)
sb.AppendLine($"- **{f.TypeName}** — {f.ChangeKind}: {f.Summary}");
}
if (changedEndpoints.Any())
{
sb.AppendLine("## API Changes");
foreach (var e in changedEndpoints)
sb.AppendLine($"- `{e.Method} {e.Route}` — {e.ChangeKind}");
}
if (changedDeployments.Any())
{
sb.AppendLine("## Deployment Changes");
foreach (var d in changedDeployments)
sb.AppendLine($"- {d.TypeName} — {d.StepCount} steps, {d.NewSteps} new");
}
return new DocumentOutput(
$"release-{concept.AttributeProperties["Version"]}.md",
sb.ToString(), DocumentFormat.Markdown, []);
}
}[DocumentStrategy<ReleaseAttribute>(typeof(ReleaseDocumentStrategy))]
public sealed class ReleaseDocumentStrategy : IDocumentStrategy<ReleaseAttribute>
{
public DocumentOutput Generate(DslConceptInfo<ReleaseAttribute> concept, DocumentContext ctx)
{
var previousTag = ctx.Git.GetPreviousTag("v*");
var changedFiles = ctx.Git.GetChangedFilesSince(previousTag);
// Find which typed artifacts were modified
var changedFeatures = ctx.FindChangedArtifacts<FeatureBase>(changedFiles);
var changedAggregates = ctx.FindChangedArtifacts<AggregateRootAttribute>(changedFiles);
var changedEndpoints = ctx.FindChangedArtifacts<TypedEndpointAttribute>(changedFiles);
var changedDeployments = ctx.FindChangedArtifacts<DeploymentOrchestratorAttribute>(changedFiles);
var sb = new StringBuilder();
sb.AppendLine($"# Release Notes — {concept.AttributeProperties["Version"]}");
sb.AppendLine($"> Compared to: {previousTag}");
sb.AppendLine();
if (changedFeatures.Any())
{
sb.AppendLine("## Requirements Changes");
foreach (var f in changedFeatures)
sb.AppendLine($"- **{f.TypeName}** — {f.ChangeKind}: {f.Summary}");
}
if (changedEndpoints.Any())
{
sb.AppendLine("## API Changes");
foreach (var e in changedEndpoints)
sb.AppendLine($"- `{e.Method} {e.Route}` — {e.ChangeKind}");
}
if (changedDeployments.Any())
{
sb.AppendLine("## Deployment Changes");
foreach (var d in changedDeployments)
sb.AppendLine($"- {d.TypeName} — {d.StepCount} steps, {d.NewSteps} new");
}
return new DocumentOutput(
$"release-{concept.AttributeProperties["Version"]}.md",
sb.ToString(), DocumentFormat.Markdown, []);
}
}Generated release notes:
# Release Notes — v2.4.0
> Compared to: v2.3.1
## Requirements Changes
- **OrderProcessingFeature** — Modified: added AC "Order can be marked as paid"
- **PaymentFeature** — New: 3 acceptance criteria
## API Changes
- `POST /api/orders/{id}/pay` — New endpoint (v2)
- `POST /api/orders` — Modified: added PaymentMethod field to request
## Deployment Changes
- OrderServiceV24Deployment — 7 steps, 4 new migration steps
- New health check: /health/payment on OrderApi
- New alert: OrderPaymentErrorSpike (critical)
## Test Coverage
- 3 new tests covering PaymentFeature
- AC "Paid order triggers fulfillment workflow" — still untested (gap)# Release Notes — v2.4.0
> Compared to: v2.3.1
## Requirements Changes
- **OrderProcessingFeature** — Modified: added AC "Order can be marked as paid"
- **PaymentFeature** — New: 3 acceptance criteria
## API Changes
- `POST /api/orders/{id}/pay` — New endpoint (v2)
- `POST /api/orders` — Modified: added PaymentMethod field to request
## Deployment Changes
- OrderServiceV24Deployment — 7 steps, 4 new migration steps
- New health check: /health/payment on OrderApi
- New alert: OrderPaymentErrorSpike (critical)
## Test Coverage
- 3 new tests covering PaymentFeature
- AC "Paid order triggers fulfillment workflow" — still untested (gap)The Pipeline — Build to Static Site
The documentation pipeline mirrors this website's own build:
dotnet build
│
├── SGs emit .g.cs (application code)
├── SGs emit docs/ (documentation)
│ ├── *.md (Markdown)
│ ├── *.mermaid (diagrams)
│ ├── *.json (Grafana, machine-readable)
│ └── *.yaml (Prometheus, K8s, Helm)
│
└── Analyzers validate
├── DDD001-DDD00N (DDD rules)
├── OPS001-OPS012 (Ops rules)
└── DOC001-DOC005 (Documentation completeness)
CI pipeline
│
├── dotnet build (generates everything)
├── Copy docs/ to static site
├── Import grafana-dashboard.json to Grafana
├── Copy prometheus-alerts.yaml to Prometheus rules
├── Apply k8s-probes.yaml to cluster
└── Publish helm-values.yaml to Helm chart repodotnet build
│
├── SGs emit .g.cs (application code)
├── SGs emit docs/ (documentation)
│ ├── *.md (Markdown)
│ ├── *.mermaid (diagrams)
│ ├── *.json (Grafana, machine-readable)
│ └── *.yaml (Prometheus, K8s, Helm)
│
└── Analyzers validate
├── DDD001-DDD00N (DDD rules)
├── OPS001-OPS012 (Ops rules)
└── DOC001-DOC005 (Documentation completeness)
CI pipeline
│
├── dotnet build (generates everything)
├── Copy docs/ to static site
├── Import grafana-dashboard.json to Grafana
├── Copy prometheus-alerts.yaml to Prometheus rules
├── Apply k8s-probes.yaml to cluster
└── Publish helm-values.yaml to Helm chart repoThe same build that compiles your application also generates its documentation and its infrastructure artifacts. One source of truth. One build. Zero drift.
The Self-Documenting System
Remember Document<Document<>> from Part III? In the full-lifecycle view, it generates not just the Document DSL's reference — it generates the complete documentation catalog:
# Documentation Catalog — Generated by Document<Document<>>
## All Generated Documents
| Target | Domain | Files | Last Changed |
|---|---|---|---|
| Order | Architecture | 2 files (md + mermaid) | 2026-03-28 |
| OrderProcessingFeature | Requirements | 1 file (md) | 2026-03-29 |
| CreateOrderEndpoint | API | 2 files (md + openapi) | 2026-03-29 |
| OrderServiceV24Deployment | Deployment | 8 files (md + yaml + json) | 2026-03-29 |
| v2.4.0 | Release Notes | 1 file (md) | 2026-03-29 |
## Coverage Summary
- **Features with full traceability**: 3/4 (75%)
- **Aggregates with architecture docs**: 2/2 (100%)
- **Endpoints with API docs**: 2/2 (100%)
- **Deployments with runbooks**: 1/1 (100%)
- **Orphaned artifacts (DOC001)**: 1 (PaymentGatewayClient)# Documentation Catalog — Generated by Document<Document<>>
## All Generated Documents
| Target | Domain | Files | Last Changed |
|---|---|---|---|
| Order | Architecture | 2 files (md + mermaid) | 2026-03-28 |
| OrderProcessingFeature | Requirements | 1 file (md) | 2026-03-29 |
| CreateOrderEndpoint | API | 2 files (md + openapi) | 2026-03-29 |
| OrderServiceV24Deployment | Deployment | 8 files (md + yaml + json) | 2026-03-29 |
| v2.4.0 | Release Notes | 1 file (md) | 2026-03-29 |
## Coverage Summary
- **Features with full traceability**: 3/4 (75%)
- **Aggregates with architecture docs**: 2/2 (100%)
- **Endpoints with API docs**: 2/2 (100%)
- **Deployments with runbooks**: 1/1 (100%)
- **Orphaned artifacts (DOC001)**: 1 (PaymentGatewayClient)What's Next
Part VIII walks through one feature end-to-end — from requirement definition to Grafana dashboard — with every generated artifact shown. One feature. 17 files. Zero manual documentation.