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