@hawkeyexl/manni 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,77 @@
1
+ # Concept, derived from The Good Docs Project's `concept/template_concept.md`
2
+ # at release v1.6.0. The upstream Markdown is vendored at
3
+ # `test/lint/fixtures/tgdp/template_concept.md` and linted against this file, so the
4
+ # two cannot drift.
5
+ #
6
+ # Serves Diataxis's "explanation" as well as TGDP's "concept": they are the
7
+ # same shape under two names.
8
+ #
9
+ # Almost every heading in this doctype is optional - upstream marks all but
10
+ # "Use cases" with an `(Optional)` prefix - so this template mostly constrains
11
+ # *which* sections may appear and *in what order*, and says very little about
12
+ # what goes inside them. That is deliberate: a concept page is prose, and a
13
+ # minimum paragraph count per section would fail pages a reader would call
14
+ # correct.
15
+ #
16
+ # The `(\(Optional\) )?` alternative in each pattern is what lets upstream's own
17
+ # file lint clean: it ships the authoring marker in the literal heading text,
18
+ # where a real page writes just the section name.
19
+ #
20
+ # v2: the page's own body - the summary and the definition that follows it,
21
+ # which upstream deliberately leaves without a heading of its own - is the
22
+ # template's own `contains:` rather than a `title` section's. A concept page
23
+ # explains something, and explanations grow sections the published template
24
+ # never named; the trailing `min: 0` rule is what lets those through.
25
+ info:
26
+ title: Concept (The Good Docs Project)
27
+ version: "1.6.0"
28
+ source: https://gitlab.com/tgdp/templates/-/blob/v1.6.0/concept/template_concept.md
29
+
30
+ templates:
31
+ concept:
32
+ types:
33
+ - concept
34
+ - explanation
35
+ description: >-
36
+ The page title, whatever the author calls the concept. Its body is the
37
+ summary that introduces the concept and the definition that follows -
38
+ upstream notes the definition deliberately carries no heading of its
39
+ own, so it is checked here rather than in a section.
40
+ contains:
41
+ paragraphs:
42
+ min: 1
43
+ sections:
44
+ - id: background
45
+ description: Context, prehistory, or background for the concept.
46
+ heading:
47
+ pattern: '^(\(Optional\) )?Background$'
48
+ min: 0
49
+ max: 1
50
+ - id: use-cases
51
+ description: >-
52
+ How a reader benefits from the concept. The one section upstream
53
+ does not mark optional.
54
+ heading: Use cases
55
+ max: 1
56
+ - id: comparison
57
+ description: >-
58
+ A comparison of the options or alternatives the concept sits
59
+ among. Upstream titles it `Comparison of {thing being compared}`,
60
+ so only the literal prefix is anchored.
61
+ heading:
62
+ pattern: '^(\(Optional\) )?Comparison( of .+)?$'
63
+ min: 0
64
+ max: 1
65
+ - id: related-resources
66
+ description: >-
67
+ Links out to related documentation. Upstream recommends "Related
68
+ concepts" or "Additional information" as more descriptive names,
69
+ so all three are accepted.
70
+ heading:
71
+ pattern: '^(\(Optional\) )?(Related resources|Related concepts|Additional information)$'
72
+ min: 0
73
+ max: 1
74
+ # A concept page explains something, and explanations grow sections the
75
+ # published template never named. The four above are the ones TGDP
76
+ # names; anything else the author needs is allowed through.
77
+ - min: 0
@@ -0,0 +1,64 @@
1
+ # Derived from The Good Docs Project "how-to" template, pinned to v1.6.0:
2
+ # https://gitlab.com/tgdp/templates/-/blob/v1.6.0/how-to/template_how-to.md
3
+ #
4
+ # The upstream Markdown is vendored at test/lint/fixtures/tgdp/template_how-to.md and
5
+ # linted against this file, so the two cannot drift. Where they disagree,
6
+ # upstream is right.
7
+ #
8
+ # v2: the template *is* the page (proposal 0061's grammar). Upstream's `# Title`
9
+ # is a placeholder, so what used to be a `title` section wrapping everything is
10
+ # now the template's own `sections:` directly - there is nothing to say about
11
+ # the H1's heading text or its own content.
12
+ info:
13
+ title: How-to guide (The Good Docs Project)
14
+ version: "1.6.0"
15
+ source: https://gitlab.com/tgdp/templates/-/blob/v1.6.0/how-to/template_how-to.md
16
+
17
+ templates:
18
+ how-to:
19
+ types:
20
+ - how-to
21
+ sections:
22
+ - id: overview
23
+ description: >-
24
+ What the guide explains, and optionally when and why a reader
25
+ would want to do it. A how-to that does not say what task it
26
+ covers is not a how-to, so at least one paragraph is required.
27
+ heading: Overview
28
+ max: 1
29
+ contains:
30
+ paragraphs:
31
+ min: 1
32
+ - id: before-you-start
33
+ description: >-
34
+ Prerequisites. Upstream marks this "{This section is optional}",
35
+ and the authoring guide repeats that, so it is not required.
36
+ Its shape varies too much to constrain - a lead-in and a bullet
37
+ list in the template, but prose or grouped categories in the
38
+ guide's own examples - so no content counts are set.
39
+ heading: Before you start
40
+ min: 0
41
+ max: 1
42
+ - id: task
43
+ description: >-
44
+ The steps. Upstream's heading is the placeholder "{Task name}",
45
+ so this is a slot; leaving `max` unbounded lets a page carry
46
+ several task sections, which the guide explicitly contemplates
47
+ ("you may break down the task into multiple logical sub-tasks").
48
+ No `lists` floor: a task that delegates its procedure to
49
+ sub-tasks legitimately holds no ordered list of its own.
50
+ sections:
51
+ - id: sub-task
52
+ description: >-
53
+ "### {Sub-task}" - another placeholder heading, and upstream
54
+ says to "include a sub-task only if the task is big and
55
+ complex", so it is optional and may occur more than once.
56
+ min: 0
57
+ - id: see-also
58
+ description: >-
59
+ Related reading. Upstream includes it unconditionally and does not
60
+ mark it optional the way it marks "Before you start", so it is
61
+ required. Its body is a mix of prose and links, so nothing is
62
+ counted.
63
+ heading: See also
64
+ max: 1
@@ -0,0 +1,57 @@
1
+ {
2
+ "$comment": "Built-in doctype templates derived from The Good Docs Project templates, pinned to release v1.6.0 (\"Iron\"): https://gitlab.com/tgdp/templates/-/tree/v1.6.0. Each entry's `file` is a YAML template beside this manifest; `source` is the upstream Markdown it was derived from, vendored under test/lint/fixtures/tgdp/ and linted against the derived template so the two cannot drift. Run `npm run check:tgdp-pin` to see whether upstream has moved past the pin.",
3
+ "vendor": "tgdp",
4
+ "upstream": "https://gitlab.com/tgdp/templates",
5
+ "pin": "v1.6.0",
6
+ "templates": [
7
+ {
8
+ "id": "tgdp:how-to:1.6",
9
+ "file": "tgdp/how-to.yaml",
10
+ "title": "How-to guide (The Good Docs Project)",
11
+ "types": ["how-to"],
12
+ "source": "how-to/template_how-to.md"
13
+ },
14
+ {
15
+ "id": "tgdp:tutorial:1.6",
16
+ "file": "tgdp/tutorial.yaml",
17
+ "title": "Tutorial (The Good Docs Project)",
18
+ "types": ["tutorial"],
19
+ "source": "tutorial/template_tutorial.md"
20
+ },
21
+ {
22
+ "id": "tgdp:reference:1.6",
23
+ "file": "tgdp/reference.yaml",
24
+ "title": "Reference (The Good Docs Project)",
25
+ "types": ["reference"],
26
+ "source": "reference/template_reference.md"
27
+ },
28
+ {
29
+ "id": "tgdp:concept:1.6",
30
+ "file": "tgdp/concept.yaml",
31
+ "title": "Concept (The Good Docs Project)",
32
+ "types": ["concept", "explanation"],
33
+ "source": "concept/template_concept.md"
34
+ },
35
+ {
36
+ "id": "tgdp:troubleshooting:1.6",
37
+ "file": "tgdp/troubleshooting.yaml",
38
+ "title": "Troubleshooting (The Good Docs Project)",
39
+ "types": ["troubleshooting"],
40
+ "source": "troubleshooting/template_troubleshooting.md"
41
+ },
42
+ {
43
+ "id": "tgdp:release-notes:1.6",
44
+ "file": "tgdp/release-notes.yaml",
45
+ "title": "Release notes (The Good Docs Project)",
46
+ "types": ["release-notes"],
47
+ "source": "release-notes/template_release-notes.md"
48
+ },
49
+ {
50
+ "id": "tgdp:readme:1.6",
51
+ "file": "tgdp/readme.yaml",
52
+ "title": "README (The Good Docs Project)",
53
+ "types": ["readme"],
54
+ "source": "readme/template_readme.md"
55
+ }
56
+ ]
57
+ }
@@ -0,0 +1,163 @@
1
+ info:
2
+ title: README (The Good Docs Project)
3
+ vendor: tgdp
4
+ pin: v1.6.0
5
+ source: https://gitlab.com/tgdp/templates/-/blob/v1.6.0/readme/template_readme.md
6
+
7
+ # Derived from The Good Docs Project's README template. Almost every heading
8
+ # upstream interpolates a project name, so this file leans on two devices:
9
+ #
10
+ # * A heading that is *entirely* a placeholder (`## {Project Name}`) becomes a
11
+ # slot - a rule with no `heading` key - because there is no literal text to
12
+ # anchor on.
13
+ # * A heading that wraps a placeholder in stable words (`### Install {Project
14
+ # Name}`, `## Instructions for using {Project Name}`) gets a `pattern`
15
+ # anchored on those words. Patterns keep neighbouring sections tellable
16
+ # apart, which a run of adjacent slots cannot do.
17
+ #
18
+ # Only the project title is required. Upstream marks the logo and table of
19
+ # contents optional outright, and treats the rest as boilerplate a project
20
+ # customises or deletes; real READMEs routinely name the same content
21
+ # differently or leave it out. So the teeth here are section *order*, the shape
22
+ # of the instructions subsections, and content minimums that bite only once a
23
+ # section is actually present.
24
+ #
25
+ # v2: the template *is* the page, so what used to be a `title` section wrapping
26
+ # everything - itself nested under a v1 root that also carried its own
27
+ # `additionalSections: true` - collapses into one level, the template's own
28
+ # `sections:`. The root's own `additionalSections` governed siblings of the H1,
29
+ # which a single page never has, so v2 has nothing to say in its place; the
30
+ # `title` rule's `additionalSections: true` is what survives, as the trailing
31
+ # `min: 0` rule at the end of this list.
32
+ templates:
33
+ readme:
34
+ types:
35
+ - readme
36
+ sections:
37
+ - id: logo-and-badges
38
+ description: >-
39
+ `## {Project} logo and badges`. Explicitly optional upstream.
40
+ Anchored on the words either side of the placeholder rather than
41
+ left as a slot, so it cannot swallow whatever section happens to
42
+ come first.
43
+ min: 0
44
+ max: 1
45
+ heading:
46
+ pattern: "\\b[Ll]ogos?\\b|\\b[Bb]adges?\\b"
47
+ - id: project-name
48
+ description: >-
49
+ `## {Project Name}` - the heading is nothing but a placeholder,
50
+ so this is a slot. One section, never a run.
51
+ min: 0
52
+ max: 1
53
+ sections:
54
+ - min: 0
55
+ - id: table-of-contents
56
+ description: >-
57
+ Explicitly optional upstream. A table of contents that holds no
58
+ list is not one, hence the list minimum.
59
+ min: 0
60
+ max: 1
61
+ heading: Table of contents
62
+ contains:
63
+ lists:
64
+ min: 1
65
+ - id: project-description
66
+ description: What the project is and what it lets you do.
67
+ min: 0
68
+ max: 1
69
+ heading: Project description
70
+ contains:
71
+ paragraphs:
72
+ min: 1
73
+ sections:
74
+ - min: 0
75
+ - id: who-this-project-is-for
76
+ description: The intended audience and their objective.
77
+ min: 0
78
+ max: 1
79
+ heading: Who this project is for
80
+ contains:
81
+ paragraphs:
82
+ min: 1
83
+ - id: project-dependencies
84
+ description: >-
85
+ Prerequisites. No list minimum: upstream's own troubleshooting
86
+ content shows these sections are as often tables, which the
87
+ parser does not count as lists.
88
+ min: 0
89
+ max: 1
90
+ heading: Project dependencies
91
+ - id: instructions-for-use
92
+ description: >-
93
+ `## Instructions for using {Project Name}`, anchored on the
94
+ literal opening words. Its subsections are the install/configure/
95
+ run/troubleshoot procedure, each of which is itself optional and
96
+ itself heading-anchored.
97
+ min: 0
98
+ max: 1
99
+ heading:
100
+ pattern: "^Instructions\\b"
101
+ sections:
102
+ - id: install
103
+ description: "`### Install {Project Name}`."
104
+ min: 0
105
+ max: 1
106
+ heading:
107
+ pattern: "^Install"
108
+ sections:
109
+ - min: 0
110
+ - id: configure
111
+ description: "`### Configure {Project Name}`."
112
+ min: 0
113
+ max: 1
114
+ heading:
115
+ pattern: "^Configur"
116
+ sections:
117
+ - min: 0
118
+ - id: run
119
+ description: "`### Run {Project Name}`."
120
+ min: 0
121
+ max: 1
122
+ heading:
123
+ pattern: "^Run(ning)?\\b"
124
+ sections:
125
+ - min: 0
126
+ - id: troubleshoot
127
+ description: "`### Troubleshoot {Project Name}`."
128
+ min: 0
129
+ max: 1
130
+ heading:
131
+ pattern: "^Troubleshoot"
132
+ sections:
133
+ - min: 0
134
+ - min: 0
135
+ - id: contributing-guidelines
136
+ description: How to contribute, or a link to the contributing guide.
137
+ min: 0
138
+ max: 1
139
+ heading: Contributing guidelines
140
+ contains:
141
+ paragraphs:
142
+ min: 1
143
+ - id: additional-documentation
144
+ description: Links to further reading.
145
+ min: 0
146
+ max: 1
147
+ heading: Additional documentation
148
+ - id: how-to-get-help
149
+ description: Support resources.
150
+ min: 0
151
+ max: 1
152
+ heading: How to get help
153
+ - id: terms-of-use
154
+ description: The licence the project is published under.
155
+ min: 0
156
+ max: 1
157
+ heading: Terms of use
158
+ contains:
159
+ paragraphs:
160
+ min: 1
161
+ # Tolerate a document that carries more than one top-level heading
162
+ # beyond the ones named above.
163
+ - min: 0
@@ -0,0 +1,67 @@
1
+ # Reference, derived from The Good Docs Project's `reference/template_reference.md`
2
+ # at release v1.6.0. The upstream Markdown is vendored at
3
+ # `test/lint/fixtures/tgdp/template_reference.md` and linted against this file, so the
4
+ # two cannot drift.
5
+ #
6
+ # v2: upstream ships the H1 as `# Reference template`, but a real reference
7
+ # names its own subject, so there is nothing to say about the page's own
8
+ # heading. No paragraph minimum either: the published template carries only
9
+ # block quotes under the H1, and a reference that opens straight into its
10
+ # first entry section is well formed.
11
+ info:
12
+ title: Reference (The Good Docs Project)
13
+ version: "1.6"
14
+ source: https://gitlab.com/tgdp/templates/-/blob/v1.6.0/reference/template_reference.md
15
+
16
+ templates:
17
+ reference:
18
+ types:
19
+ - reference
20
+
21
+ sections:
22
+ - id: reference-description
23
+ description: >-
24
+ `## {Reference description}` - a placeholder heading, so a slot.
25
+ Summarizes what the reference covers and how it relates to the
26
+ rest of the doc set. Required: the guide makes this the section
27
+ that "concisely summarizes the reference article's content and
28
+ purpose".
29
+ max: 1
30
+
31
+ - id: structured-entry
32
+ description: >-
33
+ `## {Table name or other structured entry}` - a placeholder
34
+ heading standing for a repeated section, so a slot with an
35
+ unbounded `max`. Claims every consecutive section up to
36
+ `commands`. Optional because it and `reference-description` are
37
+ both unconstrained placeholders: the matcher cannot tell "the
38
+ description" from "the first entry", so requiring both would
39
+ mandate two H2s where the doctype only asks that entries exist.
40
+ The node model can name a table directly (proposal 0065), so this
41
+ asks for one. Every parser reports tables now, so the rule runs and
42
+ upstream's own table satisfies it. Against a format that cannot
43
+ report them the rule is pruned and reported as an
44
+ `unsupported_content_kind` warning, rather than silently passing or
45
+ failing a page for a shape that format cannot show.
46
+ min: 0
47
+ contains:
48
+ tables:
49
+ min: 1
50
+
51
+ - id: commands
52
+ description: >-
53
+ `## (Optional) Commands`. The guide calls this "this optional
54
+ section" outright. The pattern accepts the heading with the
55
+ `(Optional)` marker still attached, as upstream ships it, and
56
+ with the marker removed, as an author who keeps the section would
57
+ write it. A section named anything else - "CLI commands",
58
+ "Command reference" - simply falls to the entry slot above.
59
+ min: 0
60
+ max: 1
61
+ heading:
62
+ pattern: '^(?:\(Optional\)\s+)?Commands$'
63
+
64
+ # Reference pages routinely end with sections the doctype does not
65
+ # enumerate - "See also", "Related information", "Notes". The upstream
66
+ # template does not forbid them, so they are not findings.
67
+ - min: 0
@@ -0,0 +1,108 @@
1
+ # Release notes, derived from The Good Docs Project's published template at
2
+ # v1.6.0 ("Iron"):
3
+ # https://gitlab.com/tgdp/templates/-/blob/v1.6.0/release-notes/template_release-notes.md
4
+ #
5
+ # Almost everything here is optional, on purpose. A release notes page is a
6
+ # report on one release, and no release has every kind of change in it: a
7
+ # maintenance release with three bug fixes and nothing else is a correct
8
+ # release notes page, and a template that demanded "New features" would be
9
+ # wrong about it. What the doctype genuinely mandates is the title. What this
10
+ # template is *for* is asserting that the sections which do appear carry
11
+ # upstream's names and appear in upstream's order - so `## Bug Fixes`,
12
+ # `## Fixes`, or a "Bug fixes" section placed above "New features" is reported,
13
+ # while a page that simply omits four of the six categories is not.
14
+ #
15
+ # That assertion is why the template itself carries no trailing wildcard rule:
16
+ # an unrecognised H2 has to be reported for the naming check to have any force.
17
+ # Inside a category the opposite holds - upstream prescribes the category
18
+ # headings, not how a category is subdivided - so each one ends with a
19
+ # trailing `min: 0` rule that lets any subsection through.
20
+ #
21
+ # There are no paragraph, list, or code-block minimums anywhere. Upstream marks
22
+ # only the release date as non-optional prose, and a category whose body is a
23
+ # single bullet list, a table, or a paragraph are all ordinary shapes for this
24
+ # doctype; counting blocks would fail correct pages without catching a real
25
+ # structural mistake.
26
+ info:
27
+ title: Release notes (The Good Docs Project)
28
+ version: "1.6.0"
29
+ source: https://gitlab.com/tgdp/templates/-/blob/v1.6.0/release-notes/template_release-notes.md
30
+
31
+ templates:
32
+ release-notes:
33
+ types:
34
+ - release-notes
35
+ description: >-
36
+ The page itself. Upstream titles it
37
+ `Release notes - {Product name} {Release number}`; only the braced
38
+ parts are placeholders, so the literal prefix is the one thing this
39
+ template insists on. Its body carries the release version, the
40
+ release date, and an optional high-level summary.
41
+ heading:
42
+ pattern: '^Release [Nn]otes\b'
43
+ sections:
44
+ - id: new-features
45
+ description: Functionality this release adds. Omitted by a release that adds none.
46
+ heading: New features
47
+ min: 0
48
+ max: 1
49
+ sections:
50
+ - min: 0
51
+
52
+ - id: new-features-requiring-configuration-updates
53
+ description: >-
54
+ New functionality that does not switch itself on. Separated from
55
+ `New features` upstream because these entries are action items
56
+ for the reader, not announcements.
57
+ heading: New features requiring configuration updates
58
+ min: 0
59
+ max: 1
60
+ sections:
61
+ - min: 0
62
+
63
+ - id: improvements
64
+ description: Changes to functionality that already existed - speed, usability, behaviour.
65
+ heading: Improvements
66
+ min: 0
67
+ max: 1
68
+ sections:
69
+ - min: 0
70
+
71
+ - id: api-web-service-updates
72
+ description: Changes to programmatic interfaces, which have a different audience from the rest of the page.
73
+ heading: API/Web service updates
74
+ min: 0
75
+ max: 1
76
+ sections:
77
+ - min: 0
78
+
79
+ - id: bug-fixes
80
+ description: Defects resolved in this release.
81
+ heading: Bug fixes
82
+ min: 0
83
+ max: 1
84
+ sections:
85
+ - id: known-issues
86
+ description: >-
87
+ Defects that are known and *not* resolved. Upstream nests this
88
+ under `Bug fixes` rather than making it a category of its own,
89
+ which puts what is still broken next to what was fixed.
90
+ heading: Known issues
91
+ min: 0
92
+ max: 1
93
+ sections:
94
+ - min: 0
95
+ - min: 0
96
+
97
+ - id: deprecation-notice
98
+ description: >-
99
+ Functionality being retired, with the date it stops being
100
+ supported and what replaces it. Upstream writes the heading as
101
+ `Optional: Deprecation notice`, so the pattern accepts the
102
+ published form as well as the one a real page would use.
103
+ heading:
104
+ pattern: '^(Optional: )?Deprecation notice$'
105
+ min: 0
106
+ max: 1
107
+ sections:
108
+ - min: 0
@@ -0,0 +1,98 @@
1
+ # Troubleshooting, derived from The Good Docs Project's troubleshooting
2
+ # template at release v1.6.0 ("Iron"):
3
+ #
4
+ # https://gitlab.com/tgdp/templates/-/blob/v1.6.0/troubleshooting/template_troubleshooting.md
5
+ #
6
+ # The upstream file is vendored at test/lint/fixtures/tgdp/template_troubleshooting.md
7
+ # and linted against this template, so the two cannot drift.
8
+ #
9
+ # The doctype is a list of symptoms, each explained by one or more causes and
10
+ # the solution or workaround for each. Upstream numbers every heading -
11
+ # `## Symptom 1`, `### Cause 2 of symptom 1` - but the numbering is
12
+ # illustrative, so the patterns here anchor on the leading word only: a page
13
+ # with one symptom, a page with five, and a page whose headings read
14
+ # `Symptom: disk full` or `Workaround` all pass. An unbounded `max` on an
15
+ # anchored rule claims the whole run of consecutive sections whose headings
16
+ # satisfy it, which is what lets the heading text be checked and repeated at
17
+ # once.
18
+ #
19
+ # v1 could not repeat a *pair* of rules, so it fell back to one rule matching
20
+ # either word ("Cause" or "Solution"), losing the doctype's actual order. v2's
21
+ # `repeat:` groups sibling rules into one repeated unit, which is exactly what
22
+ # the alternation is: each unit is one required Cause followed by one optional
23
+ # Solution or Workaround - optional because upstream's own file has a cause
24
+ # with no heading solution beneath it (the second solution in "Symptom 1" is
25
+ # unheaded prose, not a subsection). The unit itself repeats without limit, so
26
+ # a symptom may carry as many cause/solution pairs as it needs.
27
+ info:
28
+ title: Troubleshooting (The Good Docs Project)
29
+ version: "1.6.0"
30
+ source: https://gitlab.com/tgdp/templates/-/blob/v1.6.0/troubleshooting/template_troubleshooting.md
31
+
32
+ templates:
33
+ troubleshooting:
34
+ types:
35
+ - troubleshooting
36
+ description: >-
37
+ The page itself (H1). Upstream titles it
38
+ `# Troubleshooting {product name, feature, or task}`, a placeholder,
39
+ so the text is left free. What the doctype does ask for is underneath
40
+ it: the one- or two-sentence statement of what the guide covers,
41
+ which is how a reader decides in seconds whether they are in the
42
+ right document.
43
+ contains:
44
+ paragraphs:
45
+ min: 1
46
+ sections:
47
+ - id: symptom
48
+ description: >-
49
+ One thing the reader might be seeing - an error message, a
50
+ failure, a performance problem. An unbounded `max` claims every
51
+ consecutive H2 whose title starts with "Symptom". The number
52
+ upstream attaches (`## Symptom 1`) is not required, so
53
+ `## Symptom: sync stalls` is equally acceptable.
54
+ heading:
55
+ pattern: '^[Ss]ymptoms?\b'
56
+ sections:
57
+ - id: cause-or-solution
58
+ description: >-
59
+ One cause of the symptom, optionally followed by its solution
60
+ or workaround - `### Cause 1 of symptom 1`, then
61
+ `### Solution or workaround to cause 1 of symptom 1`. The
62
+ solution is optional within the pair because upstream's own
63
+ file pairs a second cause with no heading solution at all.
64
+ repeat:
65
+ - id: cause
66
+ description: >-
67
+ At least one is required: a symptom with no cause is not
68
+ a troubleshooting entry. Content is left unconstrained,
69
+ because the guide recommends bullet points for symptoms
70
+ and numbered steps for solutions, so a section here may
71
+ legitimately hold no paragraph at all.
72
+ heading:
73
+ pattern: '^[Cc]auses?\b'
74
+ max: 1
75
+ - id: solution
76
+ heading:
77
+ pattern: '^([Ss]olutions?|[Ww]orkarounds?)\b'
78
+ min: 0
79
+ max: 1
80
+ - id: for-more-information
81
+ description: >-
82
+ Further reading for this symptom. Optional, and anchored, so
83
+ the repeating pair above stops at it rather than treating it
84
+ as one more cause.
85
+ heading: For more information
86
+ min: 0
87
+ max: 1
88
+ - id: for-more-information
89
+ description: >-
90
+ Further reading for the guide as a whole. Upstream writes this
91
+ heading at H3, inside the last symptom, which reads like a level
92
+ slip - its text ("other sources ... with your product, task, or
93
+ feature") is about the product, not about one symptom. Rather
94
+ than pick a side, the section is allowed, and optional, at both
95
+ levels.
96
+ heading: For more information
97
+ min: 0
98
+ max: 1