Problem
Included architecture artifacts currently break the assembled AsciiDoc heading hierarchy. The assembled architecture document should be the only level-0 document title. Whenever a source file is included at the same semantic level as the include macro, the include should use leveloffset=+1 so the included document becomes a child section.
Current ADR, quality scenario, and risk source artifacts start with level-0 headings, for example:
src/docs/arc42/09-architecture-decisions/adr-001-asciidoc-primary-source.adoc starts with = ADR-001: ....
src/docs/arc42/10-quality-requirements/qs-001-reproducible-generation.adoc starts with = QS-001: ....
src/docs/arc42/11-risks-and-technical-debt/r-001-ai-suggestions-as-truth.adoc starts with = R-001: ....
The generated chapter include fragments include those files without a level offset, for example:
include::../09-architecture-decisions/adr-001-asciidoc-primary-source.adoc[]
include::../10-quality-requirements/qs-001-reproducible-generation.adoc[]
include::../11-risks-and-technical-debt/r-001-ai-suggestions-as-truth.adoc[]
Rendered result: ADRs, QSs, and risks become top-level sibling chapters of arc42 Chapter 9/10/11 instead of child sections. A render smoke check showed examples such as:
ADR-001 rendered as chapter 10, after Architecture Decisions rendered as chapter 9.
QS-001 rendered as chapter 16, after Quality Requirements rendered as chapter 15.
R-001 rendered as chapter 22, after Risks And Technical Debt rendered as chapter 21.
Likely root cause
The missing rule is spread across templates, generator, tests, and instructions:
templates/adr.adoc, templates/quality-scenario.adoc, and templates/risk.adoc define standalone artifacts with = level-0 titles.
- The corresponding example templates are byte-identical and carry the same level-0 titles.
ChapterIncludeFragmentGenerator in scripts/validate-metamodel.rb emits include::#{target}[] for every detail artifact and does not compute or add leveloffset.
test/validate_metamodel_test.rb currently asserts the no-offset include output, so the test suite locks in the wrong behavior.
general-semantic-contracts.md, skills/adr/SKILL.md, skills/quality-scenario/SKILL.md, skills/risk/SKILL.md, and skills/bootstrap-project/SKILL.md say to use generated include fragments and templates, but do not explicitly state the AsciiDoc heading-level rule for included standalone artifacts.
Concrete changes to analyze and implement
-
Decide the canonical rule:
- Prefer keeping standalone ADR/QS/R files as standalone source artifacts with
= titles, because they can render independently.
- Generated chapter include fragments should include standalone detail artifacts with
leveloffset=+1 when their first heading is =.
- Existing source detail pages that already start with
== may not need an offset, but the generator should either detect the first heading level or apply a documented consistent policy.
-
Update ChapterIncludeFragmentGenerator:
- Detect each included artifact's first AsciiDoc section level after YAML front matter.
- Add
leveloffset=+1 when including a file whose first heading is at the same level as the including chapter context.
- Preserve deterministic sorting by artifact ID.
- Keep generated index fragments directly included in their chapter context where appropriate.
-
Update generated include fragments after generator changes:
src/docs/arc42/generated/doc-09000-architecture-decisions-includes.adoc should no longer let ADRs render as sibling chapters.
src/docs/arc42/generated/doc-10000-quality-requirements-includes.adoc should no longer let QS files render as sibling chapters.
src/docs/arc42/generated/doc-11000-risks-and-technical-debt-includes.adoc should no longer let risk files render as sibling chapters.
- Check all other generated chapter include fragments for the same heading-level issue.
-
Update tests:
- Change the existing chapter include fragment tests that currently assert
include::...[].
- Add a regression test with a generated include fragment containing one
= artifact and one == artifact, or otherwise codify the chosen policy.
- Add a render-oriented regression check if feasible: rendered arc42 output should not promote ADR/QS/R artifacts to top-level siblings of Chapter 9/10/11.
-
Update instructions and docs:
- Add the heading-level/include-offset rule to
general-semantic-contracts.md under Docs-as-Code / arc42 include rules.
- Add the same rule, or a pointer to it, in ADR/QS/R/bootstrap skills where they mention templates and generated include fragments.
- Update README generator documentation to state how generated include fragments handle section levels.
-
Decide whether templates should remain level-0:
- If standalone rendering is required, keep
= in templates/adr.adoc, templates/quality-scenario.adoc, and templates/risk.adoc and solve via generated leveloffset.
- If these artifacts are never meant to render standalone, change templates to
==. This would simplify includes but weakens standalone source artifact rendering. Current evidence points toward preserving standalone = and fixing includes.
Dogfood example findings
The example/ directory is no longer fully aligned with the current toolkit conventions:
example/scripts/validate-metamodel.rb is older than the root script and lacks ChapterIncludeFragmentGenerator entirely.
example/metamodel/*.yaml matches the root metamodel schemas.
example/templates/adr.adoc, example/templates/quality-scenario.adoc, and example/templates/risk.adoc match the root templates, including the level-0 heading issue.
example/src/docs/arc42/doc-09000-architecture-decisions.adoc, doc-10000-quality-requirements.adoc, and doc-11000-risks-and-technical-debt.adoc still manually list detail artifacts instead of using generated chapter include fragments.
example/src/docs/arc42/doc-01000-introduction-and-goals.adoc also manually includes detail documents.
- Example validation currently passes with no warnings, so the validator does not detect this drift.
- Rendering the example shows the same hierarchy issue: ADRs, QSs, and risks render as sibling chapters rather than children of their arc42 chapters.
Keeping consuming projects up to date
Add an explicit toolkit update story for repositories that copy skills, templates, scripts, metamodel schemas, and examples from this toolkit. Possible approach:
- Add a
toolkit-version metadata file or manifest in bootstrapped projects listing copied asset versions/checksums and source paths.
- Provide a small update/check command that compares local copied assets against the current toolkit release or
main.
- Treat copied toolkit assets as upstream-managed unless the consuming project records local overrides.
- Add documentation for update modes: report-only, apply non-conflicting updates, and open a PR with copied asset refreshes.
- Make the example a first-class dogfood fixture in CI so drift between root toolkit assets and
example/ is visible.
Acceptance criteria
- Assembled root arc42 output has only the main document as level 0, and ADR/QS/R artifacts render below their owning chapter.
- Generated chapter include fragments apply the chosen
leveloffset policy deterministically.
- Tests cover generated include level offsets and fail on the current behavior.
- README, semantic contract, and relevant skills document the include-level rule.
example/ uses the current generator behavior and no longer manually maintains chapter detail includes where generated fragments exist.
- Example scripts/templates/metamodel are either current or intentionally versioned as copied toolkit assets.
- Validation and render checks pass for both root docs and
example/.
Problem
Included architecture artifacts currently break the assembled AsciiDoc heading hierarchy. The assembled architecture document should be the only level-0 document title. Whenever a source file is included at the same semantic level as the include macro, the include should use
leveloffset=+1so the included document becomes a child section.Current ADR, quality scenario, and risk source artifacts start with level-0 headings, for example:
src/docs/arc42/09-architecture-decisions/adr-001-asciidoc-primary-source.adocstarts with= ADR-001: ....src/docs/arc42/10-quality-requirements/qs-001-reproducible-generation.adocstarts with= QS-001: ....src/docs/arc42/11-risks-and-technical-debt/r-001-ai-suggestions-as-truth.adocstarts with= R-001: ....The generated chapter include fragments include those files without a level offset, for example:
Rendered result: ADRs, QSs, and risks become top-level sibling chapters of arc42 Chapter 9/10/11 instead of child sections. A render smoke check showed examples such as:
ADR-001rendered as chapter10, afterArchitecture Decisionsrendered as chapter9.QS-001rendered as chapter16, afterQuality Requirementsrendered as chapter15.R-001rendered as chapter22, afterRisks And Technical Debtrendered as chapter21.Likely root cause
The missing rule is spread across templates, generator, tests, and instructions:
templates/adr.adoc,templates/quality-scenario.adoc, andtemplates/risk.adocdefine standalone artifacts with=level-0 titles.ChapterIncludeFragmentGeneratorinscripts/validate-metamodel.rbemitsinclude::#{target}[]for every detail artifact and does not compute or addleveloffset.test/validate_metamodel_test.rbcurrently asserts the no-offset include output, so the test suite locks in the wrong behavior.general-semantic-contracts.md,skills/adr/SKILL.md,skills/quality-scenario/SKILL.md,skills/risk/SKILL.md, andskills/bootstrap-project/SKILL.mdsay to use generated include fragments and templates, but do not explicitly state the AsciiDoc heading-level rule for included standalone artifacts.Concrete changes to analyze and implement
Decide the canonical rule:
=titles, because they can render independently.leveloffset=+1when their first heading is=.==may not need an offset, but the generator should either detect the first heading level or apply a documented consistent policy.Update
ChapterIncludeFragmentGenerator:leveloffset=+1when including a file whose first heading is at the same level as the including chapter context.Update generated include fragments after generator changes:
src/docs/arc42/generated/doc-09000-architecture-decisions-includes.adocshould no longer let ADRs render as sibling chapters.src/docs/arc42/generated/doc-10000-quality-requirements-includes.adocshould no longer let QS files render as sibling chapters.src/docs/arc42/generated/doc-11000-risks-and-technical-debt-includes.adocshould no longer let risk files render as sibling chapters.Update tests:
include::...[].=artifact and one==artifact, or otherwise codify the chosen policy.Update instructions and docs:
general-semantic-contracts.mdunder Docs-as-Code / arc42 include rules.Decide whether templates should remain level-0:
=intemplates/adr.adoc,templates/quality-scenario.adoc, andtemplates/risk.adocand solve via generatedleveloffset.==. This would simplify includes but weakens standalone source artifact rendering. Current evidence points toward preserving standalone=and fixing includes.Dogfood example findings
The
example/directory is no longer fully aligned with the current toolkit conventions:example/scripts/validate-metamodel.rbis older than the root script and lacksChapterIncludeFragmentGeneratorentirely.example/metamodel/*.yamlmatches the root metamodel schemas.example/templates/adr.adoc,example/templates/quality-scenario.adoc, andexample/templates/risk.adocmatch the root templates, including the level-0 heading issue.example/src/docs/arc42/doc-09000-architecture-decisions.adoc,doc-10000-quality-requirements.adoc, anddoc-11000-risks-and-technical-debt.adocstill manually list detail artifacts instead of using generated chapter include fragments.example/src/docs/arc42/doc-01000-introduction-and-goals.adocalso manually includes detail documents.Keeping consuming projects up to date
Add an explicit toolkit update story for repositories that copy skills, templates, scripts, metamodel schemas, and examples from this toolkit. Possible approach:
toolkit-versionmetadata file or manifest in bootstrapped projects listing copied asset versions/checksums and source paths.main.example/is visible.Acceptance criteria
leveloffsetpolicy deterministically.example/uses the current generator behavior and no longer manually maintains chapter detail includes where generated fragments exist.example/.