| name | review-docs |
| description | Review documentation files for grammar, factual accuracy, and query correctness. Use when the user asks to review docs, validate documentation, or check YQL examples. Accepts a path to a file or directory as argument. |
| user-invocable | true |
Review documentation files for grammar, factual accuracy, and query correctness.
The user will provide a path to a single document or a folder containing documents.
Use $ARGUMENTS as the target path. If no argument is provided, ask the user for the path.
Scope
This command reviews Markdown documentation files (.md) covering:
- Grammar and style — punctuation, spelling, word choice, hyphenation, sentence structure
- Factual claims — verify statements about database behavior against the actual codebase
- Query correctness — validate all YQL/SQL code examples by executing them on a real in-memory database
- Internal consistency — cross-reference links, terminology, and naming conventions within and across documents
- Code example formatting — verify code blocks have correct language tags, consistent style
Workflow
Step 1: Discover target files
- If
$ARGUMENTS points to a single .md file, review that file.
- If
$ARGUMENTS points to a directory, discover all .md files in it recursively using Glob.
- Read each file and build a review queue.
Step 2: Grammar and style review (per file)
For each document, check for:
- Punctuation: missing commas after introductory phrases ("For this reason,"), before conjunctions in compound sentences, around parenthetical clauses.
- Spelling: typos, common misspellings (e.g., "straight forward" -> "straightforward").
- Hyphenation: compound adjectives before nouns need hyphens (e.g., "case-insensitive", "not-indexed").
- Word choice: awkward phrasing (e.g., "suggest to use" -> "suggest using", "look to" -> "refer to").
- Consistency: same terms spelled/capitalized the same way throughout. Check
YouTrackDB, YQL, class names, etc.
- Formatting: extra spaces before colons/punctuation, double spaces, inconsistent heading levels.
- Code block language tags: ensure
```sql, ```java, etc. are present and correct.
Produce a table of findings per file: line number, issue, suggested fix.
Step 3: Link and reference validation (per file)
- Extract all Markdown links
[text](target) and anchor links [text](#anchor).
- For file links (e.g.,
YQL-Where.md), check if the referenced file exists relative to the document using Glob. Report missing files but do not block the review — flag them as warnings.
- For anchor links, check if the referenced heading exists in the target file.
- Check for inconsistent link targets (e.g., a file linked as both
SQL-Syntax.md and YQL-Syntax.md when only one exists).
Step 4: Factual claim extraction
Read through each document and extract all verifiable factual claims about YouTrackDB / YQL behavior. Examples:
- "Keywords and class names are case-insensitive"
- "Field names and values are case-sensitive"
- "YouTrackDB does not support the HAVING keyword"
- "YouTrackDB allows only one class as the target"
- "The YQL engine automatically recognizes if any indexes can be used"
For each claim, note the file, line number, and the exact claim text.
Step 5: Query extraction
Extract all YQL/SQL code examples from fenced code blocks (```sql sections). For each query, note:
- The file and line number
- Whether it is a YouTrackDB YQL query or a standard SQL example (for comparison only)
- Whether it should succeed or fail (some examples demonstrate unsupported syntax)
Step 6: Build validation test
Add new test methods to the persistent DocValidationTest class (core/src/test/java/com/jetbrains/youtrackdb/internal/core/sql/DocValidationTest.java) that validate extracted queries and factual claims against a real in-memory YouTrackDB instance using the Gremlin API with yql() methods. If the test class does not exist yet, create it with the following pattern:
package com.jetbrains.youtrackdb.internal.core.sql;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import com.jetbrains.youtrackdb.api.DatabaseType;
import com.jetbrains.youtrackdb.api.YouTrackDB;
import com.jetbrains.youtrackdb.api.YourTracks;
import com.jetbrains.youtrackdb.api.gremlin.YTDBGraphTraversalSource;
import java.nio.file.Path;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class DocValidationTest {
private static YouTrackDB youTrackDB;
private static Path dbPath;
private YTDBGraphTraversalSource g;
@BeforeClass
public static void setUpClass() throws Exception {
dbPath = Path.of(System.getProperty("java.io.tmpdir"), "doc-validation-test");
youTrackDB = YourTracks.instance(dbPath.toString());
youTrackDB.create("test", DatabaseType.MEMORY, "admin", "admin", "admin");
}
@AfterClass
public static void tearDownClass() {
youTrackDB.close();
}
@Before
public {
g = youTrackDB.openTraversal(, , );
}
{
g.close();
}
}
CRITICAL: Only use the public Gremlin API. The test class lives in com.jetbrains.youtrackdb.internal.core.sql for organizational reasons (it is in the core module's test tree), but it must only import from com.jetbrains.youtrackdb.api.* and standard TinkerPop packages (org.apache.tinkerpop.gremlin.*). Never import internal classes like DatabaseSessionEmbedded, YouTrackDBImpl, DbTestBase, or anything else under com.jetbrains.youtrackdb.internal.
Key patterns for writing tests:
- Schema commands (CREATE CLASS, CREATE PROPERTY, CREATE INDEX) run outside transactions using
g.command(): g.command("CREATE CLASS Foo EXTENDS V") — always use EXTENDS V (vertex) or EXTENDS E (edge) so results are compatible with the Gremlin result mapper.
- Creating data — use
CREATE VERTEX (not INSERT INTO) inside transactions:
g.executeInTx(tx -> {
tx.yql("CREATE VERTEX Foo SET name = 'bar'").iterate();
});
- Updating data — use
UPDATE inside transactions via yql().iterate():
g.executeInTx(tx -> {
tx.yql("UPDATE Foo SET name = 'baz' WHERE name = 'bar'").iterate();
});
- Querying data — use
SELECT inside transactions via g.computeInTx():
var results = g.computeInTx(tx -> tx.yql("SELECT FROM Foo").toList());
assertThat(results).isNotEmpty();
Results from SELECT on vertex classes are Vertex objects — cast and use .value("prop"):
Vertex v = (Vertex) results.get(0);
assertThat((String) v.value("name")).isEqualTo("baz");
- Queries that should fail (unsupported syntax): wrap in
assertThatThrownBy:
assertThatThrownBy(() -> g.executeInTx(tx -> {
tx.yql("BAD QUERY").iterate();
}));
- The
yql() method returns a lazy YTDBGraphTraversal — always call .iterate() or .toList() to execute it.
- The
command() method executes eagerly — no need to call .iterate(). However, internally iterates results through the Gremlin result mapper, which only supports vertices and stateful edges. Therefore, (CREATE CLASS, CREATE PROPERTY, CREATE INDEX) — never for INSERT, UPDATE, or DELETE.
Gremlin API limitations to be aware of
These limitations affect what can be validated through the public API:
- All classes must extend V or E — the Gremlin result mapper (
GremlinResultMapper) only supports vertices and stateful edges. SELECT on a plain class (not extending V/E) will throw IllegalStateException: Only vertices and stateful edges are supported in Gremlin results. If a document example uses a plain class, create it with EXTENDS V for testing purposes.
- Use
yql().iterate() for UPDATE/INSERT — never use command() for data mutation commands, as it will fail when the result mapper tries to process the non-vertex result.
RETURN AFTER on UPDATE — use tx.yql("UPDATE ... RETURN AFTER @this").toList() to collect results. The results are vertex objects when the target class extends V.
Group tests by document section. Each test method should have a comment referencing the document claim it validates.
Step 7: Run validation
- Run the test class:
./mvnw -pl core clean test -Dtest=DocValidationTest
- If Spotless formatting fails, fix it first:
./mvnw -pl core spotless:apply
- If tests fail, analyze each failure:
- Parse error on a query the doc says should work -> the document has a query bug. Flag it.
- Query succeeds but the doc says it should fail -> the document claim is wrong. Flag it.
- Wrong result count or values -> the document example may be misleading. Flag it.
- Compilation error -> fix the test code and re-run.
Step 8: Produce review report
After all checks complete, present a consolidated report to the user:
## Documentation Review: <path>
### Grammar & Style
| File | Line | Issue | Suggested Fix |
|------|------|-------|---------------|
| ... | ... | ... | ... |
### Link Validation
| File | Line | Link Target | Status |
|------|------|-------------|--------|
| ... | ... | ... | Missing / OK |
### Factual Claims
| File | Line | Claim | Verified | Notes |
|------|------|-------|----------|-------|
| ... | ... | ... | Yes/No | ... |
### Query Validation
| File | Line | Query | Expected | Result | Notes |
|------|------|-------|----------|--------|-------|
| ... | ... | ... | Success/Fail | Pass/Fail | ... |
### Summary
- Total files reviewed: N
- Grammar issues found: N
- Broken links: N
- Factual claims verified: N/N
- Queries validated: N/N
Step 9: Apply fixes
Ask the user whether to:
- Apply grammar fixes — edit the documents directly using the Edit tool.
- Flag query/factual issues only — report without changing files (the user may want to rewrite sections).
- Apply all fixes — grammar fixes + rewrite incorrect queries/claims.
Step 10: Verify test class
After the review is complete:
- Keep the
DocValidationTest class — it serves as a living validation of documentation examples.
- Ensure all new test methods were added and pass:
./mvnw -pl core clean test -Dtest=DocValidationTest
- Run Spotless to ensure formatting:
./mvnw -pl core spotless:apply
Important notes
- Never modify the test infrastructure — only add methods to
DocValidationTest.
- The
core module uses JUnit 4 (not JUnit 5). Use @Test, @Before, @After, @BeforeClass, @AfterClass from org.junit.
- Always run
spotless:apply before running tests if the test class is new.
- When validating queries, create unique class names per test to avoid collisions (e.g.,
CityDistinct, EmpSalary).
- Standard SQL examples shown for comparison (e.g., JOIN syntax) should NOT be executed — they are expected to be invalid in YouTrackDB.
- If a document references files that don't exist yet, flag them as warnings but don't fail the review.
- Use
yql() for YQL queries — the yql() method on YTDBGraphTraversalSourceDSL returns a lazy traversal; always terminate with .iterate() or .toList().
- Use
command() for schema DDL — command() executes eagerly and is appropriate for CREATE CLASS, CREATE PROPERTY, CREATE INDEX, etc.
- Transaction helpers: Use
g.executeInTx() for side-effecting operations, g.computeInTx() when you need a return value, and g.autoExecuteInTx() when returning a traversal that should be auto-iterated.