docopslab-dev 0.1.0 → 0.2.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.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +645 -318
  3. data/docopslab-dev.gemspec +2 -3
  4. data/docs/agent/index.md +4 -8
  5. data/docs/agent/misc/bash-styles.md +470 -0
  6. data/docs/agent/missions/conduct-release.md +161 -87
  7. data/docs/agent/missions/setup-new-project.md +228 -134
  8. data/docs/agent/roles/devops-release-engineer.md +60 -17
  9. data/docs/agent/roles/docops-engineer.md +84 -20
  10. data/docs/agent/roles/planner-architect.md +22 -0
  11. data/docs/agent/roles/product-engineer.md +63 -15
  12. data/docs/agent/roles/product-manager.md +57 -24
  13. data/docs/agent/roles/project-manager.md +48 -12
  14. data/docs/agent/roles/qa-testing-engineer.md +48 -14
  15. data/docs/agent/roles/tech-docs-manager.md +63 -17
  16. data/docs/agent/roles/tech-writer.md +68 -14
  17. data/docs/agent/skills/asciidoc.md +65 -238
  18. data/docs/agent/skills/bash-cli-dev.md +135 -0
  19. data/docs/agent/skills/code-commenting.md +143 -106
  20. data/docs/agent/skills/fix-broken-links.md +145 -100
  21. data/docs/agent/skills/fix-jekyll-asciidoc-build-errors.md +1 -10
  22. data/docs/agent/skills/fix-spelling-issues.md +0 -3
  23. data/docs/agent/skills/git.md +69 -34
  24. data/docs/agent/skills/github-issues.md +110 -71
  25. data/docs/agent/skills/rake-cli-dev.md +1 -1
  26. data/docs/agent/skills/readme-driven-dev.md +1 -0
  27. data/docs/agent/skills/release-history.md +1 -7
  28. data/docs/agent/skills/ruby.md +18 -7
  29. data/docs/agent/skills/schemagraphy-sgyml.md +3 -0
  30. data/docs/agent/skills/tests-running.md +22 -14
  31. data/docs/agent/skills/tests-writing.md +51 -28
  32. data/docs/agent/skills/write-the-docs.md +71 -9
  33. data/docs/agent/topics/common-project-paths.md +122 -70
  34. data/docs/agent/topics/dev-tooling-usage.md +70 -77
  35. data/docs/agent/topics/devops-ci-cd.md +3 -1
  36. data/docs/agent/topics/product-docs-deployment.md +18 -12
  37. data/docs/library-readme.adoc +39 -0
  38. data/lib/docopslab/dev/cast_ops.rb +199 -0
  39. data/lib/docopslab/dev/config_manager.rb +6 -6
  40. data/lib/docopslab/dev/data_utils.rb +42 -0
  41. data/lib/docopslab/dev/file_utils.rb +18 -7
  42. data/lib/docopslab/dev/git_branch.rb +201 -0
  43. data/lib/docopslab/dev/git_hooks.rb +17 -11
  44. data/lib/docopslab/dev/initializer.rb +13 -4
  45. data/lib/docopslab/dev/library/cache.rb +167 -0
  46. data/lib/docopslab/dev/library/fetch.rb +209 -0
  47. data/lib/docopslab/dev/library.rb +328 -0
  48. data/lib/docopslab/dev/linters.rb +63 -12
  49. data/lib/docopslab/dev/manifest.rb +28 -0
  50. data/lib/docopslab/dev/paths.rb +0 -17
  51. data/lib/docopslab/dev/script_manager.rb +12 -6
  52. data/lib/docopslab/dev/skim.rb +109 -0
  53. data/lib/docopslab/dev/spell_check.rb +2 -2
  54. data/lib/docopslab/dev/sync_ops.rb +94 -33
  55. data/lib/docopslab/dev/tasks.rb +58 -18
  56. data/lib/docopslab/dev/version.rb +1 -1
  57. data/lib/docopslab/dev.rb +75 -35
  58. data/specs/data/default-manifest.yml +15 -5
  59. data/specs/data/library-index.yml +22 -0
  60. data/specs/data/manifest-schema.yaml +142 -4
  61. data/specs/data/tasks-def.yml +122 -10
  62. metadata +28 -39
  63. data/assets/config-packs/actionlint/base.yml +0 -13
  64. data/assets/config-packs/actionlint/project.yml +0 -13
  65. data/assets/config-packs/htmlproofer/base.yml +0 -27
  66. data/assets/config-packs/htmlproofer/project.yml +0 -25
  67. data/assets/config-packs/rubocop/base.yml +0 -130
  68. data/assets/config-packs/rubocop/project.yml +0 -8
  69. data/assets/config-packs/shellcheck/base.shellcheckrc +0 -14
  70. data/assets/config-packs/subtxt/ai-asciidoc-antipatterns.sub.txt +0 -11
  71. data/assets/config-packs/vale/asciidoc/ExplicitSectionIDs.yml +0 -8
  72. data/assets/config-packs/vale/asciidoc/ExtraLineBeforeLevel1.yml +0 -7
  73. data/assets/config-packs/vale/asciidoc/OneSentencePerLine.yml +0 -8
  74. data/assets/config-packs/vale/asciidoc/PreferSourceBlocks.yml +0 -8
  75. data/assets/config-packs/vale/asciidoc/ProperAdmonitions.yml +0 -8
  76. data/assets/config-packs/vale/asciidoc/ProperDLs.yml +0 -7
  77. data/assets/config-packs/vale/asciidoc/UncleanListStart.yml +0 -8
  78. data/assets/config-packs/vale/authoring/ButParagraph.yml +0 -8
  79. data/assets/config-packs/vale/authoring/ExNotEg.yml +0 -8
  80. data/assets/config-packs/vale/authoring/LiteralTerms.yml +0 -20
  81. data/assets/config-packs/vale/authoring/Spelling.yml +0 -679
  82. data/assets/config-packs/vale/base.ini +0 -38
  83. data/assets/config-packs/vale/config/scripts/ExplicitSectionIDs.tengo +0 -56
  84. data/assets/config-packs/vale/config/scripts/ExtraLineBeforeLevel1.tengo +0 -121
  85. data/assets/config-packs/vale/config/scripts/OneSentencePerLine.tengo +0 -53
  86. data/assets/config-packs/vale/project.ini +0 -5
  87. data/assets/hooks/pre-commit +0 -63
  88. data/assets/hooks/pre-push +0 -72
  89. data/assets/scripts/adoc_section_ids.rb +0 -50
  90. data/assets/scripts/build-common.sh +0 -193
  91. data/assets/scripts/build-docker.sh +0 -64
  92. data/assets/scripts/build.sh +0 -56
  93. data/assets/scripts/parse_jekyll_asciidoc_logs.rb +0 -467
  94. data/assets/templates/Gemfile +0 -7
  95. data/assets/templates/Rakefile +0 -3
  96. data/assets/templates/gitignore +0 -69
  97. data/assets/templates/jekyll-asciidoc-fix.prompt.yml +0 -17
  98. data/assets/templates/spellcheck.prompt.yml +0 -16
  99. data/docs/agent/AGENTS.md +0 -229
data/README.adoc CHANGED
@@ -1,21 +1,57 @@
1
1
  = DocOps Lab Dev Tooling
2
2
  :toc: macro
3
3
  :toclevels: 2
4
- // tag::globals[]
5
- :vale_off: pass:[<!-- vale off -->]
6
- :vale_on: pass:[<!-- vale on -->]
7
- :docopslab_hub_url: https://github.com/DocOps
8
- :docopslab_lab_hub_base_url: {docopslab_hub_url}/lab
9
- :project_manifest_path: .config/docopslab-dev.yml
10
- // end::globals[]
11
-
4
+ // tag::global-settings[]
5
+ :this_proj_slug: lab
6
+ :this_proj_name: DocOps Lab LAB
7
+ :this_prod_slug: docopslab-dev
8
+ :this_prod_path: gems/docopslab-dev
9
+ // tag::universal-settings[]
10
+ // ALL changes within this block must be made in prime template:
11
+ // DocOps/lab/gems/docopslab-dev/templates/README.asciidoc
12
+ :docopslab_src_www_url: https://github.com/DocOps
13
+ :docopslab_domain: docopslab.org
14
+ :docopslab_www_url: https://{docopslab_domain}
15
+ :docopslab_io_www_url: https://docopslab.github.io
16
+ :docopslab_ruby_version: 3.2.7
17
+ :docopslab_git_src_uri: git@github.com:DocOps
18
+ :docopslab_src_raw_url: https://raw.githubusercontent.com/DocOps
19
+ :this_proj_src_www_url: {docopslab_src_www_url}/{this_proj_slug}
20
+ :this_proj_src_raw_url: {docopslab_src_raw_url}/{this_proj_slug}
21
+ :this_proj_src_main_raw_url: {this_proj_src_raw_url}/main
22
+ :this_proj_src_main_files_url: {this_proj_src_www_url}/blob/main
23
+ :this_proj_src_git_uri: {docopslab_git_src_uri}/{this_proj_slug}.git
24
+ :this_proj_ruby_version: {docopslab_ruby_version}
25
+ // tag::env-settings[]
26
+ :docs_extn:
27
+ ifdef::env-github[]
28
+ :docs_extn: .adoc
29
+ :icons: font
30
+ :caution-caption: :fire:
31
+ :important-caption: :exclamation:
32
+ :note-caption: :paperclip:
33
+ :tip-caption: :bulb:
34
+ :warning-caption: :warning:
35
+ endif::[]
36
+ // end::env-settings[]
37
+ // Settings likely to be overridden locally
38
+ :this_prod_slug: {this_proj_slug}
39
+ :this_prod_name: {this_proj_name}
40
+ :this_prod_src_www_url: {this_proj_src_www_url}
41
+ // end::universal-settings[]
42
+ :docopslab_lab_src_www_url: {docopslab_src_www_url}/lab
43
+ :docopslab_lab_www_url: https://docopslab.org
44
+ :default_manifest_path: .config/docopslab-dev.yml
45
+ // end::global-settings[]
46
+
47
+ // tag::ai-prompt[]
12
48
  Internal development tooling for working on DocOps Lab codebases.
13
49
 
14
50
  // tag::docopsbox[]
15
51
  [IMPORTANT]
16
52
  ====
17
53
  The environment described and provided here is _not_ optimized for DocOps Lab _applications_ used in third-party projects.
18
- For your own applications of DocOps Labs products like ReleaseHx and Issuer, see link:https://github.com/DocOps/box[DocOps Box] for a full-featured docs-focused workspace, runtime, and production environment.
54
+ For your own applications of DocOps Labs products like ReleaseHx and Issuer, see link:{docopslab_lab_www_url}/projects/docops-box[DocOps Box] for a full-featured docs-focused workspace, runtime, and production environment.
19
55
  ====
20
56
  // end::docopsbox[]
21
57
 
@@ -55,6 +91,7 @@ Automated pre-commit linting and validation with interactive updates
55
91
  Docker image::
56
92
  Completely containerized docopslab-dev environment without local installation
57
93
  // end::features[]
94
+ // end::ai-prompt[]
58
95
 
59
96
 
60
97
  [[setup]]
@@ -62,7 +99,7 @@ Completely containerized docopslab-dev environment without local installation
62
99
  // tag::setup[]
63
100
  If this is _your first time using_ `docopslab-dev` on a given workstation, you will need to ensure the <<prerequisites,prerequisites>> are met.
64
101
 
65
- If you have the prerequisites and are just getting started with _a given DocOps Lab project_, you should be ready after <<init-sync>>.
102
+ If you have the prerequisites and are just getting started with _a given DocOps Lab project_, you should be ready after <<initialize-sync>>.
66
103
 
67
104
  If you are initializing `docopslab-dev` in an new project, you will also need to initialize the environment.
68
105
 
@@ -107,6 +144,11 @@ actionlint::
107
144
  * Otherwise see link:https://github.com/rhysd/actionlint/blob/v1.7.7/docs/install.md[install guide].
108
145
  * If not installed, `actionlint` operations will fallback to Docker execution
109
146
 
147
+ gh (preferred) or git::
148
+ * `brew install gh` (macOS)
149
+ * See link:https://github.com/cli/cli/blob/trunk/docs/install_linux.md[install guide] for Linux (APT, DNF, etc.)
150
+ * Used for `labdev:sync:library`; falls back to `git` if not installed
151
+
110
152
  [[setup-docker-only]]
111
153
  === Option 2: Full Docker Environment
112
154
 
@@ -129,6 +171,15 @@ Add an alias to your shell profile (`~/.bashrc`, `~/.zshrc`, etc.) to make Docke
129
171
  alias lab-dev='docker run -it --rm -v "$(pwd):/workspace" docopslab/dev'
130
172
  ----
131
173
 
174
+ For Zshell users, the `noglob` command prefix is recommended to prevent formatting issues when passing arguments to tasks.
175
+
176
+ [source,shell]
177
+ ----
178
+ alias lab-dev='noglob docker run -it --rm -v "$(pwd):/workspace" docopslab/dev'
179
+ ----
180
+
181
+ Be sure to run `source ~/.bashrc` or `source ~/.zshrc` or equivalent to instantiate the alias.
182
+
132
183
  Now `lab-dev` replaces the full Docker command and causes insertion of `bundle exec` for `rake` or `labdev:` commands.
133
184
 
134
185
  [[setup-ruby-docker]]
@@ -177,7 +228,7 @@ A project lacking any configuration files can now be initialized.
177
228
  [.prompt]
178
229
  bundle exec rake labdev:init:all
179
230
 
180
- The `init` task creates `{project_manifest_path}` and default project configs for all tools.
231
+ The `init` task creates `{default_manifest_path}` and default project configs for all tools.
181
232
  This file should be Git tracked for the project.
182
233
 
183
234
  Initialization also performs environment synchronization.
@@ -194,25 +245,55 @@ This process is part of the `init` operation, but on its own it ensures local co
194
245
  .Sync configuration files
195
246
  [.prompt]
196
247
  bundle exec rake labdev:sync:all
248
+
249
+ [[manifest-file]]
250
+ === Manifest File
251
+
252
+ // tag::manifest-intro[]
253
+ Every project using `docopslab-dev` is configured through a single manifest file at
254
+ `{default_manifest_path}` (created by `labdev:init:all` or manually).
255
+
256
+ The manifest has four top-level keys, each documented in detail in the relevant section:
257
+
258
+ `tools:`::
259
+ <<managed-tools>>: active linters and their config file mappings.
260
+
261
+ `docs:`::
262
+ <<file-syncing>> > <<technical-documentation>>: agent docs and guides to sync.
263
+
264
+ `templates:`::
265
+ <<sync-cast>>: Liquid-rendered source-to-target entries.
266
+
267
+ `library:`::
268
+ <<remote-library,Remote Asset Library>>: library source and cache settings.
269
+ // end::manifest-intro[]
270
+
197
271
  // end::setup[]
198
272
 
199
273
 
274
+ // tag::ai-prompt[]
200
275
  [[using]]
201
- == Using the Library
276
+ == Using the Tool (Rake Tasks)
202
277
  // tag::usage[]
203
278
  // tag::standard-usage[]
204
- This gem mainly supplies rake tasks for performing common development operations across unified configurations and sub-libraries.
279
+ This gem mainly supplies rake tasks for performing common development operations across and between projects.
205
280
 
206
281
  [[standard-usage]]
207
282
  === Standard Usage
208
283
 
284
+ With a proper native Ruby environment, use the `bundle exec` prefix to ensure consistent dependency versioning.
285
+
286
+ .Sync all configs and assets
287
+ [.prompt]
288
+ bundle exec rake labdev:sync:all
289
+
209
290
  .Run all linters
210
291
  [.prompt]
211
292
  bundle exec rake labdev:lint:all
212
293
 
213
294
  .Auto-fix safe issues
214
295
  [.prompt]
215
- bundle exec rake labdev:heal
296
+ bundle exec rake labdev:heal:all
216
297
 
217
298
  // end::standard-usage[]
218
299
 
@@ -227,12 +308,12 @@ Non-Ruby commands like `vale` and `shellcheck` are immediately available.
227
308
 
228
309
  .First time in a DocOps Lab project
229
310
  [.prompt]
230
- lab-dev rake labdev:sync:all
311
+ lab-dev :sync:all
231
312
 
232
313
  .Regular development workflow
233
- lab-dev rake labdev:sync:all
234
- lab-dev rake labdev:lint:all
235
- lab-dev rake labdev:heal
314
+ lab-dev :sync:all
315
+ lab-dev :lint:all
316
+ lab-dev :heal
236
317
 
237
318
  .Irregular commands
238
319
  lab-dev vale --config .config/vale.ini README.adoc
@@ -252,14 +333,14 @@ All tools use the host project's Gemfile for version consistency.
252
333
  [TIP]
253
334
  ====
254
335
  Make sure container-managed paths are not tracked in Git.
255
- Add `.config/.vendor/` and `.bundle/` to `.gitignore`.
336
+ Add `.config/.vendor/`, `scripts/.vendor`, and `.bundle/` to `.gitignore`.
256
337
  ====
257
338
  // end::usage[]
258
339
 
259
340
  See <<more-example-commands>> for additional common commands.
260
341
 
261
- [[handy-devlab-tasks]]
262
- === Handy `devlab` Tasks
342
+ [[handy-labdev-tasks]]
343
+ === Handy Tasks
263
344
 
264
345
  .Lint only for AsciiDoc syntax issues
265
346
  [.prompt]
@@ -273,23 +354,42 @@ See <<more-example-commands>> for additional common commands.
273
354
  [.prompt]
274
355
  bundle exec rake labdev:lint:docs
275
356
 
276
- .Generate a spellcheck report
357
+ .Get a Spelling report
277
358
  [.prompt]
278
359
  bundle exec rake labdev:lint:spellcheck
279
360
 
361
+ .Troubleshoot a Jekyll-AsciiDoc build
362
+ [source,shell]
363
+ # example docs gen
364
+ bundle exec jekyll build --config .config/jekyll.yml --verbose > /tmp/logs/jekyll-build.log 2>&1
365
+ # parse the logs for errors
366
+ bundle exec rake labdev:lint:logs[jekyll,/tmp/logs/jekyll-build.log]
280
367
 
281
- [[configuration]]
282
- == Configuration
368
+ .Generate a semantic index/outline of documentation source files
369
+ [.prompt]
370
+ bundle exec rake labdev:skim:adoc[.,tree,json] > .agent/docs/docs-skim.json
371
+
372
+ .Generate an index/outline of Agent-oriented Markdown files (with overlays)
373
+ [.prompt]
374
+ bundle exec rake labdev:skim:md[.agent/docs/:_docs/agent/,tree,json] > .agent/docs/agent-docs-skim.json
283
375
 
284
- The `docopslab-dev` gem itself is configured with a manifest file.
376
+ // end::ai-prompt[]
377
+
378
+
379
+ [[managed-tools]]
380
+ == Managed Tools
381
+
382
+ The `docopslab-dev` gem itself is orchestrated using a manifest file.
285
383
  This manifest declares which tools are active and their integration settings.
286
384
 
287
385
  Individual configs are maintained for all supported tools in each project codebase.
386
+ For each project implementation (application) of this coordinating gem, local configs inherit from centrally maintained "`canonical`" configs that ship with the gem.
387
+ See <<file-syncing>> for details on how the synchronization process works.
288
388
 
289
- [[manifest-configuration]]
290
- === Manifest Configuration
389
+ [[tools-manifest]]
390
+ === Tools Manifest Configuration
291
391
  // tag::manifest-config[]
292
- Initialization automatically creates `{project_manifest_path}`, which you can edit, or you can create it manually.
392
+ Initialization automatically creates `{default_manifest_path}`, which you can edit, or you can create it manually.
293
393
 
294
394
  ifndef::site-gen-jekyll[]
295
395
  See `specs/data/default-manifest.yml` for the default manifest structure.
@@ -301,104 +401,51 @@ include::specs/data/default-manifest.yml[]
301
401
  ----
302
402
  endif::[]
303
403
 
304
- [[properties-ref]]
305
- ==== Properties Reference
404
+ [[tools-manifest-properties]]
405
+ ==== Tools Properties Reference
306
406
 
307
- `tools`::
308
- (Array) List of tool configurations to enable and manage.
309
- Each entry may/must include:
407
+ The following parameters are available for each record in the `tools:` block of the manifest.
310
408
 
311
- `tool`:::
312
- (Slug) Name of the tool, ex:, `rubocop`, `vale`, `htmlproofer`, `actionlint`, `shellcheck`.
409
+ `tool`::
410
+ (Slug, *required*)
411
+ Name of the tool, ex:, `rubocop`, `vale`, `htmlproofer`, `actionlint`, `shellcheck`.
313
412
 
314
- `enabled`:::
315
- (Boolean) Whether to enable this tool's tasks and git hooks.
413
+ `enabled`::
414
+ (Boolean)
415
+ Whether to enable this tool's tasks and git hooks.
316
416
 
317
- `files`:::
318
- List of files to init or sync for the tool.
417
+ `manifest`::
418
+ (Array of Maps, *required*)
419
+ Listing of files to init or sync for the tool.
420
+ Each entry supports the following properties:
319
421
 
320
- `source`::::
321
- Path within the gem where the base config is located, e.g., `config-packs/rubocop/base.yml`.
422
+ `source`:::
423
+ (Path, *required*)
424
+ Path within the asset library where the base config is located, e.g., `config-packs/rubocop/base.yml`.
322
425
 
323
- `target`::::
426
+ `target`:::
427
+ (Path, *required*)
324
428
  Path in the project where the file should be synced, e.g., `.config/.vendor/docopslab/rubocop.yml`.
325
429
 
326
- `paths`:::
327
- Repo=specific paths to include or exclude in linting operations for this tool.
430
+ `paths`::
431
+ (Map) Repo-specific paths to include or exclude in linting operations for this tool.
328
432
 
329
- `lint`::::
433
+ `lint`:::
330
434
  (Array) List of paths or glob patterns to lint with this tool.
331
435
 
332
- `skip`::::
436
+ `skip`:::
333
437
  (Array) List of paths or glob patterns to exclude from linting with this tool.
334
438
 
335
- `exts`::::
439
+ `exts`:::
336
440
  (Array) List of file extensions to include in linting with this tool.
337
441
 
338
- `git_tracked_only`::::
442
+ `git_tracked_only`:::
339
443
  (Boolean) Whether to limit linting to only Git-tracked files.
340
444
 
341
-
342
- `docs`::
343
- (Array) List of documentation files to sync from the gem to the target project.
344
- Each entry includes:
345
-
346
- `source`:::
347
- (String) Source path relative to `lib/docopslab/` in the gem.
348
- Supports glob patterns (e.g., `docs/agent/*.md`) or specific files.
349
-
350
- `target`:::
351
- (String) Target path relative to the project root.
352
- Can be a directory (e.g., `_docs/`) or specific file path (e.g., `AGENTS.md`).
353
-
354
- `synced`:::
355
- (Boolean) Whether to update existing files on sync.
356
- +
357
- * `true` - Always overwrite on sync (keeps docs current with gem updates)
358
- * `false` - Create once, preserve user customizations
359
-
360
- [[documentation-syncing-examples]]
361
- ==== Documentation Syncing Examples
362
-
363
- .Customizable template (create once, allow modifications)
364
- [source,yaml]
365
- ----
366
- docs:
367
- - source: docs/AGENTS.md
368
- target: AGENTS.md
369
- synced: false
370
- ----
371
-
372
- .Auto-synced agent guides (keep current)
373
- [source,yaml]
374
- ----
375
- docs:
376
- - source: docs/agent/*.md
377
- target: .docopslab-dev/agent/
378
- synced: true
379
- ----
380
-
381
- .Mixed strategy (glob + specific override)
382
- [source,yaml]
383
- ----
384
- docs:
385
- - source: docs/agent/*.md
386
- target: _docs/
387
- synced: true
388
- - source: docs/agent/ruby.md
389
- target: _docs/styles/ruby-custom.md
390
- synced: false
391
- ----
392
-
393
445
  // end::manifest-config[]
394
446
 
395
- [[standardized-tooling-configs]]
396
- === Standardized Tooling Configs
397
-
398
- Configuration files follow a consistent inheritance pattern where project configs inherit from centrally managed base configs.
399
-
400
447
  [[rubocop]]
401
- ==== RuboCop
448
+ === RuboCop
402
449
  // tag::config-rubocop[]
403
450
  Ruby code style and quality checking.
404
451
 
@@ -411,7 +458,7 @@ Your project config can override any rule while maintaining consistency with the
411
458
  // end::config-rubocop[]
412
459
 
413
460
  [[vale]]
414
- ==== Vale
461
+ === Vale
415
462
  // tag::config-vale[]
416
463
  Linting for documentation quality and consistency, both AsciiDoc markup syntax and prose quality/correctness.
417
464
 
@@ -423,7 +470,7 @@ Ephemeral config:: `.config/vale.ini` (merged from base and target)
423
470
  Sync command:: `bundle exec rake labdev:sync:vale`
424
471
 
425
472
  [[vale-consumer-mode]]
426
- ===== Consumer Mode (Other Projects)
473
+ ==== Consumer Mode (Other Projects)
427
474
 
428
475
  For all other projects, the gem works in a standard package consumption mode:
429
476
 
@@ -431,33 +478,25 @@ For all other projects, the gem works in a standard package consumption mode:
431
478
  * The `labdev:sync:styles` task simply runs `vale sync` in the proper context, downloading all listed packages into a local `.vale/styles` directory.
432
479
 
433
480
  [TIP]
434
- The `labdev:sync:vale` task updates both the base config and the styles package.
481
+ The `labdev:sync:vale` task updates both the base config and the style packages.
435
482
 
436
- The `.config/vale.ini` for consumer projects (based on the gem's template) should look like this:
483
+ A project's `.config/vale.local.ini` should look something like the one for this repository (DocOps/lab).
437
484
 
485
+ .A snippet from DocOps/lab's `.config/vale.local.ini`
438
486
  [source,ini]
439
487
  ----
440
- # CONSUMER MODE CONFIG
441
-
442
- StylesPath = .vale/styles
443
-
444
- # List all packages, including the URL to the central DocOpsLabStyles package.
445
- # TODO: Update with the real URL.
446
- Packages = RedHat, proselint, write-good, https://example.com/path/to/DocOpsLabStyles.zip
447
-
448
- [*.adoc]
449
- BasedOnStyles = RedHat, DocOpsLab-Authoring, DocOpsLab-AsciiDoc
488
+ include::../../.config/vale.local.ini[tag="core-settings"]
450
489
  ----
451
490
 
452
491
  This dual-mode system provides a robust workflow for both developing and consuming the centralized Vale styles.
453
492
 
454
493
  [NOTE]
455
- For full Vale configuration settings ("`keys`") reference, see link:https://vale.sh/docs/configuration[the Vale documentation].
494
+ For full Vale configuration settings ("`keys`") reference, see the link:https://vale.sh/docs/vale-ini[official Vale documentation].
456
495
 
457
496
  // end::config-vale[]
458
497
 
459
498
  [[htmlproofer]]
460
- ==== HTMLProofer
499
+ === HTMLProofer
461
500
  // tag::config-htmlproofer[]
462
501
  HTML validation for Jekyll sites and documentation builds.
463
502
 
@@ -485,150 +524,392 @@ For full HTMLProofer configuration options, see link:https://github.com/gjtoriki
485
524
 
486
525
  // end::config-htmlproofer[]
487
526
 
488
- [[common-scripts]]
489
- === Common vs Local Scripts
490
527
 
491
- The `labdev:run:script` task exists to execute auxiliary scripting in a proper environment, simplifying the most common developer commands.
528
+ [[file-syncing]]
529
+ == File Syncing
492
530
 
493
- Upstream (centrally authored) scripts are synced to `scripts/.vendor/docopslab/` and can be executed with local override priority via `bundle exec rake 'labdev:run:script[script_name]'`.
531
+ This gem enables central/upstream authorship and maintenance of technical documentation and other flat-file content, with flexible syncing to downstream projects.
494
532
 
495
- [NOTE]
496
- There is no local configuration of or manifest control over these scripts as there is with configs.
533
+ [[sync-categories]]
534
+ === Sync Categories
535
+
536
+ [cols="1,2,2",options="header"]
537
+ |===
538
+ |Category |Manifest key |Primary task(s)
539
+
540
+ |Documentation (whole-file)
541
+ |`docs:`
542
+ |`labdev:sync:docs`
543
+
544
+ |Tool configs
545
+ |`tools:`
546
+ |`labdev:sync:configs`
547
+
548
+ |Scripts
549
+ |none
550
+ |`labdev:sync:scripts`
551
+
552
+ |Git hooks
553
+ |none
554
+ |`labdev:sync:hooks`
555
+
556
+ |Templates (Sync/Cast)
557
+ |`templates:`
558
+ |`labdev:sync:templates`
559
+ |===
560
+
561
+ Run `labdev:sync:all` to execute all sync operations in one command.
562
+
563
+ [[file-syncing-types]]
564
+ === Types of File-sync Operations
565
+
566
+ The `docopslab-dev` tool supports two main types of syncing operations, each with different use cases and behaviors.
567
+
568
+ whole-file syncing::
569
+ Maintain a local copy of centrally managed files like developer documentation, tool configs, and automation scripts.
570
+ This is the main syncing pattern.
497
571
 
498
- Local overrides are placed at `scripts/` and take precedence over upstream versions of scripts with their same filename.
572
+ <<sync-cast,template sync casting>>::
573
+ Maintain canonical sections of code or text in files that need to be partially customized but also regularly updated from a central source.
499
574
 
500
- To execute, use `bundle exec rake labdev:run:script[script_name]`, where `script_name` is `script_name.sh` or `script_name`.
501
- Use `bundle exec rake 'labdev:run:script[script_name,--option1 value --option]` to add options to the standard script execution.
575
+ stub initialization::
576
+ This is actually just an instance of casting that is not kept in sync after being written to the codebase during an `init` operation.
502
577
 
503
- To extend an upstream script, source or execute the upstream script from within the same-named local script, using its relative path.
578
+ [[file-syncing-semantics]]
579
+ === File Syncing Semantics
504
580
 
505
- Use complete script names including extensions for non-Bash scripts.
581
+ Files are kept in sync under the following categorical semantics:
506
582
 
507
- See <<assets-scripts>> for more.
583
+ documentation (`docs`)::
584
+ Whole directories of documentation files that are authored in the DocOps/lab repo and synced to projects using `rake labdev:sync:docs`.
508
585
 
509
- [[documentation-syncing]]
510
- === Documentation Syncing
586
+ tool configuration files (`configs`)::
587
+ Files tied dependency tools like Vale and RuboCop.
588
+ Synced using `rake labdev:sync:configs`.
511
589
 
512
- The gem packages agent instruction documentation that can be synced to target projects.
590
+ scripts::
591
+ All files in `scripts/.vendor/` path (`rake labdev:sync:scripts`).
513
592
 
514
- [[available-documentation]]
515
- ==== Available Documentation
593
+ Git hooks (`hooks`)::
594
+ All Git hooks from the assets library (`rake labdev:sync:hooks`).
516
595
 
517
- AGENTS.md template::
518
- A comprehensive template for creating project-specific AI agent orientation files.
519
- Includes placeholders for project details, architecture, and development patterns.
596
+ linter styles/rules (`styles`)::
597
+ Specific rulesets mapped to linters, including third-party origins.
598
+
599
+ Vale linter (`vale`)::
600
+ Includes Vale styles and config, together (`rake labdev:sync:vale`).
601
+
602
+ Liquid/casting `templates`::
603
+ Files that are rendered using Liquid syntax and/or canonical block resolution.
604
+ Uses `rake labdev:sync:templates` or `rake labdev:sync:templates[.gitignore]` for a specific file.
605
+
606
+ The command `rake labdev:sync:all` performs all syncing operations in one go.
607
+
608
+ [[whole-file-syncing]]
609
+ === Whole-file Syncing Operations
610
+
611
+ When we talk about "`whole file`" vs "`templated`" file syncing, we refer strictly to the relationship with upstream/centralized canonical sources.
612
+ Even whole-file syncing does not mean the downstream version of such files are what affects the system.
613
+
614
+ Configs can generally be merged with local settings, whereas documents and scripts tend to be replaced by local alternates.
615
+
616
+ [[technical-documentation]]
617
+ ==== Cross-project Documentation
618
+
619
+ The gem manages LLM/agent-oriented documentation that can be synced to downstream projects for local availability.
620
+ Some files and paths are highlighted here.
520
621
 
521
- Agent guides::
522
622
  Specific instruction files for AI agents working with common tools and patterns.
523
- For instance:
623
+ For instance, local paths:
524
624
 
525
- * `agent/git.md`
526
- * `agent/ruby.md`
527
- * `agent/fix-spelling-issues.md`
625
+ * `.agent/skills/git.md`
626
+ * `.agent/skills/fix-spelling-issues.md`
627
+ * `.agent/missions/conduct-release.md`
528
628
 
529
- // tag::sync-behavior[]
530
- [[sync-behavior]]
531
- ==== Sync Behavior
629
+ Such files are sourced as AsciiDoc in `DocOps/lab/_docs/agent/`, largely reusing content from people-facing docs sourced in `_docs/reference/` and `_docs/tasks/`.
532
630
 
533
- The `synced:` flag in the manifest (`{project_manifest_path}`) controls update behavior:
631
+ In most contexts, agents are instructed to check for a parallel file in the local project's `docs/` directory that would supersede the locally synced copy.
534
632
 
535
- `synced: true`::
536
- *Always updates* +
537
- File is overwritten on each sync.
538
- Use for reference documentation that should stay current with gem updates.
633
+ [[tool-configs-scripts]]
634
+ ==== Tool Configs and Scripts
539
635
 
540
- `synced: false`::
541
- *Create once, preserve customizations* +
542
- Existing files are not overwritten unless `force` is used.
543
- Use for templates that are manually customized to the local project.
636
+ Tool configs, linter styles, scripts, and Git hooks are all synced as part of `labdev:sync:all`.
637
+ Most have no per-project manifest configuration; they are sourced from the centrally managed
638
+ library and written to conventional paths.
544
639
 
545
- [TIP]
546
- Be sure to add synced files to `.gitignore` and to track all locally modified files in Git.
640
+ Configs and linter styles::
641
+ Synced by `labdev:sync:configs`, `labdev:sync:vale`, `labdev:sync:styles`, and `labdev:sync:all`, depending on intent.
642
+ +
643
+ These types of files are generally merged with existing local versions, rather than replaced, to preserve any project-specific customizations while still applying updates from the central source.
644
+
645
+ Scripts::
646
+ Synced to `scripts/.vendor/docopslab/` using `labdev:sync:scripts`.
647
+ Local overrides placed at `scripts/` take precedence over upstream versions of the same filename, though of course they can execute the upstream-sourced scripts.
648
+
649
+ Git hooks::
650
+ Synced to `.git/hooks/` with `labdev:sync:hooks`.
651
+ Git hooks do not have a merge or override system; they are either present or not.
652
+
653
+ [[sync-cast]]
654
+ === Template Sync Casting
655
+
656
+ While most `docopslab-dev` file-sync operations are standard (whole-file replacement), the concept of sync casting deserves more attention.
657
+
658
+ Template sync casting keeps project files (_targets_) up to date with upstream canonical source templates (_primes_) using the link:{docopslab_src_www_url}/asciisourcerer/#sync-cast[AsciiSourcerer::Sync::Cast] model and engine.
659
+
660
+ Casting can swap whole blocks of code, and it can render Liquid syntax, on a one-time or ongoing basis.
661
+
662
+ Liquid can be used anywhere in the source/prime template.
663
+ It will be processed during `init` operations for full rendering of the initial file.
664
+
665
+ During `sync` operations, casting will render Liquid syntax in canonical block content only.
666
+
667
+ [[sync-cast-data]]
668
+ ==== Liquid Context
669
+
670
+ While the canonical blocks are sourced right in the `source` template file, data used to render Liquid-tagged content must come from an external source.
671
+
672
+ runtime variables::
673
+ At runtime, project attributes are derived from the `README.adoc` file and made available to all templates as `{{ data.project.attributes.<attr_key_name> }}`.
674
+
675
+ manifest assignment::
676
+ Data objects (variables) can be defined in the manifest, alongside a given instance of the mapping.
677
+ These are available as `{{ data.variables.<object> }}` in the template, where `<object>` is the name of a String, Boolean, Number, Array, or Map variable type.
678
+
679
+ local/inherited assignment::
680
+ Standard Liquid variables established with `{% assign %} or `{% capture %}` tags in templates or arguments passed to Jekyll-style `{% include %}` tags.
681
+
682
+ [[sync-cast-operations]]
683
+ ==== Operations
684
+
685
+ Two operations are available:
686
+
687
+ `labdev:init:templates`::
688
+ Bootstrap new target files from their source templates.
689
+ During init, the entire source template is rendered through link:https://shopify.github.io/liquid/[Liquid] before writing, so every `{{ data.project.attributes.name }}` or `{{ data.variables.my_key }}` placeholder anywhere in the document is resolved.
690
+ Targets that already exist are skipped.
691
+
692
+ `labdev:sync:templates`::
693
+ Update canonical blocks in existing target files from the source template.
694
+ During sync, only the _content inside canonical blocks_ is rendered through Liquid.
695
+ Content outside blocks is sourced from the target, not the source template, so template syntax outside blocks is never touched.
696
+
697
+ .Bootstrap all configured targets
698
+ [.prompt]
699
+ bundle exec rake labdev:init:templates
700
+
701
+ .Sync all configured targets
702
+ [.prompt]
703
+ bundle exec rake labdev:sync:templates
704
+
705
+ .Sync a single target (by its target path)
706
+ [.prompt]
707
+ bundle exec rake 'labdev:sync:templates[AGENTS.md]'
708
+
709
+ .Preview a single target without writing
710
+ [.prompt]
711
+ bundle exec rake 'labdev:sync:templates[AGENTS.md,dry]'
712
+
713
+ The bulk sync is also included in `labdev:sync:all`.
714
+
715
+ [[file-sync-manifest]]
716
+ ==== Manifest Configuration
717
+
718
+ This reference covers the properties relevant to file syncing and sync casting in the manifest file at `{default_manifest_path}`.
719
+
720
+ // tag::manifest-config[]
721
+ The `docs:` block in the manifest is itself a manifest array.
722
+ Each entry supports the following properties:
723
+
724
+ `source`::
725
+ (Path, *required*) Source path relative to `lib/docopslab/` in the gem.
726
+ Supports glob patterns (e.g., `docs/agent/*.md`) or specific files.
727
+
728
+ `target`::
729
+ (Path, *required*) Target path relative to the project root.
730
+ Can be a directory (e.g., `_docs/`) or specific file path (e.g., `AGENTS.md`).
731
+
732
+ `synced`::
733
+ (Boolean) Whether to update existing files on sync.
734
+ +
735
+ * `true` - Always overwrite on sync (keeps docs current with gem updates)
736
+ * `false` - Create once, preserve user customizations
737
+
738
+ The `templates:` block in the manifest is a Map that nests its own `manifest:` listing as well as global data ingestion directives in `data:`.
739
+
740
+ `manifest`:::
741
+ (Array) Listing of prime templates and their downstream target files for Sync/Cast operations, optionally passing additional data.
742
+
743
+ `source`::::
744
+ (String) The path to the source template file, library relative (resolved via `labdev:sync:library`).
745
+
746
+ `target`::::
747
+ (String) The path in the project where the rendered template should be synced, relative to the project root.
748
+
749
+ `data`::::
750
+ (Map) Optional additional data to pass to the template rendering process.
751
+
752
+ `data.variables`::::
753
+ (Map) Key-value pairs of variables bearing any value type to pass to the template rendering process, accessible as `{{ data.variables.<key> }}` in templates.
754
+
755
+ // end::manifest-config[]
756
+
757
+ [[sync-cast-config]]
758
+ ==== Template Manifest Configuration
759
+
760
+ Entries are declared under the `templates.manifest:` key in `{default_manifest_path}`.
761
+ The key takes a Hash with two children: a global `data:` node and a `manifest:` list.
547
762
 
548
- .Default source, target, and syncing states for agent docs
549
763
  [source,yaml]
550
764
  ----
551
- - source: docs/agent/AGENTS.md
552
- target: AGENTS.md
553
- synced: false
554
- - source: docs/agent/*.md
555
- target: .agent/
556
- synced: true
765
+ templates:
766
+ data: # Global data available to all entries
767
+ variables:
768
+ project_name: "My Project"
769
+ manifest:
770
+ - source: templates/AGENTS.markdown # Library-relative source template path
771
+ target: AGENTS.md # Project-local target path
772
+ - source: templates/custom.adoc
773
+ target: docs/custom.adoc
774
+ data: # Per-entry overrides, merged on top of global
775
+ variables:
776
+ extra_key: "value"
557
777
  ----
558
778
 
559
- // end::sync-behavior[]
779
+ For a full property reference, see the comments in `specs/data/default-manifest.yml` in the gem source.
560
780
 
561
- [[target-path-selection]]
562
- ==== Target Path Selection
781
+ [[sync-cast-liquid]]
782
+ ==== Liquid Template Context
563
783
 
564
- Documentation can be synced to different locations based on project structure:
784
+ All Liquid variables are scoped under the top-level `data` key:
565
785
 
566
- .To project root
567
- [source,yaml]
786
+ `data.project.attributes.<key>`::
787
+ Document attributes loaded from the project's `README.adoc` header.
788
+ Asciidoctor built-in attributes are filtered out; only user-defined string attributes are available.
789
+
790
+ `data.variables.<key>`::
791
+ Merged from global `data.variables` and the per-entry `data.variables` override.
792
+ Per-entry values take precedence.
793
+
794
+ [source,liquid]
568
795
  ----
569
- - source: docs/AGENTS.md
570
- target: AGENTS.md
796
+ {{ data.project.attributes.this_proj_name }}
797
+ {{ data.variables.description }}
571
798
  ----
572
799
 
573
- .To existing `_docs/` directory
574
- [source,yaml]
800
+ [TIP]
801
+ ====
802
+ During `init`, Liquid is rendered across the entire source template, so all `{{ data.* }}` references anywhere in the file are resolved.
803
+ During `sync`, only the content _inside_ canonical blocks is rendered; template syntax outside blocks is intentional scaffolding and will never be evaluated.
804
+ ====
805
+
806
+ [[sync-cast-block-syntax]]
807
+ ==== Block Syntax
808
+
809
+ Canonical blocks use the same AsciiDoc tag syntax as the rest of the DocOps Lab toolchain, wrapped in file-appropriate comments.
810
+
811
+ .AsciiDoc / Markdown (HTML comment wrapper)
812
+ [source,html]
575
813
  ----
576
- - source: docs/agent/*.md
577
- target: _docs/agent/
814
+ <!-- tag::example-text[] -->
815
+ This content is managed in the source template.
816
+ <!-- end::example-text[] -->
578
817
  ----
579
818
 
580
- .To vendor path (if no `_docs/`)
581
- [source,yaml]
819
+ .AsciiDoc (native comment)
820
+ [source,asciidoc]
582
821
  ----
583
- - source: docs/agent/*.md
584
- target: .docopslab-dev/agent/
822
+ // tag::example-source[]
823
+ This content is managed in the prime template.
824
+ // end::example-source[]
585
825
  ----
586
826
 
587
- [[pattern-matching]]
588
- ==== Pattern Matching
827
+ The `canonical_prefix:` setting controls which tagged blocks are treated as canonical.
828
+ By default this is `universal-`.
829
+ A target may contain alternate-prefixed blocks (e.g. `local-agency`) as a cue to the engine that a canonical block has been intentionally replaced; no warning is emitted for those.
589
830
 
590
- Glob patterns allow bulk operations:
831
+ [[sync-cast-init-target-workflow]]
832
+ ==== Typical Workflow
833
+
834
+ The expected workflow for a new project:
835
+
836
+ . Register the entry in `{default_manifest_path}` under `templates.manifest`.
837
+ . Run `labdev:init:templates` to bootstrap the target file.
838
+ . Customize the project-specific sections (outside canonical blocks).
839
+ . As the source template evolves upstream, run `labdev:sync:templates` to pull in updated canonical blocks without disturbing local content.
840
+
841
+
842
+ [[remote-library]]
843
+ == Remote Asset Library
844
+
845
+ The `docopslab-dev` fetches a centrally managed asset library from the `labdev-library` branch of `DocOps/lab` and caches it host-wide at `~/.cache/docopslab/dev/library/`.
846
+ This enables updates per-project updates to config packs, templates, docs, hooks, and scripts without needing to update the gem package or re-download the remote library.
847
+
848
+ [[library-cache-layout]]
849
+ === Cache Layout
850
+
851
+ The library cache lives at `~/.cache/docopslab/dev/library/` (or under `$XDG_CACHE_HOME/docopslab/dev/library/` if that variable is set):
591
852
 
592
- .All markdown files
593
- [source,yaml]
594
853
  ----
595
- - source: docs/agent/*.md
596
- target: _docs/
597
- synced: true
854
+ ~/.cache/docopslab/dev/library/
855
+ current/ # Active snapshot used by sync and resolve operations
856
+ catalog.json # Catalog with version, ref, and checksums
857
+ config-packs/
858
+ docs/
859
+ hooks/
860
+ scripts/
861
+ templates/
862
+ previous/ # Prior snapshot retained for fast rollback
598
863
  ----
599
864
 
600
- .Specific file override
865
+ Updates are _never automatic_.
866
+ Run `labdev:sync:library` explicitly to pull a new snapshot.
867
+ The prior snapshot is preserved as `previous/` so a broken update can be rolled back immediately.
868
+
869
+ On first use, sync operations auto-fetch the library if no cache exists.
870
+
871
+ [[library-configuration]]
872
+ === Library Configuration
873
+
874
+ Add a `library:` block to `.config/docopslab-dev.yml` to configure the source.
875
+ All fields are optional; defaults target the `labdev-library` branch of `DocOps/lab`.
876
+
601
877
  [source,yaml]
602
878
  ----
603
- - source: docs/agent/ruby.md
604
- target: _docs/styles/ruby-custom.md
605
- synced: false
606
- - source: docs/agent/*.md
607
- target: _docs/
608
- synced: true
879
+ library:
880
+ enabled: true
881
+ source:
882
+ type: git-branch
883
+ repo: DocOps/lab
884
+ ref: labdev-library
885
+ path: library
886
+ sync:
887
+ mode: latest-only
888
+ cache_root: ~/.cache/docopslab/dev/library
889
+ # Optional: local fallback path when XDG cache is absent.
890
+ # Populated by `bundle exec rake gemdo:push:library:stage` in DocOps/lab.
891
+ local_path: .library
609
892
  ----
610
893
 
611
- Result: Most files auto-sync to `_docs/`, but `ruby.md` also copied to custom path and preserved.
612
-
613
- [[syncing-documentation]]
614
- ==== Syncing Documentation
894
+ [[library-tasks]]
895
+ === Library Tasks (Consumer Projects)
615
896
 
616
- Your docs are probably already initialized as part of the basic `labdev:init` task, but if you _only_ want the docs, there's a task for that.
617
-
618
- .Initialize the docsets
897
+ .Fetch and cache the latest remote library
619
898
  [.prompt]
620
- bundle exec rake labdev:init:docs
621
-
622
- Docs will be kept in sync by the general `labdev:sync` command, but you may always update the docs alone.
899
+ bundle exec rake labdev:sync:library
623
900
 
624
- .Sync docs explicitly (respects `synced:` flags)
901
+ .Show current library cache status and version
625
902
  [.prompt]
626
- bundle exec rake labdev:sync:docs
903
+ bundle exec rake labdev:show:library
904
+
905
+ [NOTE]
906
+ The fetch tasks require either the `gh` CLI or `git` to be available on your `PATH`.
907
+ The `gh` CLI is preferred and will be used when present.
627
908
 
628
909
 
629
910
  // tag::workflow[]
630
- [[available-tasks]]
631
- == Tasks and Workflow
911
+ [[task-reference]]
912
+ == Task Reference
632
913
 
633
914
  [.prompt]
634
915
  bundle exec rake --tasks | grep labdev:
@@ -655,7 +936,7 @@ This should yield warnings and errors if active linters find issues.
655
936
 
656
937
  . Auto-fix what you can.
657
938
  +
658
- bundle exec rake labdev:heal
939
+ bundle exec rake labdev:heal:all
659
940
 
660
941
  . Review the changes.
661
942
  +
@@ -689,6 +970,30 @@ Bypass the pre-push gates (usually to test or demo the failure at origin):
689
970
  git push --no-verify
690
971
  ====
691
972
 
973
+ // tag::usage[]
974
+ // tag::standard-usage[]
975
+ [[override-commands]]
976
+ === Override Commands
977
+
978
+ Most executions of the packaged tools are handled through Rake tasks, but you can always run them directly, especially to pass arguments not built into the tasks.
979
+
980
+ RuboCop::
981
+ +
982
+ bundle exec rubocop --config .config/rubocop.yml [options]
983
+ bundle exec rubocop --config .config/rubocop.yml --auto-correct-all
984
+ bundle exec rubocop --config .config/rubocop.yml --only Style/StringLiterals
985
+
986
+ Vale::
987
+ +
988
+ vale --config=.config/vale.ini [options] [files]
989
+ vale --config=.config/vale.ini README.adoc
990
+ vale --config=.config/vale.ini --minAlertLevel=error .
991
+
992
+ HTMLProofer::
993
+ +
994
+ bundle exec htmlproofer --ignore-urls "/www.github.com/,/foo.com/" ./_site
995
+ // end::standard-usage[]
996
+ // end::usage[]
692
997
  // end::workflow[]
693
998
 
694
999
 
@@ -698,7 +1003,7 @@ Bypass the pre-push gates (usually to test or demo the failure at origin):
698
1003
 
699
1004
  Override settings by editing the project configs:
700
1005
 
701
- * `{project_manifest_path}`
1006
+ * `{default_manifest_path}`
702
1007
  * `.config/rubocop.yml`
703
1008
  * `.config/vale.ini`
704
1009
  * `.config/htmlproofer.yml`
@@ -714,7 +1019,7 @@ Projects using `docopslab-dev` will have a configuration structure like the foll
714
1019
 
715
1020
  [source,tree]
716
1021
  ----
717
- config/
1022
+ .config/
718
1023
  ├── docopslab-dev.yml # Project manifest (tracked)
719
1024
  ├── actionlint.yml # Project config (tracked; inherits from base)
720
1025
  ├── htmlproofer.local.yml # Project config (tracked; inherits from base)
@@ -736,129 +1041,90 @@ env.private # Environment variables (git ignored)
736
1041
  ----
737
1042
  // end::customization[]
738
1043
 
739
- // tag::usage[]
740
- // tag::standard-usage[]
741
- [[override-commands]]
742
- === Override Commands
743
-
744
- Most executions of the packaged tools are handled through Rake tasks, but you can always run them directly, especially to pass arguments not built into the tasks.
745
-
746
- RuboCop::
747
- +
748
- bundle exec rubocop --config .config/rubocop.yml [options]
749
- bundle exec rubocop --config .config/rubocop.yml --auto-correct-all
750
- bundle exec rubocop --config .config/rubocop.yml --only Style/StringLiterals
751
-
752
- Vale::
753
- +
754
- vale --config=.config/vale.ini [options] [files]
755
- vale --config=.config/vale.ini README.adoc
756
- vale --config=.config/vale.ini --minAlertLevel=error .
757
-
758
- HTMLProofer::
759
- +
760
- bundle exec htmlproofer --ignore-urls "/www.github.com/,/foo.com/" ./_site
761
-
762
- [[more-example-commands]]
763
- === More Example Commands
764
1044
 
765
- .Lint specific Ruby file with specific rule
766
- [.prompt]
767
- bundle exec rake 'labdev:lint:ruby[lib/myfile.rb,Style/StringLiterals]'
768
-
769
- .Lint all AsciiDoc files for a specific Vale rule
770
- [.prompt]
771
- bundle exec rake 'labdev:lint:adoc[,DocOpsLab-Authoring.ExNotEg]'
772
-
773
- .Lint specific shell script
774
- [.prompt]
775
- bundle exec rake 'labdev:lint:bash[scripts/docksh]'
776
-
777
- .Lint specific file with Vale (text mode)
778
- [.prompt]
779
- bundle exec rake 'labdev:lint:text[_docs/myfile.adoc]'
1045
+ [[development]]
1046
+ == Development
780
1047
 
781
- .Show a specific lint rule profile
782
- [.prompt]
783
- bundle exec rake 'labdev:show:rule[vale,RedHat]'
1048
+ This gem is developed within the link:{docopslab_lab_src_www_url}[DocOps Lab monorepo] at `/gems/docopslab-dev/`.
784
1049
 
785
- // end::standard-usage[]
786
- // end::usage[]
1050
+ This section pertains to working _on_ the `docopslab-dev` tool, rather than working _with_ it.
787
1051
 
1052
+ [[strategy]]
1053
+ === Strategy and Aims
788
1054
 
789
- [[assets]]
790
- == Other Assets
1055
+ In addition to centralized configuration, script, docs, and hooks management, the gem aims to cover:
791
1056
 
792
- Linters are the main feature of this gem, but it also handles other shared assets.
1057
+ * Central documentation build tooling (probably to spin off as `docopslab-docs` gem)
1058
+ * RSpec test framework management and templates
1059
+ * Security analysis (Brakeman, Bundler Audit)
1060
+ * Dependency management (Dependabot)
1061
+ * More CI/CD workflow templates
1062
+ * Generative AI agent templates and MCP infrastructure
1063
+ * Linting of SGYML YAML files
1064
+ * Linting of AsciiDoc/Markdown content stored in YAML files
793
1065
 
794
- [[assets-scripts]]
795
- === Managed Scripts
1066
+ Contributions in these directions are welcome.
796
1067
 
797
- .List available scripts
798
- [.prompt]
799
- bundle exec rake labdev:show:scripts
1068
+ [[making-changes]]
1069
+ === Making Changes
800
1070
 
801
- Unlike other `labdev:run` tasks, `labdev:run:script` requires a `script_name` of an existing local or an upstream-sourced script stored in the `scripts/.vendor/` path and maintained as part of the link:{docopslab_lab_hub_base_url}[DocOps/lab project].
1071
+ There are two types of changes
802
1072
 
803
- They are superseded by a script of the same name in the local `scripts/` directory, if present.
804
- (See >><common-scripts>> for more.)
1073
+ . Edit files in `lib/` or `assets/`.
1074
+ . Test with lab repo as consumer.
805
1075
 
806
- [[git-hooks]]
807
- === Git Hooks
1076
+ For changes to docs or assets:
808
1077
 
809
- The gem provides git hooks with a developer-oriented strategy:
1078
+ [start=3]
1079
+ . Run linters on any scripts or content added.
1080
+ . Publish independently using the base repo's Rake tasks (`rake gemdo:push:library`).
810
1081
 
811
- *Pre-commit* (Advisory):
1082
+ For changes to functionality in `lib/docopslab/dev/`:
812
1083
 
813
- * Quick syntax validation on staged files
814
- * Config sync status check
815
- * Non-blocking - encourages frequent commits
1084
+ [start=3]
1085
+ . Add or update RSpec tests in `spec/` and ensure they pass.
1086
+ . Update version in `lib/docopslab/dev/version.rb`.
1087
+ . Run linters on any Ruby and docs changes.
1088
+ . Update this `README.adoc` with new features or changed functionality.
816
1089
 
817
- *Pre-push* (Quality Gate):
1090
+ [[asset-resolution-policy]]
1091
+ === Asset Resolution Policy
818
1092
 
819
- * Comprehensive linting with `labdev:lint:all`
820
- * Blocks problematic code from reaching CI
821
- * Provides clear fix workflow instructions
1093
+ To ensure that AI agents and tools have reliable access to resources while allowing for project-specific overrides, `docopslab-dev` follows a **local-first** resolution policy for most assets.
822
1094
 
823
- .Show hook status
824
- [.prompt]
825
- bundle exec rake labdev:show:hooks
1095
+ [[prompt-templates]]
1096
+ ==== Prompt Templates
826
1097
 
827
- .Install/update hooks
828
- [.prompt]
829
- bundle exec rake labdev:sync:hooks
1098
+ Downstream scripts (like the Jekyll-AsciiDoc log parser) resolve prompt templates using the following order:
830
1099
 
831
- Bypass (extraordinary use): `git push --no-verify`
1100
+ . **Local Project Override**: `.config/prompts/<filename>` (Git-tracked or user-defined).
1101
+ . **Upstream Library Fallback**: `templates/<filename>` inside the host-wide library cache (e.g., `~/.cache/docopslab/dev/library/current/templates/`).
832
1102
 
1103
+ This pattern ensures that a project can always "pin" or customize its agent interactions locally without breaking the default provided by the toolchain.
833
1104
 
834
- [[development]]
835
- == Development
1105
+ [[config-scripts]]
1106
+ ==== Configuration and Scripts
836
1107
 
837
- This gem is developed within the link:{docopslab_lab_hub_base_url}[DocOps Lab monorepo] at `/gems/docopslab-dev/`.
1108
+ Scripts::
1109
+ The `labdev:run:scripts` task searches `scripts/` (local) before `scripts/.vendor/docopslab/` (synced).
838
1110
 
839
- [[strategy]]
840
- === Strategy and Aims
1111
+ Configs::
1112
+ Linter configurations are generally merged, with the local `.config/` version taking precedence over the bundled vendor versions.
841
1113
 
842
- In addition to centralized configuration, script, docs, and hooks management, the gem aims to cover:
1114
+ [[submodule-api-pattern]]
1115
+ === Submodule API Pattern
843
1116
 
844
- * Central documentation build tooling (probably to spin off as `docopslab-docs` gem)
845
- * RSpec test framework management and templates
846
- * Security analysis (Brakeman, Bundler Audit)
847
- * Dependency management (Dependabot)
848
- * More CI/CD workflow templates
849
- * Generative AI agent templates and MCP infrastructure
850
- * Linting of SGYML YAML files
851
- * Linting of AsciiDoc/Markdown content stored in YAML files
852
-
853
- Contributions in these directions are welcome.
1117
+ Each feature area lives in its own submodule under `DocOpsLab::Dev` (e.g., `Library`, `SyncOps`, `ConfigManager`).
1118
+ New public methods must be exposed on the submodule directly:
854
1119
 
855
- [[making-changes]]
856
- === Making Changes
1120
+ [source,ruby]
1121
+ ----
1122
+ DocOpsLab::Dev::Library.fetch!
1123
+ DocOpsLab::Dev::Library.resolve('templates/README.asciidoc')
1124
+ ----
857
1125
 
858
- . Edit files in `lib/`, `config-packs/`, or `hooks/`.
859
- . Test with lab repo as consumer.
860
- . Update version in `lib/docopslab/dev/version.rb`.
861
- . Update this README with new features.
1126
+ The top-level `DocOpsLab::Dev` class surface (`Dev.library_fetch!`, etc.) is a backward-compatibility layer only and should not receive new methods.
1127
+ Callers consuming library features from Rake tasks or other modules should reference the submodule path, not the `Dev` facade.
862
1128
 
863
1129
  [[vale-dev-mode]]
864
1130
  === Running Vale in Development Mode
@@ -869,12 +1135,7 @@ When running within the `DocOps/lab` monorepo, the `labdev:sync:styles` task ope
869
1135
  * It also runs `vale sync` to download any remote packages like `RedHat` or `proselint` into that same directory.
870
1136
  * This allows you to edit the custom styles in the gem and see your changes immediately when you run the linter.
871
1137
 
872
- The `.config/vale.ini` for this mode should use the project's local defaults for `.config/vale.local.ini`.:
873
-
874
- [[implementation]]
875
- === Implementation Notes
876
-
877
-
1138
+ The `.config/vale.ini` for this mode should use the project's local defaults for `.config/vale.local.ini`.
878
1139
 
879
1140
  [[build-artifacts]]
880
1141
  === Building docopslab-dev Artifacts
@@ -889,6 +1150,72 @@ To build the `docopslab/dev` Docker image:
889
1150
  [.prompt]
890
1151
  bundle exec rake gemdo:build_docker
891
1152
 
1153
+ [[publish-artifacts]]
1154
+ === Publish & Deploy Artifacts
1155
+
1156
+ For general DocOps Lab release procedures, see link:{xref_docs_release_url}[Release Process (General)].
1157
+
1158
+ The `docopslab-dev` gem and `docopslab/dev` Docker image follow that process with these specific considerations:
1159
+
1160
+ [NOTE]
1161
+ To *publish the _assets_ library*, see link:{docopslab_lab_src_www_url}#library-publish[the main DocOps/lab README].
1162
+
1163
+ [[publishing-requirements]]
1164
+ ==== Publishing Requirements
1165
+
1166
+ [%interactive]
1167
+ - [ ] RubyGems.org account with MFA enabled
1168
+ - [ ] Docker Hub account with push access to `docopslab` organization
1169
+ - [ ] Clean local build environment (no uncommitted changes)
1170
+ - [ ] All tests passing (`bundle exec rspec`)
1171
+ - [ ] Version bumped in `lib/docopslab/dev/version.rb`
1172
+ - [ ] Agent documentation generated (`bundle exec rake gemdo:generate_agent_docs`)
1173
+
1174
+ [[publish-gem]]
1175
+ ==== Publishing the Gem
1176
+
1177
+ Build and publish to RubyGems.org:
1178
+
1179
+ cd gems/docopslab-dev
1180
+ bundle exec rake build
1181
+ gem push pkg/docopslab-dev-<version>.gem
1182
+
1183
+ RubyGems.org will prompt for MFA code during push.
1184
+ You must have valid authentication for an account with permissions to publish this gem.
1185
+
1186
+ [[publishing-the-docker-image]]
1187
+ ==== Publishing the Docker Image
1188
+
1189
+ Build and push to Docker Hub:
1190
+
1191
+ cd gems/docopslab-dev
1192
+ docker build -t docopslab/dev:<version> -t docopslab/dev:latest .
1193
+ docker push docopslab/dev:<version>
1194
+ docker push docopslab/dev:latest
1195
+
1196
+ Both version-specific and `:latest` tags should be published.
1197
+
1198
+ [[testing-published-artifacts]]
1199
+ ==== Testing Published Artifacts
1200
+
1201
+ Verify the gem installation from RubyGems.org:
1202
+
1203
+ gem install docopslab-dev
1204
+ lab-dev --version
1205
+
1206
+ Verify the Docker image from Docker Hub:
1207
+
1208
+ docker pull docopslab/dev:latest
1209
+ docker run --rm docopslab/dev:latest lab-dev --version
1210
+
1211
+ Test in a fresh project directory to ensure all dependencies install correctly:
1212
+
1213
+ mkdir /tmp/test-lab-dev
1214
+ cd /tmp/test-lab-dev
1215
+ echo 'source "https://rubygems.org"' > Gemfile
1216
+ echo 'gem "subtxt"' >> Gemfile
1217
+ docker run --rm -v "$PWD:/workspace" -w /workspace docopslab/dev:latest bundle exec subtxt --help
1218
+
892
1219
 
893
1220
  [[legal]]
894
1221
  == Legal