review-lesson-technical

star 28

Review a single lesson for AsciiDoc syntax, link formatting, code blocks, slides structure, and question includes. Fixes issues inline and appends a WHY report.

neo4j-graphacademy By neo4j-graphacademy schedule Updated 3/26/2026

name: review-lesson-technical description: Review a single lesson for AsciiDoc syntax, link formatting, code blocks, slides structure, and question includes. Fixes issues inline and appends a WHY report. allowed-tools: Read, Edit, Glob, Grep

Review: Technical Formatting

Purpose: Fix AsciiDoc syntax errors, link formatting problems, code block issues, slides structure, and question includes in a single lesson.adoc file. Every change is recorded with a reason.

When to use: Stage 3 of the course review pipeline. Run after grammar and structure reviews.

Input: Path to a lesson folder (e.g. asciidoc/courses/my-course/modules/1-intro/lessons/1-overview/)

Output:

  • lesson.adoc — fixed in place
  • REVIEW-REPORT.md in the lesson folder — created or appended with a technical section

Overview

This review checks and fixes:

  1. AsciiDoc syntax — blank lines between elements, lists, no markdown
  2. Links — action text, external window flag, Aura console URL
  3. Code blocks — correct delimiters, titles, callout syntax
  4. Admonitions — titles required, correct delimiter
  5. Questions — read button vs questions, all question files included
  6. Slides — opening header required when slides are present

Phase 1: Read the Lesson

Read lesson.adoc in full before making changes. Note:

  • Whether the lesson contains [.slide blocks (slides-enabled)
  • Whether there is a questions/ subfolder with .adoc files
  • Whether the lesson has a read:: button

Phase 2: AsciiDoc Syntax

Blank lines between elements

There must be a blank line between a paragraph and any list (ordered or unordered).

Here is some text.
* Item 1
* Item 2

Here is some text.

* Item 1
* Item 2

Two blank lines between major sections

There must be two blank lines between section blocks (before a [.slide] marker or a == header).

[.slide]
== Section One

Content here.
[.slide]
== Section Two

[.slide]
== Section One

Content here.


[.slide]
== Section Two

No markdown syntax

Replace any markdown that has crept in:

Markdown (wrong) AsciiDoc (correct)
## Heading == Heading
**bold** *bold*
```lang / ``` [source,lang]\n----\n----
[link text](url) link:url[link text]
> blockquote [quote]\n____\ntext\n____
--- (horizontal rule) '''

Ordered lists — dot notation

Use . for ordered list items, not explicit numbers.

1. First step
2. Second step

. First step
. Second step

If an image or code block appears mid-list, use + for continuation:

. First step
+
image::images/step.png[]

. Second step

Phase 3: Links

Link text must be actionable

Link text should describe the action the user takes by clicking, not the destination name alone.

link:https://neo4j.com/docs[here]link:https://neo4j.com/docs[Neo4j documentation]link:https://neo4j.com/docs[Read the Neo4j documentation^]link:https://neo4j.com/docs[View installation options^]

External links must open in a new window

Any link to a URL outside the course must have ^ at the end of the link text.

link:https://neo4j.com/docs[Read the docs]link:https://neo4j.com/docs[Read the docs^]

Aura console URL

Links to the Aura console must use the /graphacademy path:

link:https://console.neo4j.io/[Open the Aura console^]link:https://console.neo4j.io/graphacademy[Open the Aura console^]

Internal course links

Links within the course (to other lessons or modules) do not need ^ and should use relative paths, not absolute URLs.


Phase 4: Code Blocks

Correct delimiter format

Code blocks must use four hyphens ----, not backticks.

```cypher
MATCH (n) RETURN n;
```

[source,cypher]
.Find all nodes
----
MATCH (n) RETURN n;
----

Code block title

Every code block should have a descriptive title on the line immediately after the [source,...] marker, prefixed with .:

[source,cypher]
.Find all customers who placed an order
----
MATCH (c:Customer)-[:PLACED]->(o:Order)
RETURN c.name, count(o) AS orderCount;
----

Callout syntax

Callouts in code blocks use angle-bracket notation with a // comment:

MATCH (n) RETURN n; // (1)MATCH (n) RETURN n; // <1>

The callout list below the code block uses:

<1> Explanation of this part
<2> Explanation of this part

Code block context and explanation

Every code block must have both:

  1. An introduction before it — one sentence explaining what the code demonstrates and why it is there.
  2. An effect explanation after it — one sentence describing what running this code actually does: what it creates, returns, modifies, or produces.

A code block with only an introduction but no follow-up is incomplete — the learner sees the code but does not know what to expect from it.

❌ (introduction only, no effect):

Add a user preference to long-term memory:

[source,python]
----
await memory.long_term.add_preference(
    category="communication",
    preference="Prefers concise responses"
)
----

read::Continue[]

✅ (introduction + effect):

Add a user preference to long-term memory:

[source,python]
----
await memory.long_term.add_preference(
    category="communication",
    preference="Prefers concise responses"
)
----

This creates a `Preference` node linked to the current user. On future sessions, the agent retrieves matching preferences before generating a response.

❌ (no introduction, code appears directly after prose):

Your AuraDB graph stores connected data.

[source,cypher]
----
MATCH (m:Movie)<-[:ACTED_IN]-(a:Person)
RETURN m.title
----
A Cypher Template stores a fixed query with one or more parameters the LLM fills at runtime.
A "Get Customer" tool might look like this:

[source,cypher]
----
MATCH (c:Customer {customerID: $customerID})
RETURN c.companyName, c.contactName
----

This returns the company name and contact name for the customer matching the given ID.

Code must use the course schema

Code examples must use the same data model as the course — not a generic placeholder from an unrelated domain. A Northwind course must not show Movie/Person examples; a movie course must not show Customer/Order examples. If a code block uses a schema that does not match the course topic, flag it for replacement.

No placeholder syntax inside code blocks

Code shown in a [source,...] block or an inline backtick must be valid, runnable code. Ellipsis (...), placeholder comments (// add more here), or truncation markers inside executable positions are not valid and will produce syntax errors if a learner runs them.

`MATCH (c:Customer {id: $id}) RETURN c.name, ...``MATCH (c:Customer {id: $id}) RETURN c.name, c.city`

If the code is intentionally incomplete, move it into a callout explanation rather than the code itself.

All imports and referenced names must be present

Every Python code block must be self-contained or clearly part of a continuation. Any class, function, or variable used in a code block must be either defined in that block or imported in that block.

❌ (uses MemoryDependency without import or definition — NameError at runtime)

result = await agent.run("Hello", deps=MemoryDependency(memory=memory))

✅ (all names are either imported or clearly part of the library's public API)

result = await agent.run("Hello")

For each code block in a Python lesson, check that:

  • All import statements for the classes/functions used are present in the block or in a preceding "Setup" block clearly identified as shared
  • No class name appears that is not defined in the block, not imported, and not a documented library export
  • If a class is user-defined (e.g. a dataclass the learner must write), the definition appears before first use

Flag any code block that references an undefined name. Do not guess at what the import might be — flag it as requiring manual review if the correct import is not clear.


Phase 4a: No definition lists — use bullet points

AsciiDoc definition lists (term:: / body) must be converted to bullet points with the term bolded inline. Definition lists render inconsistently and are harder to read on screen.

Context injection::
The most recent messages are retrieved and injected into each new prompt automatically.

Semantic search::
Past messages are embedded and indexed.

* *Context injection* — the most recent messages are retrieved and injected into each new prompt automatically.
* *Semantic search* — past messages are embedded and indexed.

How to identify: Look for lines ending in :: followed by a body paragraph. Convert every occurrence.


Phase 4b: Schema diagrams must use Mermaid, not Cypher

A [source,cypher] block that shows node definitions ((:Label {props})) or relationship patterns without a MATCH/CREATE/RETURN clause is a schema diagram, not executable Cypher. Schema diagrams must use [source,mermaid] so the platform renders them as graphs.

How to identify a schema block vs executable Cypher:

  • Schema: contains (:Label {prop}) node definitions or bare relationship patterns like (a)-[:REL]->(b) without MATCH, CREATE, MERGE, RETURN
  • Executable: contains Cypher clauses (MATCH, CREATE, WITH, RETURN, etc.) — keep as [source,cypher]

❌ Schema shown as Cypher (wrong):

[source,cypher]
.Short-term memory schema
----
(:Conversation {id, user_id})
(:Message {id, role, content, embedding})
(c:Conversation)-[:FIRST_MESSAGE]->(m:Message)
----

✅ Schema shown as Mermaid (correct):

[source,mermaid]
----
graph LR
    C([Conversation \n id, user_id]) -->|FIRST_MESSAGE| M([Message \n role, embedding])
----

When converting, replace node definitions with Mermaid node syntax and keep the key properties inline using \n line breaks. Use graph LR for linear chains and graph TB for multi-layer schemas with subgraphs.

Phase 4c: Mermaid Diagrams

Mermaid diagrams must use the [source,mermaid] block attribute, not [mermaid] alone.

[mermaid]
----
graph LR
    A --> B
----

[source,mermaid]
----
graph LR
    A --> B
----

If a lesson contains [mermaid] without source,, replace it with [source,mermaid].

Mermaid line breaks require spaces on both sides

Inside Mermaid node labels, \n must have a space on both sides to render as a line break. Without surrounding spaces, the text runs together.

M1([Message\nrole: user])

M1([Message \n role: user])

If a diagram contains \n without surrounding spaces inside node labels, add them.

=======

fa056e45f (update claude skills)


Phase 5: Admonitions

Every admonition ([NOTE], [TIP], [WARNING], [CAUTION], [IMPORTANT]) must have a title:

[NOTE]
=====
This is important.
=====

[NOTE]
.Important
=====
This is important.
=====

The title should be brief and descriptive, not just repeat the admonition type.


Phase 6: Questions

Read button vs questions

A lesson cannot have both a read:: button and questions. If a questions/ folder exists with .adoc files, remove the read:: button.

❌ (lesson has both)

read::Let's move on[]

include::questions/1-question.adoc[leveloffset=+1]

✅ (keep only the include)

include::questions/1-question.adoc[leveloffset=+1]

All question files must be included

Check the questions/ folder for .adoc files:

Glob pattern: questions/*.adoc

For every .adoc file found, verify there is a corresponding include::questions/[filename].adoc[leveloffset=+1] in lesson.adoc. Add any missing includes.

Quiz marker

The == Check your understanding section must be preceded by [.quiz] on the previous line:

[.quiz]
== Check your understanding

Sequential attribute

If the lesson has more than one question, the :sequential: true attribute may be appropriate (if questions build on each other). If there is only one question, remove :sequential: true if present.


Phase 7: Slides

If the lesson contains any [.slide markers, it has slide view enabled and requires additional checks.

Opening header required

The lesson must begin with a level-2 header immediately after the attributes. Text before the first header is not shown in slide view.

= Lesson Title
:order: 1

Some opening text without a header.

✅ (header visible in slide view)

= Lesson Title
:order: 1


[.slide]
== Introduction

Some opening text.

✅ (header hidden in read view with discrete)

= Lesson Title
:order: 1


[.slide.discrete]
== Introduction

Some opening text.

Phase 8: Write the Report

After fixing the file, create or append REVIEW-REPORT.md in the lesson folder.

## Technical Formatting Review — YYYY-MM-DD

**Status:** ✅ Complete / ⚠️ Issues remain

### Changes Made

- **List spacing**: Added blank line before bullet list in "Understanding indexes" section — _AsciiDoc requires blank line before lists_
- **Link**: Added `^` to docs link — _External links must open in new window_
- **Aura URL**: Changed `console.neo4j.io/` → `console.neo4j.io/graphacademy` — _Must use /graphacademy path for learner context_
- **Code block**: Replaced backtick fence with `[source,cypher]\n----` — _AsciiDoc format required; no markdown_
- **Callout**: Changed `// (1)` → `// <1>` — _AsciiDoc callout syntax_
- **Read button**: Removed `read::` button — _Lesson has questions; cannot have both_
- **Missing include**: Added `include::questions/2-verify.adoc[leveloffset=+1]` — _Question file existed but was not included_

### Issues Requiring Manual Review

- [ ] Dead link suspected: `link:https://neo4j.com/docs/old-page[...]` — _Could not verify; check that this URL still resolves_

References

  • .cursor/technical-lesson-review.mdc — AsciiDoc, links, questions, slides
  • .cursor/rules/asciidoc-syntax.mdc — Line break requirements
  • .cursor/rules/code-callouts.mdc — Callout syntax
  • .cursor/rules/slides-formatting.mdc — Slide structure rules
Install via CLI
npx skills add https://github.com/neo4j-graphacademy/courses --skill review-lesson-technical
Repository Details
star Stars 28
call_split Forks 44
navigation Branch main
article Path SKILL.md
More from Creator
neo4j-graphacademy
neo4j-graphacademy Explore all skills →