docopslab-dev 0.1.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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.adoc +904 -0
- data/assets/config-packs/actionlint/base.yml +13 -0
- data/assets/config-packs/actionlint/project.yml +13 -0
- data/assets/config-packs/htmlproofer/base.yml +27 -0
- data/assets/config-packs/htmlproofer/project.yml +25 -0
- data/assets/config-packs/rubocop/base.yml +130 -0
- data/assets/config-packs/rubocop/project.yml +8 -0
- data/assets/config-packs/shellcheck/base.shellcheckrc +14 -0
- data/assets/config-packs/subtxt/ai-asciidoc-antipatterns.sub.txt +11 -0
- data/assets/config-packs/vale/asciidoc/ExplicitSectionIDs.yml +8 -0
- data/assets/config-packs/vale/asciidoc/ExtraLineBeforeLevel1.yml +7 -0
- data/assets/config-packs/vale/asciidoc/OneSentencePerLine.yml +8 -0
- data/assets/config-packs/vale/asciidoc/PreferSourceBlocks.yml +8 -0
- data/assets/config-packs/vale/asciidoc/ProperAdmonitions.yml +8 -0
- data/assets/config-packs/vale/asciidoc/ProperDLs.yml +7 -0
- data/assets/config-packs/vale/asciidoc/UncleanListStart.yml +8 -0
- data/assets/config-packs/vale/authoring/ButParagraph.yml +8 -0
- data/assets/config-packs/vale/authoring/ExNotEg.yml +8 -0
- data/assets/config-packs/vale/authoring/LiteralTerms.yml +20 -0
- data/assets/config-packs/vale/authoring/Spelling.yml +679 -0
- data/assets/config-packs/vale/base.ini +38 -0
- data/assets/config-packs/vale/config/scripts/ExplicitSectionIDs.tengo +56 -0
- data/assets/config-packs/vale/config/scripts/ExtraLineBeforeLevel1.tengo +121 -0
- data/assets/config-packs/vale/config/scripts/OneSentencePerLine.tengo +53 -0
- data/assets/config-packs/vale/project.ini +5 -0
- data/assets/hooks/pre-commit +63 -0
- data/assets/hooks/pre-push +72 -0
- data/assets/scripts/adoc_section_ids.rb +50 -0
- data/assets/scripts/build-common.sh +193 -0
- data/assets/scripts/build-docker.sh +64 -0
- data/assets/scripts/build.sh +56 -0
- data/assets/scripts/parse_jekyll_asciidoc_logs.rb +467 -0
- data/assets/templates/Gemfile +7 -0
- data/assets/templates/Rakefile +3 -0
- data/assets/templates/gitignore +69 -0
- data/assets/templates/jekyll-asciidoc-fix.prompt.yml +17 -0
- data/assets/templates/spellcheck.prompt.yml +16 -0
- data/docopslab-dev.gemspec +56 -0
- data/docs/agent/AGENTS.md +229 -0
- data/docs/agent/index.md +80 -0
- data/docs/agent/missions/conduct-release.md +224 -0
- data/docs/agent/missions/setup-new-project.md +250 -0
- data/docs/agent/roles/devops-release-engineer.md +152 -0
- data/docs/agent/roles/docops-engineer.md +193 -0
- data/docs/agent/roles/planner-architect.md +74 -0
- data/docs/agent/roles/product-engineer.md +153 -0
- data/docs/agent/roles/product-manager.md +130 -0
- data/docs/agent/roles/project-manager.md +139 -0
- data/docs/agent/roles/qa-testing-engineer.md +115 -0
- data/docs/agent/roles/tech-docs-manager.md +143 -0
- data/docs/agent/roles/tech-writer.md +163 -0
- data/docs/agent/skills/asciidoc.md +609 -0
- data/docs/agent/skills/code-commenting.md +347 -0
- data/docs/agent/skills/fix-broken-links.md +309 -0
- data/docs/agent/skills/fix-jekyll-asciidoc-build-errors.md +23 -0
- data/docs/agent/skills/fix-spelling-issues.md +13 -0
- data/docs/agent/skills/git.md +170 -0
- data/docs/agent/skills/github-issues.md +135 -0
- data/docs/agent/skills/product-release-rollback-and-patching.md +71 -0
- data/docs/agent/skills/rake-cli-dev.md +57 -0
- data/docs/agent/skills/readme-driven-dev.md +13 -0
- data/docs/agent/skills/release-history.md +29 -0
- data/docs/agent/skills/ruby.md +192 -0
- data/docs/agent/skills/schemagraphy-sgyml.md +18 -0
- data/docs/agent/skills/tests-running.md +25 -0
- data/docs/agent/skills/tests-writing.md +45 -0
- data/docs/agent/skills/write-the-docs.md +54 -0
- data/docs/agent/topics/common-project-paths.md +117 -0
- data/docs/agent/topics/dev-tooling-usage.md +202 -0
- data/docs/agent/topics/devops-ci-cd.md +55 -0
- data/docs/agent/topics/product-docs-deployment.md +25 -0
- data/lib/docopslab/dev/auto_fix_asciidoc.rb +46 -0
- data/lib/docopslab/dev/checkers.rb +108 -0
- data/lib/docopslab/dev/config_manager.rb +241 -0
- data/lib/docopslab/dev/file_utils.rb +140 -0
- data/lib/docopslab/dev/git_hooks.rb +140 -0
- data/lib/docopslab/dev/help.rb +121 -0
- data/lib/docopslab/dev/initializer.rb +95 -0
- data/lib/docopslab/dev/linters.rb +451 -0
- data/lib/docopslab/dev/log_parser.rb +31 -0
- data/lib/docopslab/dev/paths.rb +46 -0
- data/lib/docopslab/dev/script_manager.rb +136 -0
- data/lib/docopslab/dev/spell_check.rb +194 -0
- data/lib/docopslab/dev/sync_ops.rb +468 -0
- data/lib/docopslab/dev/tasks.rb +440 -0
- data/lib/docopslab/dev/tool_execution.rb +68 -0
- data/lib/docopslab/dev/version.rb +8 -0
- data/lib/docopslab/dev.rb +392 -0
- data/specs/data/default-manifest.yml +64 -0
- data/specs/data/manifest-schema.yaml +63 -0
- data/specs/data/tasks-def.yml +321 -0
- data/specs/data/tools.yml +60 -0
- metadata +362 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
# Code Commenting
|
|
2
|
+
|
|
3
|
+
This document is intended for AI agents operating within a DocOps Lab environment.
|
|
4
|
+
|
|
5
|
+
Employing good code commenting practices is more important than ever in the age of LLM-assisted programming. Existing comments are a model for future comments, and poor commenting hygiene is contagious.
|
|
6
|
+
|
|
7
|
+
In order to maximize the usefulness of code comments for both human and AI readers, DocOps Lab projects follow specific commenting conventions, including purpose and style constraints.
|
|
8
|
+
|
|
9
|
+
LLM-backed tools and linters are used to review comments and enforce adherence to these conventions, but developer attention is critical. Comments are unlikely to be improved upon after initially merged.
|
|
10
|
+
|
|
11
|
+
Table of Contents
|
|
12
|
+
|
|
13
|
+
- Code Comments Orientation
|
|
14
|
+
- Kinds of Comments
|
|
15
|
+
- Flavors of Code
|
|
16
|
+
- General Style Rules
|
|
17
|
+
- Expository Comments: Use and Abuse
|
|
18
|
+
- Principles
|
|
19
|
+
- General Examples
|
|
20
|
+
- Style
|
|
21
|
+
- Examples
|
|
22
|
+
- Comment Protocols by Language
|
|
23
|
+
- Ruby Commenting Protocols
|
|
24
|
+
- YAML Commenting Protocols
|
|
25
|
+
|
|
26
|
+
## Code Comments Orientation
|
|
27
|
+
|
|
28
|
+
To begin, we will standardize our understanding of what types of comments are applied to what kinds of code.
|
|
29
|
+
|
|
30
|
+
### Kinds of Comments
|
|
31
|
+
|
|
32
|
+
Code comments come in several distinct types.
|
|
33
|
+
|
|
34
|
+
**documentation** :
|
|
35
|
+
Code comments used to build downstream-facing reference docs for methods, classes, functions, data objects, and so forth.
|
|
36
|
+
|
|
37
|
+
_Docstrings_ are specifically comments used in the generation of rich-text reference docs. That they also happen to “document” the code to which they are adjacent is secondary.
|
|
38
|
+
|
|
39
|
+
**expository** :
|
|
40
|
+
Code comments that explain the purpose or function of code blocks, algorithms, or complex logic, strictly in natural language. Also called “inline comments”, these arbitrary remarks are mainly what is governed by this protocol guide.
|
|
41
|
+
|
|
42
|
+
**rationale** :
|
|
43
|
+
Comments that explain the reasoning behind a particular implementation choice, design pattern, or data structure.
|
|
44
|
+
|
|
45
|
+
**status** :
|
|
46
|
+
Stability and lifecycle markers: `DEPRECATED:`, `EXPERIMENTAL:`, `INTERNAL:`, `UNSTABLE:`. May also include planned removal dates, version gates, feature flags.
|
|
47
|
+
|
|
48
|
+
**admonition** :
|
|
49
|
+
Developer-facing warnings, notes, or tips embedded in code. Use `WARNING:`, `NOTE:`, and `TIP:` prefixes to mark these comments distinctly.
|
|
50
|
+
|
|
51
|
+
**task** :
|
|
52
|
+
Comments like `TODO:` and `FIXME:` are used to mark code that needs further work.
|
|
53
|
+
|
|
54
|
+
**instructional** :
|
|
55
|
+
Code comments left in template, stub, or sample files for interactive use. These comments tend to be intended for a downstream user who will interact directly with the file or one based on it.
|
|
56
|
+
|
|
57
|
+
**label** :
|
|
58
|
+
Comments that simply annotate sections of code by category or general purpose, to help with demarcation and navigation. These comments are usually brief and may use special formatting to stand out.
|
|
59
|
+
|
|
60
|
+
**directive** :
|
|
61
|
+
In some languages, we use special character patterns to signify that a comment has a special purpose, other than for generating reference docs. These comments may mark code for special parsing, content transclusion, or other operations.
|
|
62
|
+
|
|
63
|
+
In AsciiDoc, comments like `// tag::example[]` and `// end::example[]` are used to mark content for inclusion elsewhere.
|
|
64
|
+
|
|
65
|
+
The popular linter Vale recognizes HTML comments like `<!-- vale off -→` and `<!-- vale on -→` to disable and re-enable content linting.
|
|
66
|
+
|
|
67
|
+
**sequential/collection** :
|
|
68
|
+
Comments that number or order logical stages in a complex or lengthy process or members of a set. Usually something like `# STEP 1:`, `# PHASE 1:`, and so forth, or else `# GROUP A:`, `# SECTION 1:`, etc. Always use uppercase for these markers (ex: `# STEP:` not `# Step:`).
|
|
69
|
+
|
|
70
|
+
### Flavors of Code
|
|
71
|
+
|
|
72
|
+
**Ruby** :
|
|
73
|
+
The most robust environment for code comments, Ruby supports RDoc/YARD-style documentation comments that can be used to generate reference documentation. See Ruby Commenting Protocols for more.
|
|
74
|
+
|
|
75
|
+
**Bash** :
|
|
76
|
+
We make extensive use of comments in Bash scripts, but Bash has no standard for documentation comments or structured comments.
|
|
77
|
+
|
|
78
|
+
**AsciiDoc** :
|
|
79
|
+
Comments in `.adoc` files tend to be labels, tasks, and directives (AsciiDoc tags). AsciiDoc files tend not to have expository comments, since the content is already documentation.
|
|
80
|
+
|
|
81
|
+
**YAML/SGYML** :
|
|
82
|
+
YAML files use copious label and instructional comments to help downstream users navigate and understand large or complex data structures. Comments can also be used to annotate nesting depth. See YAML Commenting Protocols for more.
|
|
83
|
+
|
|
84
|
+
**Liquid** :
|
|
85
|
+
Our use of Liquid comments is inconsistent at best. Part of the problem is their terrible format with explicit `{% comment %}` and `{% endcomment %}` tags. While Liquid 5 has greatly improved that, DocOps Lab tooling is standardized on Liquid 4 at this time.
|
|
86
|
+
|
|
87
|
+
**HTML** :
|
|
88
|
+
We don’t code much HTML directly. It is mostly either converted from lightweight markup or rendered by Liquid templates (or JavaScript). Comments are usually to mark nested objects for convenience, to label major structures or to highlight/clarify obscure asset references, or as directives such as `<!-- vale off -→`, which disables content linting.
|
|
89
|
+
|
|
90
|
+
**JavaScript** :
|
|
91
|
+
We are not a JavaScript shop, but we do write a good bit of vanilla JavaScript. Comments are used mainly to establish our bearings in the code and therefor are sometimes heavier than with other languages.
|
|
92
|
+
|
|
93
|
+
**CSS/SCSS** :
|
|
94
|
+
We mainly write CSS as SCSS, and commenting is mainly to express the intent upon compiling.
|
|
95
|
+
|
|
96
|
+
### General Style Rules
|
|
97
|
+
|
|
98
|
+
- Do not use em dashes or en dashes or (` - `).
|
|
99
|
+
|
|
100
|
+
- Use colons (`: `) to prefix a comment with a classification.
|
|
101
|
+
- Use semicolons (`; `) to break up clauses.
|
|
102
|
+
- Use sentence-style capitalization.
|
|
103
|
+
- Do not use terminal punctuation (periods, exclamation points, question marks) unless the comment is multiple sentences.
|
|
104
|
+
- Hard wrap comments around 110-120 characters.
|
|
105
|
+
|
|
106
|
+
- Use one-sentence per line.
|
|
107
|
+
- Try not to wrap anything _except_ full sentences.
|
|
108
|
+
- When wrapping multi-line sentences, indent subsequent lines by an additional space.
|
|
109
|
+
|
|
110
|
+
## Expository Comments: Use and Abuse
|
|
111
|
+
|
|
112
|
+
Arbitrary inline comments used to explain code should be used consistently and only when they add value.
|
|
113
|
+
|
|
114
|
+
Arbitrary comments can _often_ add value, under an array of conditions that may be more art than science. We must be forgiving and understanding of occasional or even frequent misfires in various developers' subjective takes on what is useful.
|
|
115
|
+
|
|
116
|
+
This guide exists to help with comment evaluation.
|
|
117
|
+
|
|
118
|
+
### Principles
|
|
119
|
+
|
|
120
|
+
Expository comments (and their authors) should adhere to these principles:
|
|
121
|
+
|
|
122
|
+
**1) Express purpose, not implementation.**:
|
|
123
|
+
Comments should explain why code exists or what it is intended to do, rather than how it does it. (Rationale comments are available for explaining design/engineering choices, if necessary.)
|
|
124
|
+
|
|
125
|
+
**2) Summarize peculiar or complex implementation (without violating #1).**:
|
|
126
|
+
Expository comments may _include_ a _brief_ reference to an explicit design choice. Still not a _rationale comment_ (too brief, in passing) nor a _task comment_ (no further action prescribed), just a nod to an unusual or non-obvious implementation detail.
|
|
127
|
+
|
|
128
|
+
**3) Use natural, imperative language.**:
|
|
129
|
+
Comments should not contain code, and they should be formatted as English clauses or sentences. Comments should be phrased as commands or instructions, focusing on the action being performed, from the perspective of what the code is to do.
|
|
130
|
+
|
|
131
|
+
**4) Be concise.**:
|
|
132
|
+
Comments should be as brief as possible. Multi-sentence comments should be the exception. In fact, comments should not typically be complete sentences.
|
|
133
|
+
|
|
134
|
+
**5) Maintain relevance and accuracy.**:
|
|
135
|
+
Comments should be reviewed and updated as code changes to ensure they remain accurate and relevant.
|
|
136
|
+
|
|
137
|
+
**6) Never cover straightforward code (except…).**:
|
|
138
|
+
Not all blocks need comments at all. The main criterion is whether the code’s purpose or function would not be _immediately_ clear from the code itself to a newcomer with beginner or intermediate knowledge of the language and little familiarity with the application architecture.
|
|
139
|
+
|
|
140
|
+
Exception: Sometimes an oddity or pivotal point needs to be highlighted even in otherwise straightforward code.
|
|
141
|
+
|
|
142
|
+
**7} Do not use comments as notes to reviewers.** :
|
|
143
|
+
Temporary comments intended to guide code reviewers should be avoided. Code used to help with flag logical points or communicate during pair programming or pre-commit review should be denoted as admonitions (such as `# LOGIC: ` or `# REVIEW: `) or `# TEMP: ` and removed before merging.
|
|
144
|
+
|
|
145
|
+
### General Examples
|
|
146
|
+
|
|
147
|
+
#### Unnecessary Comments
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
# Create destination directory if needed
|
|
151
|
+
FileUtils.mkdir_p(File.dirname(target_path))
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
This code does _exactly and only_ what the English comment says. In fact, the comment is muddier than the code. The code will create any necessary parent directories, whereas the comment only mentions the destination directory itself and does not explain _if needed_. In `mkdor_p`, the _if needed_ means _if the ancestor directories do not exist_.
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
# Determine if we should copy the file
|
|
158
|
+
file_existed_before_copy = File.exist?(target_path)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
This comment is trying to explain the _purpose_ of the line it precedes, but this is unnecessary. The code itself merely sets a variable to a Boolean value. Not only is the direct purpose of the variable clear from its name and the code making up its value, but the purpose of the variable is only relevant in the context of later code that uses it.
|
|
162
|
+
|
|
163
|
+
#### Comments that Add Value
|
|
164
|
+
|
|
165
|
+
```ruby
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Public helper methods accessible to LogIssue class
|
|
169
|
+
|
|
170
|
+
def normalize_source_path source_file
|
|
171
|
+
normalized = source_file.gsub(/#excerpt$/, '').gsub(%r{/$}, '')
|
|
172
|
+
normalized.gsub(%r{^\./}, '')
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def normalize_problem_path reported_path, source_file
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
A comment preceded and followed by blank lines indicates that it references or labels multiple subsequent blocks. (Or it is be part of a series of such comments that tend to and in its own case may yet still cover multiple blocks each.)
|
|
179
|
+
|
|
180
|
+
This categorizes sections for user convenience. It also helps LLM-backed tools to find relevant sections more easily.
|
|
181
|
+
|
|
182
|
+
```ruby
|
|
183
|
+
# Try to convert absolute path back to relative path
|
|
184
|
+
if missing_path =~ %r{/home/[^/]+/[^/]+/work/[^/]+/(.+)$} ||
|
|
185
|
+
missing_path =~ %r{/([^/]+/[^/]+\.adoc)$}
|
|
186
|
+
@path = Regexp.last_match(1)
|
|
187
|
+
end
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Summarizing a complex Regex pattern is vital. Conveying the _intent_ of the pattern is far more important than explaining its mechanics.
|
|
191
|
+
|
|
192
|
+
### Style
|
|
193
|
+
|
|
194
|
+
Expository comments have a _subject_: the code they refer to, typically in the form of a line or block. In nearly all cases, comments should immediately precede the subject code.
|
|
195
|
+
|
|
196
|
+
Example of comment preceding subject code
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
# Validate all inputs individually
|
|
200
|
+
inputs.each do |input|
|
|
201
|
+
# ...
|
|
202
|
+
end
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
In some languages, comments can be placed inline. This should be used sparingly.
|
|
206
|
+
|
|
207
|
+
We most commonly do this in YAML files.
|
|
208
|
+
|
|
209
|
+
Example of inline comment in YAML
|
|
210
|
+
|
|
211
|
+
```yaml
|
|
212
|
+
inputs: # List of inputs to validate
|
|
213
|
+
- input1
|
|
214
|
+
- input2
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
We also do this in JavaScript files.
|
|
218
|
+
|
|
219
|
+
Example of inline comment in JavaScript
|
|
220
|
+
|
|
221
|
+
```javascript
|
|
222
|
+
let count = calculated; // Start with the dynamic value
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Examples
|
|
226
|
+
|
|
227
|
+
Good comment examples
|
|
228
|
+
|
|
229
|
+
```ruby
|
|
230
|
+
# Calculate the factorial of a number using recursion
|
|
231
|
+
|
|
232
|
+
# Handle the base case
|
|
233
|
+
|
|
234
|
+
# Never call factorial with a negative number
|
|
235
|
+
|
|
236
|
+
# Validate all inputs individually
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Good comments are descriptive and purely abstract. They express an instruction and/or a principle to be adhered to or enforced within the subject block.
|
|
240
|
+
|
|
241
|
+
Bad comment examples (too simple/unnecessary)
|
|
242
|
+
|
|
243
|
+
```ruby
|
|
244
|
+
# Initialize the result to 1
|
|
245
|
+
|
|
246
|
+
# Loop through numbers from 1 to n
|
|
247
|
+
|
|
248
|
+
# Return the result
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Bad comment examples (non-imperative form)
|
|
252
|
+
|
|
253
|
+
```ruby
|
|
254
|
+
# Calculates the factorial of a number
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Comment Protocols by Language
|
|
258
|
+
|
|
259
|
+
### Ruby Commenting Protocols
|
|
260
|
+
|
|
261
|
+
All public-facing methods and classes should be documented with YARD documentation comments.
|
|
262
|
+
|
|
263
|
+
For expository comments, follow the Principles outlined above.
|
|
264
|
+
|
|
265
|
+
#### API Documentation Comments
|
|
266
|
+
|
|
267
|
+
Many of our Ruby gems provide public APIs that are documented using YARD.
|
|
268
|
+
|
|
269
|
+
Private methods and classes may also be documented, but this is not required.
|
|
270
|
+
|
|
271
|
+
Never describe a method just by what it returns or what parameters it takes. Describe what the method _does_ behind the scenes or what its summarized purpose.
|
|
272
|
+
|
|
273
|
+
When documenting Ruby classes and methods with YARD, follow these patterns:
|
|
274
|
+
|
|
275
|
+
**class descriptions** :
|
|
276
|
+
Keep class descriptions focused on the class’s primary responsibility and role within the system. Avoid overselling capabilities or implementation details.
|
|
277
|
+
|
|
278
|
+
**method descriptions** :
|
|
279
|
+
Lead with what the method accomplishes, not just its signature. Example: "Processes the provided attributes to populate Change properties" rather than "Initializes a new Change object."
|
|
280
|
+
|
|
281
|
+
**capitalization consistency** :
|
|
282
|
+
When referring to class objects conceptually or as an instance (not variable names), use CamelCase names. Use lowercase for most instances where the term refers to a real-world object or concept.
|
|
283
|
+
|
|
284
|
+
**voice consistency** :
|
|
285
|
+
Use descriptive, present-tense “voice” for API documentation and YARD comments.
|
|
286
|
+
|
|
287
|
+
#### Exceptions
|
|
288
|
+
|
|
289
|
+
On rare occasions, comments are used to denote deep nesting in large files.
|
|
290
|
+
|
|
291
|
+
Annotating `end` keywords that wrap up large blocks/statements
|
|
292
|
+
|
|
293
|
+
```ruby
|
|
294
|
+
end # method my_method
|
|
295
|
+
end # class MyClass
|
|
296
|
+
end # module MyModule
|
|
297
|
+
end # module SuperModule
|
|
298
|
+
end # module OurCoolGem
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Whenever possible, even when deep nesting is warranted, keep files small enough that such labels won’t be need, all else being equal.
|
|
302
|
+
|
|
303
|
+
### YAML Commenting Protocols
|
|
304
|
+
|
|
305
|
+
YAML files often contain extensive comments to help users understand the structure and purpose of the data.
|
|
306
|
+
|
|
307
|
+
Comments should be used to label sections, explain complex structures, and provide hints or assistance for downstream/later users populating data fields.
|
|
308
|
+
|
|
309
|
+
Examples of YAML comments
|
|
310
|
+
|
|
311
|
+
```yaml
|
|
312
|
+
# General data
|
|
313
|
+
inputs:
|
|
314
|
+
- name: input1 # required
|
|
315
|
+
- name: input2 # optional
|
|
316
|
+
config: # Settings for the application itself
|
|
317
|
+
setting1: value1 # Enable feature X (which is not called setting1 and thus needs translation)
|
|
318
|
+
body: | # Use AsciiDoc format
|
|
319
|
+
This is content for the body of something.
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
We sometimes use comments to categorize a large Array or Map for navigation, even if the data is included in all members of the Array.
|
|
323
|
+
|
|
324
|
+
Example of YAML section label
|
|
325
|
+
|
|
326
|
+
```yaml
|
|
327
|
+
# POSTS
|
|
328
|
+
- slug: first-post
|
|
329
|
+
title: My First Post
|
|
330
|
+
type: post
|
|
331
|
+
|
|
332
|
+
- slug: second-post
|
|
333
|
+
title: My Second Post
|
|
334
|
+
type: post
|
|
335
|
+
|
|
336
|
+
# - etc
|
|
337
|
+
|
|
338
|
+
# PAGES
|
|
339
|
+
- slug: about
|
|
340
|
+
title: About Me
|
|
341
|
+
type: page
|
|
342
|
+
|
|
343
|
+
# - etc
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
This is used when it makes no sense to nest data under parent keys like `posts:` and `pages:`, yet users will still need to navigate through large collections.
|
|
347
|
+
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# Fix Broken Links
|
|
2
|
+
|
|
3
|
+
This document is intended for AI agents operating within a DocOps Lab environment.
|
|
4
|
+
|
|
5
|
+
Original sources for this document include:
|
|
6
|
+
|
|
7
|
+
<!-- detect the origin url based on the slug (origin) -->
|
|
8
|
+
- [Fix Broken Links](/docs/agent/fix-broken-links/)
|
|
9
|
+
|
|
10
|
+
A systematic approach to debugging and fixing broken links in DocOps Lab websites or sites generated with DocOps Lab tooling.
|
|
11
|
+
|
|
12
|
+
Due to complex sourcing procedures at work in DocOps Lab projects, where a particular link comes from is not always obvious.
|
|
13
|
+
|
|
14
|
+
This guide focuses on the methodologies for tracing link sources rather than specific solutions, making it applicable across different Jekyll/AsciiDoc sites.
|
|
15
|
+
|
|
16
|
+
Table of Contents
|
|
17
|
+
|
|
18
|
+
- Common Link Failure Patterns
|
|
19
|
+
- External Link Failures
|
|
20
|
+
- Internal Link Failures
|
|
21
|
+
- Debugging Methodology
|
|
22
|
+
- Step 1: Run HTMLProofer and Categorize Failures
|
|
23
|
+
- Step 2: Identify High-Impact Patterns
|
|
24
|
+
- Step 3: Trace Link Sources
|
|
25
|
+
- Step 4: Apply Appropriate Fix Strategy
|
|
26
|
+
- Data-Driven Link Debugging
|
|
27
|
+
- YAML Data Sources
|
|
28
|
+
- Dependency Tracing Process
|
|
29
|
+
- Example Trace: AsciiDocsy Links
|
|
30
|
+
- Pre-Publication Link Strategy
|
|
31
|
+
- Validation and Testing
|
|
32
|
+
- Rebuild and Verify
|
|
33
|
+
- Test Cycle
|
|
34
|
+
- Prevention Strategies
|
|
35
|
+
- Development Practices
|
|
36
|
+
- Configuration Management
|
|
37
|
+
|
|
38
|
+
## Common Link Failure Patterns
|
|
39
|
+
|
|
40
|
+
### External Link Failures
|
|
41
|
+
|
|
42
|
+
**Network timeouts** :
|
|
43
|
+
Temporary connectivity issues that resolve after rebuild
|
|
44
|
+
|
|
45
|
+
**404 errors** :
|
|
46
|
+
Missing pages or incorrect URLs
|
|
47
|
+
|
|
48
|
+
**Pre-publication links** :
|
|
49
|
+
Links to repositories or resources not yet available
|
|
50
|
+
|
|
51
|
+
**Malformed URLs** :
|
|
52
|
+
Missing repository names or incorrect paths
|
|
53
|
+
|
|
54
|
+
### Internal Link Failures
|
|
55
|
+
|
|
56
|
+
**Missing project anchors** :
|
|
57
|
+
Data/template mismatches in generated content
|
|
58
|
+
|
|
59
|
+
**Section anchor mismatches** :
|
|
60
|
+
ID generation vs link target differences
|
|
61
|
+
|
|
62
|
+
**Template variable errors** :
|
|
63
|
+
Unprocessed variables in URLs
|
|
64
|
+
|
|
65
|
+
**Missing pages** :
|
|
66
|
+
Links to pages that don’t exist
|
|
67
|
+
|
|
68
|
+
## Debugging Methodology
|
|
69
|
+
|
|
70
|
+
### Step 1: Run HTMLProofer and Categorize Failures
|
|
71
|
+
|
|
72
|
+
Run link validation
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
bundle exec rake labdev:lint:html 2>&1 | tee .agent/scratch/link-failures.txt
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Extract external failure patterns
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
grep "External link.*failed" .agent/scratch/link-failures.txt | wc -l
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Extract internal failure patterns
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
grep "internally linking" .agent/scratch/link-failures.txt | wc -l
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Step 2: Identify High-Impact Patterns
|
|
91
|
+
|
|
92
|
+
Look for repeated failures across multiple pages:
|
|
93
|
+
|
|
94
|
+
- Same broken link appearing on 3+ pages = template/data issue
|
|
95
|
+
- Similar link patterns = systematic problem
|
|
96
|
+
- Timeout clusters = network/rebuild issue
|
|
97
|
+
|
|
98
|
+
### Step 3: Trace Link Sources
|
|
99
|
+
|
|
100
|
+
#### For Missing Anchors (Internal Links and X-refs)
|
|
101
|
+
|
|
102
|
+
If the problem is an anchor that does not exist, either the pointer or the anchor must be wrong.
|
|
103
|
+
|
|
104
|
+
****Consider how the page was generated:**** :
|
|
105
|
+
- Is it a standard `.adoc` file?
|
|
106
|
+
- Is it a Liquid-rendered HTML page?
|
|
107
|
+
- Is it a Liquid-rendered AsciiDoc file (usually `*.adoc.liquid` or `*.asciidoc`)
|
|
108
|
+
|
|
109
|
+
****For standard AsciiDoc files…**** :
|
|
110
|
+
The offending link source will likely be:
|
|
111
|
+
|
|
112
|
+
1. an AsciiDoc xref (`<<anchor-slug>>` or `xref:anchor-slug[]`)
|
|
113
|
+
2. a pre-generated xref in the form of an attribute placeholder (`{xref_scope_anchor-slug_link}`) that has resolved to a proper AsciiDoc xref
|
|
114
|
+
3. a hybrid reference (`link:{xref_scope_anchor-slug_url}[some text]`)
|
|
115
|
+
|
|
116
|
+
In any case, the `anchor-slug` portion should correspond literally to the reported missing anchor. If these are rendering properly and do not contain obvious misspellings, consider how the intended target might be misspelled or missing and address the source of the anchor itself.
|
|
117
|
+
|
|
118
|
+
****For Liquid-rendered pages…**** :
|
|
119
|
+
The offending link source will likely be a misspelled or poorly constructed link.
|
|
120
|
+
|
|
121
|
+
1. a hard-coded link in Liquid/HTML (`"a href="#anchor-slug">`)
|
|
122
|
+
2. a data-driven link in Liquid/HTML (`"a href="#{{ variable | slugify }}">`)
|
|
123
|
+
3. a data-driven link in Liquid/AsciiDoc (`link:#{{ variable | slugify }}`)
|
|
124
|
+
4. a pre-generated xref in the form of an attribute placeholder (`{xref_some-scope_some-slug-string_link}`; generated from Liquid such as: `{xref_{{ scope }}_{{ variable }}_link}`)
|
|
125
|
+
|
|
126
|
+
Other than for hard-coded links, you will need to trace the source to one of the following:
|
|
127
|
+
|
|
128
|
+
- A YAML file, typically in a `_data/` or `data/` directory.
|
|
129
|
+
|
|
130
|
+
Search for the offending anchor
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
grep -rn "broken-anchor-slug" --include \*.yml --include \*.yaml
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
> **NOTE:** If there are numerous errors of this kind, the problem _could_ be in the code that generates the attributes from the YAML source.
|
|
137
|
+
- Attributes derived from a file like `README.adoc`.
|
|
138
|
+
|
|
139
|
+
Search for the offending attribute
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
grep -rn "^:.*broken-anchor.*:" --include \*.adoc
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
****Other tips for investigating broken anchors:**** :
|
|
146
|
+
Check what anchors actually exist
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
grep -on 'id="[^"]*"' _site/page-slug/index.html
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Find template generating the links
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
grep -rn "distinct identifier string" _includes _pages _templates
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Step 4: Apply Appropriate Fix Strategy
|
|
159
|
+
|
|
160
|
+
#### Option A: Fix the Data (Recommended for Project Links)
|
|
161
|
+
|
|
162
|
+
Update dependency names to match actual project slugs:
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
# Before
|
|
166
|
+
deps: [jekyll-asciidoc-ui, AsciiDocsy]
|
|
167
|
+
|
|
168
|
+
# After
|
|
169
|
+
deps: [jekyll-asciidoc-ui, asciidocsy-jekyll-theme]
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Option B: Fix the Template
|
|
173
|
+
|
|
174
|
+
Update link generation to use project lookup:
|
|
175
|
+
|
|
176
|
+
```liquid
|
|
177
|
+
{% assign dep_project = projects | where: 'slug', dep | first %}
|
|
178
|
+
{% unless dep_project %}{% assign dep_project = projects | where: 'name', dep | first %}{% endunless %}
|
|
179
|
+
<a href="/projects/#{{ dep_project.slug | default: dep | slugify }}">
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
#### Option C: Fix the Anchors/IDs
|
|
183
|
+
|
|
184
|
+
Update actual IDs to match expected links. Use this solution only when the link source is wrong or the target anchor ID is wrong where it is designated or missing.
|
|
185
|
+
|
|
186
|
+
Misspelled link source
|
|
187
|
+
|
|
188
|
+
```asciidoc
|
|
189
|
+
See xref:sectione-one[Section One] for details.
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Misspelled anchor ID
|
|
193
|
+
|
|
194
|
+
```asciidoc
|
|
195
|
+
[[secton-one]]
|
|
196
|
+
=== Section One
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Data-Driven Link Debugging
|
|
200
|
+
|
|
201
|
+
### YAML Data Sources
|
|
202
|
+
|
|
203
|
+
Key files that commonly generate broken links:
|
|
204
|
+
|
|
205
|
+
**`_data/docops-lab-projects.yml`** :
|
|
206
|
+
Project dependencies and metadata
|
|
207
|
+
|
|
208
|
+
**`_data/pages/*.yml`** :
|
|
209
|
+
Navigation and cross-references
|
|
210
|
+
|
|
211
|
+
**Individual frontmatter** :
|
|
212
|
+
Local link definitions
|
|
213
|
+
|
|
214
|
+
### Dependency Tracing Process
|
|
215
|
+
|
|
216
|
+
1. **Identify the broken link pattern** : `#missing-anchor`
|
|
217
|
+
2. **Find the data source** : Search YAML files for dependency names
|
|
218
|
+
3. **Trace template processing** : Follow Liquid template logic
|
|
219
|
+
4. **Compare with reality** : Check actual generated IDs
|
|
220
|
+
5. **Apply data fix** : Update dependency to match actual slug
|
|
221
|
+
|
|
222
|
+
### Example Trace: AsciiDocsy Links
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
# 1. Broken link found
|
|
226
|
+
# internally linking to /projects/#asciidocsy
|
|
227
|
+
|
|
228
|
+
# 2. Find template source
|
|
229
|
+
grep -r "#asciidocsy" _includes/
|
|
230
|
+
# Found in: _includes/project-profile.html line 76
|
|
231
|
+
|
|
232
|
+
# 3. Check template logic
|
|
233
|
+
# href="/projects/#{{ dep | slugify }}"
|
|
234
|
+
|
|
235
|
+
# 4. Find data source
|
|
236
|
+
grep -n "AsciiDocsy" _data/docops-lab-projects.yml
|
|
237
|
+
# Found: deps: [..., AsciiDocsy]
|
|
238
|
+
|
|
239
|
+
# 5. Check actual anchor
|
|
240
|
+
grep 'id=".*asciidoc.*"' _site/projects/index.html
|
|
241
|
+
# Found: id="asciidocsy-jekyll-theme"
|
|
242
|
+
|
|
243
|
+
# 6. Fix: Change AsciiDocsy → asciidocsy-jekyll-theme
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Pre-Publication Link Strategy
|
|
247
|
+
|
|
248
|
+
For links to resources not yet available:
|
|
249
|
+
|
|
250
|
+
1. **Tag with FIXME-PREPUB** : Add comments for easy identification
|
|
251
|
+
2. **Document in notes** : Track what needs to be updated at publication
|
|
252
|
+
3. **Use conditional logic** : Hide pre-pub links in production builds
|
|
253
|
+
|
|
254
|
+
```asciidoc
|
|
255
|
+
// FIXME-PREPUB: Update when DocOps/box repository is published
|
|
256
|
+
See the link:https://github.com/DocOps/box[DocOps Box repository] for details.
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Validation and Testing
|
|
260
|
+
|
|
261
|
+
### Rebuild and Verify
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Rebuild site with fixes
|
|
265
|
+
bundle exec rake build
|
|
266
|
+
|
|
267
|
+
# Re-run validation
|
|
268
|
+
bundle exec rake labdev:lint:html
|
|
269
|
+
|
|
270
|
+
# Check specific fix
|
|
271
|
+
grep "#fixed-anchor" _site/target-page.html
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Test Cycle
|
|
275
|
+
|
|
276
|
+
1. Fix high-impact patterns first (3+ occurrences)
|
|
277
|
+
2. Rebuild and validate after each batch of fixes
|
|
278
|
+
3. Document fixes for future reference
|
|
279
|
+
4. Test both internal and external link resolution
|
|
280
|
+
|
|
281
|
+
## Prevention Strategies
|
|
282
|
+
|
|
283
|
+
### Development Practices
|
|
284
|
+
|
|
285
|
+
**Consistent naming** :
|
|
286
|
+
Align dependency names with actual project slugs
|
|
287
|
+
|
|
288
|
+
**Template validation** :
|
|
289
|
+
Test link generation logic with sample data
|
|
290
|
+
|
|
291
|
+
**Documentation standards** :
|
|
292
|
+
Document expected anchor patterns
|
|
293
|
+
|
|
294
|
+
**Regular validation** :
|
|
295
|
+
Include link checking in CI/CD pipelines
|
|
296
|
+
|
|
297
|
+
### Configuration Management
|
|
298
|
+
|
|
299
|
+
**Default values** :
|
|
300
|
+
Define link patterns in configuration rather than hardcoding
|
|
301
|
+
|
|
302
|
+
**Validation rules** :
|
|
303
|
+
Create checks for common link anti-patterns
|
|
304
|
+
|
|
305
|
+
**Documentation** :
|
|
306
|
+
Maintain mapping between logical names and actual slugs
|
|
307
|
+
|
|
308
|
+
This systematic approach transforms broken link debugging from a frustrating manual process into a predictable, methodical workflow that scales across projects and team members.
|
|
309
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Fix Jekyll AsciiDoc Build Errors
|
|
2
|
+
|
|
3
|
+
This document is intended for AI agents operating within a DocOps Lab environment.
|
|
4
|
+
|
|
5
|
+
As an AI agent, you can help fix Asciidoctor errors in Jekyll builds.
|
|
6
|
+
|
|
7
|
+
1. Perform a basic Jekyll build that writes verbose output to a local file.
|
|
8
|
+
|
|
9
|
+
Example with config option
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
bundle exec jekyll build --verbose --config configs/jekyll.yml > .agent/scratch/jekyll-build.log 2>&1
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Note the `2>&1` at the end of the command, which ensures that both standard output and error messages are captured in the log file.
|
|
16
|
+
2. Run the analysis task on the exported file.
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
bundle exec rake 'labdev:lint:logs[jekyll-asciidoc,.agent/scratch/jekyll-build.log]'
|
|
20
|
+
```
|
|
21
|
+
3. Open the YAML file relayed in the response message (example: `Jekyll AsciiDoc issues report generated: .agent/reports/jekyll-asciidoc-issues-20251214_085323.yml`).
|
|
22
|
+
4. Follow the instructions in the report to address the issues found.
|
|
23
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Fix Spelling Issues in Documentation
|
|
2
|
+
|
|
3
|
+
This document is intended for AI agents operating within a DocOps Lab environment.
|
|
4
|
+
|
|
5
|
+
As an AI agent, you can help DocOps Lab developers fix spelling issues in documentation by following the procedure below.
|
|
6
|
+
|
|
7
|
+
1. Use the spellcheck task to generate a spelling report.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
bundle exec rake labdev:lint:spellcheck
|
|
11
|
+
```
|
|
12
|
+
2. Follow the prompts in the generated report.
|
|
13
|
+
|