From jtbd-tools
Extracts JTBD records from OpenShift docs repos using _topic_map.yml structure. Parses topic maps for books/assemblies, reduces AsciiDoc assemblies, runs analysis.
npx claudepluginhub redhat-documentation/redhat-docs-agent-tools --plugin jtbd-toolsThis skill is limited to using the following tools:
Extract Jobs-To-Be-Done records from OpenShift documentation repositories that use `_topic_maps/_topic_map.yml` to define book structure, rather than a `master.adoc` entry point.
Runs end-to-end JTBD workflow on topic map-based repos like OpenShift docs: analyzes maps, generates TOCs, compares structures, consolidates reports. Batch processes multiple books.
Assesses CQA P2-P7 modularization in Red Hat AsciiDoc docs: assembly structure without rendered text between includes, module prefixes, templates, required elements, nesting depth.
Generates structured Markdown task briefs at docs/briefs/ from notes or descriptions, with sections keyed to Conventional Commits types to guide coding agents (e.g., refactor preserves, fix reproduces). Briefset mode creates parent plus child briefs for multi-context tasks.
Share bugs, ideas, or general feedback.
Extract Jobs-To-Be-Done records from OpenShift documentation repositories that use _topic_maps/_topic_map.yml to define book structure, rather than a master.adoc entry point.
# List available books for a distro
/jtbd-analyze-topicmap path/to/repo --list-books --distro openshift-gitops
# Analyze a specific book
/jtbd-analyze-topicmap path/to/repo --book installing_gitops
# Analyze with distro filter
/jtbd-analyze-topicmap path/to/repo --book installing_gitops --distro openshift-gitops
# Custom output location
/jtbd-analyze-topicmap path/to/repo --book installing_gitops --output analysis/gitops/installing_gitops/
_topic_maps/_topic_map.yml--list-books): Book directory name (e.g., installing_gitops)openshift-gitops)analysis/<distro>/<book>/ (or analysis/topicmap/<book>/ if no distro specified)asciidoctor-reducer must be installed:
gem install asciidoctor-reducer
If Ruby/gem is not available:
brew install ruby # macOS
The target repo must have _topic_maps/_topic_map.yml
_topic_maps/_topic_map.yml in the repo root--- document separators (multi-document YAML)Name, Dir, Distros, Topics--distro is specified, filter to books whose Distros field contains that distro--list-books, display the book list in a table and stopThe _topic_map.yml uses multi-document YAML (documents separated by ---). Each document represents one book:
---
Name: Installing GitOps # Book display name
Dir: installing_gitops # Directory containing assemblies
Distros: openshift-gitops # Comma-separated distro list
Topics: # Ordered list of topics
- Name: Preparing to install # Topic display name
File: preparing-gitops-install # Assembly filename (without .adoc)
- Name: Nested section # Sub-topic group
Dir: sub_directory # Subdirectory within book dir
Topics: # Nested topics
- Name: Sub-topic
File: sub-topic-file
--- document = one bookDistros can be a single string or comma-separated (e.g., openshift-enterprise,openshift-origin)Dir and TopicsName + Topics (section grouping, no file) or Name + File (leaf topic pointing to an assembly)<repo-root>/<book-Dir>/<File>.adoc or <repo-root>/<book-Dir>/<sub-Dir>/<File>.adoc for nested topicsUse the Bash tool to read the YAML file, then parse it in your response. Since Claude Code doesn't have a YAML library, follow this approach:
--- (YAML document separator)Name: line -> book nameDir: line -> book directoryDistros: line -> distro filter stringTopics: block -> list of topic entriesName:, File:, and optional nested Dir: + Topics:File references with their resolved pathsDir field matches --bookTopics list recursively (topics can have nested sub-topics with their own Dir)File field, resolve the full path:
<repo-root>/<book-Dir>/<File>.adocDir: <repo-root>/<book-Dir>/<nested-Dir>/<File>.adocCRITICAL: Working Directory
asciidoctor-reducer must run from the book directory (e.g., installing_gitops/), NOT the repo root. This is because each book directory contains symlinks that the reducer needs to resolve includes:
installing_gitops/
├── _attributes -> ../_attributes/
├── modules -> ../modules/
├── images -> ../images/
├── snippets -> ../snippets/
└── *.adoc
The reducer resolves include:: paths relative to the file being processed. Since assemblies use include::modules/..., the modules/ symlink in the book directory must be resolvable.
Verify asciidoctor-reducer is available:
which asciidoctor-reducer
If not found, tell the user to install it and stop.
Create the output directory if it doesn't exist
For each assembly .adoc file:
cd <repo-root>/<book-Dir> && asciidoctor-reducer <file>.adoc -o <output-dir>/<file>-reduced.adoc
For nested topics with a subdirectory:
cd <repo-root>/<book-Dir> && asciidoctor-reducer <sub-Dir>/<file>.adoc -o <output-dir>/<file>-reduced.adoc
Verify reduction succeeded by checking the output file exists and has no remaining include:: directives:
grep -c "^include::" <output-dir>/<file>-reduced.adoc
(Should return 0 or only have false positives in code blocks)
= <Topic Name> (using the Name from the topic map)<output-dir>/<book>-combined.adocinclude:: directives from the ORIGINAL (unreduced) assembly to build the include graphassembly: the assembly filenamemodule: the included module pathtype: module type based on naming convention (con-, proc-, ref-, snip-)leveloffset: the level offset from the include directive<output-dir>/<book>-include-graph.json{
"book": "installing_gitops",
"book_name": "Installing GitOps",
"assemblies": [
{
"file": "preparing-gitops-install.adoc",
"topic_name": "Preparing to install OpenShift GitOps",
"includes": [
{
"module": "modules/gitops-preparing-install.adoc",
"type": "CONCEPT",
"leveloffset": "+1"
}
]
}
]
}
Red Hat modular docs follow naming conventions for module files:
con-*.adoc or filename contains con- = CONCEPT (explanatory content)proc-*.adoc or filename contains proc- = PROCEDURE (step-by-step instructions)ref-*.adoc or filename contains ref- = REFERENCE (tables, lists, specifications)snip-*.adoc or filename contains snip- = SNIPPET (reusable fragments)= Level 1 (Document/Book Title)
== Level 2 (Chapter)
=== Level 3 (Section)
==== Level 4 (Subsection)
| Combined File Size | Strategy |
|---|---|
| < 500 lines | Single pass processing |
| >= 500 lines | Chunked subagent processing |
For small combined files:
methodology.md)For large combined files:
Task(subagent_type="general-purpose", prompt=chunk_analysis_prompt)
The chunk prompt must include:
methodology.mdschema.mdAfter JTBD extraction, enrich each record:
section field to a section in the combined fileevidence field to include:
notes field to include:
Example enriched record:
{
"evidence": "installing_gitops-combined.adoc -> Section 'Installing OpenShift GitOps', lines 45-120 [module: modules/gitops-proc-installing.adoc, type: PROCEDURE]",
"notes": "Source module: modules/gitops-proc-installing.adoc (PROCEDURE). Assembly: installing-openshift-gitops.adoc"
}
Unless --skip-validation is passed, run the grounding validation described in methodology.md Step 9:
evidence field to extract the source file, section heading, and line rangesection field matches an actual heading in the combined file (mechanical check)validation_status and validation_flags on each recordProcessing strategy:
Save all outputs to <output-dir>/:
<book>-jtbd.jsonl — JTBD records, one JSON object per line<book>-jtbd.csv — CSV version with the same records (for spreadsheet use)
doc,section,job_statement,job_type,persona,job_map_stage,granularity,parent_job,prerequisites,related_jobs,desired_outcomes,evidence,notes; <book>-include-graph.json — Include graph for all assemblies<book>-topicmap.json — Extracted topic map structure for this book:
{
"name": "Installing GitOps",
"dir": "installing_gitops",
"distros": "openshift-gitops",
"topics": [
{"name": "Preparing to install", "file": "preparing-gitops-install"},
{"name": "Installing OpenShift GitOps", "file": "installing-openshift-gitops"}
]
}
<file>-reduced.adoc files — Reduced assemblies<book>-combined.adoc — Concatenated reduced contentIf --output is not specified:
--distro: analysis/<distro>/<book>/--distro: analysis/topicmap/<book>/The doc field in JTBD records should be set to <book>-combined.adoc (the concatenated file name).
When using chunked processing, each subagent receives this prompt:
You are analyzing a section of the book "<Book Name>" from the <distro> documentation.
## Your Task
Extract Jobs-To-Be-Done (JTBD) records from the following AsciiDoc content.
## Methodology
<contents of [`methodology.md`](../../reference/methodology.md)>
## Record Schema
<contents of [`schema.md`](../../reference/schema.md)>
## Document Info
- doc: <book>-combined.adoc
- Book: <Book Name>
- Sections covered: <list of section headings in this chunk>
## Content to Analyze
<chunk content>
## Output Format
Output ONLY valid JSONL — one JSON object per line, no markdown fencing, no commentary.
Each record must conform to the schema above.
Set the `doc` field to "<book>-combined.adoc" for all records.
When grouping sections into chunks:
= Title (level 1) heading from the topic-map-inserted headings marks a new assembly boundary= Title headings together# Step 1: List books to find what's available
/jtbd-analyze-topicmap ~/openshift-docs --list-books --distro openshift-gitops
# Step 2: Analyze a book
/jtbd-analyze-topicmap ~/openshift-docs --book installing_gitops --distro openshift-gitops
# Step 3: Review results
cat analysis/openshift-gitops/installing_gitops/installing_gitops-jtbd.jsonl
# Step 4: Check include graph
cat analysis/openshift-gitops/installing_gitops/installing_gitops-include-graph.json
# Step 5: Generate TOC from records
/jtbd-toc analysis/openshift-gitops/installing_gitops/
# Step 6: Compare with current structure
/jtbd-compare --source analysis/openshift-gitops/installing_gitops/
include:: directives)= Topic Name headings between assembliesno_evidence records (evidence citations resolve to real content)The complete JTBD extraction methodology is shared with /jtbd-analyze and /jtbd-analyze-adoc:
methodology.md for extraction rulesschema.md for record schema