Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 27 additions & 21 deletions .apm/skills/pr-description-skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ scannable.
| 3 | Problem (WHY) | Observed failure modes; max 6 bullets, max 3 quoted anchors |
| 4 | Approach (WHAT) | Table or 3-7 bullets; may say "additive: see Implementation" |
| 5 | Implementation (HOW) | One short paragraph per file or a table |
| 6 | Diagrams | 1-3 validated mermaid blocks, each with a legend |
| 6 | Diagrams | 1-3 validated mermaid blocks, each with a legend; diagram type chosen per intent (`assets/mermaid-conventions.md`) |
| 7 | Trade-offs | 3-5 bullets (1-2 if mechanical) |
| 8 | Benefits | 3-5 numbered, measurable items |
| 9 | Validation | Real command output, ideally inside `<details>` if long |
Expand Down Expand Up @@ -224,8 +224,12 @@ Run these steps in order. Tick each before moving on.
4. [ ] Fill in the template top-to-bottom using only facts from
the activation contract. Every WHY-claim gets a verbatim
quoted anchor. If you cannot anchor a claim, drop it.
5. [ ] Generate 1-3 mermaid diagrams. Add a one-sentence legend
above each.
5. [ ] Generate 1-3 mermaid diagrams. **Before drafting any block,
load `assets/mermaid-conventions.md`** to pick the right
diagram type per intent (sequenceDiagram for execution flow,
flowchart LR for pipeline / architecture, stateDiagram-v2 for
state machines) and apply the boxing convention for NEW
behavior. Add a one-sentence legend above each diagram.
6. [ ] **Validate every mermaid block deterministically (see
below). Do NOT save the draft until every block validates.**
7. [ ] Load `assets/section-rubric.md` and run the self-check pass.
Expand Down Expand Up @@ -255,24 +259,26 @@ done
If `mmdc` reports any error, fix the diagram and re-run. The skill
MUST NOT save the draft until every mermaid block validates.

### Common mermaid pitfalls

- **Semicolons in `classDiagram` link labels break the parser.** A
label like `dispatches; verifies 3 artifacts` errors at the
semicolon. Use commas or rephrase: `dispatches, verifies 3 artifacts`.
- **`note right of X` in `stateDiagram-v2`** must close with
`end note` on its own line. A note that bleeds into the next
state declaration is a parse error.
- **Round brackets `()` in flowchart node labels** need quoting:
write `A["foo (bar)"]`, not `A[foo (bar)]`.
- **Double quotes inside node labels** must be HTML-escaped as
`&quot;`. Mermaid does not support nested or escaped double
quotes inside `"..."` labels.
- **Pipes `|` and angle brackets `<>` inside labels** also need
quoting or HTML escapes; they are operators in mermaid syntax.
- **Edge labels with colons** can confuse `stateDiagram-v2`; prefer
arrow-then-label form: `A --> B : trigger received`, not
`A --> B[trigger: received]`.
### Diagram type and pitfalls reference

The full diagram-type-by-intent table, canonical templates, and the
GitHub-renderer gotcha list (`mmdc` does NOT always catch GitHub
rejections) live in `assets/mermaid-conventions.md`. Load it whenever
a PR body needs a mermaid block.

Critical drift-known gotcha (the one most likely to bite, captured
inline because it is not obvious from `mmdc` output):

- **Square brackets in flowchart edge labels MUST be quoted.**
`A -->|[EXEC] work| B` parses on `mmdc` but is rejected by
GitHub's renderer (`Expecting 'TAGEND', ..., got 'SQS'`). Quote
the label: `A -->|"[EXEC] work"| B`. The same rule applies to
parentheses, colons, slashes, and pipes in edge labels.

For everything else (semicolons in classDiagram links, `note right
of` closing rules, round brackets in node labels, inline
`:::cssClass` failing in classDiagram on GitHub), see
Comment on lines +278 to +280
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parenthetical contains inline-code spans that are split across lines (starts at `note right and ends at of` on the next line). That tends to render poorly/ambiguously in Markdown. Please keep each inline-code span on a single line (or rephrase to avoid splitting the code span).

Suggested change
For everything else (semicolons in classDiagram links, `note right
of` closing rules, round brackets in node labels, inline
`:::cssClass` failing in classDiagram on GitHub), see
For everything else (semicolons in classDiagram links, `note right of`
closing rules, round brackets in node labels, inline `:::cssClass`
failing in classDiagram on GitHub), see

Copilot uses AI. Check for mistakes.
`assets/mermaid-conventions.md`.

## Output contract

Expand Down
229 changes: 229 additions & 0 deletions .apm/skills/pr-description-skill/assets/mermaid-conventions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
# Mermaid conventions for PR bodies

Load this asset before drafting any mermaid block in a PR body. It
defines (a) which diagram TYPE to pick per intent, (b) the boxing /
styling vocabulary that highlights NEW behavior, and (c) the
GitHub-renderer gotchas that `mmdc` does NOT always catch.

This asset is scoped to **PR bodies**. Architectural design diagrams
(component, thread fan-out, dependency graph) are owned by the
`genesis` skill and have a different convention set; do not conflate.

## Diagram type by intent

A PR body diagram answers ONE question. Pick the type that matches
the question; do not mix.

| Reviewer's question | Diagram type | Boxing convention for "what changed" |
|---|---|---|
| Which jobs / participants run, in what order? (execution flow) | `sequenceDiagram` | `rect rgb(255, 247, 200)` block around new participant interactions; `Note over X` for invariants |
| What is the data / control pipeline? (stages, transformations) | `flowchart LR` | `subgraph` per stage; `classDef new stroke-dasharray: 5 5` for new stages; class assignment via `class N1,N2 new` |
| What does the state machine look like? | `stateDiagram-v2` | `note right of S: NEW` markers on changed states |
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The table row for stateDiagram-v2 suggests single-line note right of S: NEW markers, but this same doc later states that single-line note right of X: text is NOT supported in stateDiagram-v2. Please align the table with the multi-line note ... end note form (or adjust the later rule).

Suggested change
| What does the state machine look like? | `stateDiagram-v2` | `note right of S: NEW` markers on changed states |
| What does the state machine look like? | `stateDiagram-v2` | multi-line `note right of S` ... `end note` markers on changed states |

Copilot uses AI. Check for mistakes.
| How do components / files relate? (architecture) | `flowchart LR` | `classDef new stroke-dasharray: 5 5`; subgraphs for layers |
| Is there a true type hierarchy? (rare) | `classDiagram` | standalone `class Name:::cssClass` lines only -- inline `:::` on relationship lines fails on GitHub |

### Default for "execution flow" PRs

If the PR adds, removes, or reorders **jobs, steps, or third-party
action invocations** in a workflow, use `sequenceDiagram`. Reviewers
read it top-to-bottom as a temporal sequence; the participant lanes
make the boundary between "workflow", "job", and "external action"
explicit. A flat `flowchart TD` of the same content forces the reader
to reconstruct the temporal axis from arrows and is harder to scan.

Use `rect rgb(...)` blocks to group the messages that the PR ADDS;
this gives the reviewer a single visual region to focus on without
hunting for `classDef`-marked nodes.

### Default for "pipeline" PRs

If the PR changes a data flow with discrete stages (parse -> validate
-> render), use `flowchart LR` with one `subgraph` per stage. Mark
NEW stages with `classDef new stroke-dasharray: 5 5;` and assign
nodes via `class N1,N2 new;`. Avoid `flowchart TD` for left-to-right
pipelines; it wastes vertical space and breaks scanning rhythm.

## Canonical templates

### sequenceDiagram (execution flow)

```mermaid
sequenceDiagram
participant W as Workflow
participant P as apm-prep job
participant A as apm job (matrix)
participant Ext as create-github-app-token
participant R as agent job

W->>P: trigger
rect rgb(255, 247, 200)
Note over P,A: NEW: matrix fan-out per credential group
P->>A: groups[] (JSON)
A->>Ext: mint installation token (per group)
Ext-->>A: token
A->>A: pack and upload apm-<group-id>
end
A-->>R: artifacts apm-*
Note over R: validate count vs manifest, restore via bundles-file
```

Conventions:

- Each `participant` is a distinct actor (workflow, job, action). Do
NOT inline step-level work as participants -- those go inside the
sender's lane as `X->>X: action`.
- `->>` is a synchronous send; `-->>` is a return. Pick consistently.
- Wrap NEW interactions in `rect rgb(255, 247, 200)` (a soft yellow).
ASCII labels inside the rect are fine.
- `Note over` is for invariants ("single-writer", "must be true after
this point"), not for narrative.

### flowchart LR (pipeline / architecture)

```mermaid
flowchart LR
subgraph Parse[Parse]
P1[lockfile]
P2[manifest]
end
subgraph Validate[Validate]
V1[schema check]
V2[policy check]:::new
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flowchart template marks V2 with inline :::new, but the conventions immediately below say to avoid inline N:::new and instead use a separate class N new assignment. Please update the template to follow the documented convention (and keep only one mechanism for marking NEW nodes).

Suggested change
V2[policy check]:::new
V2[policy check]

Copilot uses AI. Check for mistakes.
end
subgraph Render[Render]
R1[output]
end
P1 --> V1
P2 --> V1
V1 --> V2
V2 --> R1
classDef new stroke-dasharray: 5 5;
class V2 new;
```

Conventions:

- One `subgraph` per logical stage; the subgraph label is the stage
name (capitalize for scanability).
- Mark NEW nodes with `classDef new stroke-dasharray: 5 5;` and a
separate `class N new;` assignment line (NOT inline `N:::new`,
which works in flowchart but is inconsistent with classDiagram and
hurts copy-paste portability).
- Edges carry verbs only when non-obvious. Default to unlabeled.
- Prefer `LR` for pipelines (left-to-right reads naturally). Use
`TD` only for tree-shaped hierarchies.

### stateDiagram-v2 (state machine)

```mermaid
stateDiagram-v2
[*] --> Pending
Pending --> Resolving: install start
Resolving --> Cached: hit
Resolving --> Downloading: miss
note right of Downloading
NEW: per-group token mint
end note
Downloading --> Cached
Cached --> [*]
```

Convention: `note right of X` requires the multi-line form with
`end note` on its own line. Single-line `note right of X: text` is
NOT supported in `stateDiagram-v2` -- it parses elsewhere but
fails here.

## GitHub-renderer gotchas (drift-known, mmdc does NOT always catch)

These are renderer-level rejections that `mmdc` may parse cleanly
because mmdc and GitHub's mermaid version sometimes drift. Treat the
following as PR-body-specific rules, not as guesses.

### Square brackets in edge labels MUST be quoted

Wrong (parses on mmdc, rejected by GitHub):

```
A -->|[EXEC] do work| B
```

Right:

```
A -->|"[EXEC] do work"| B
```

GitHub's mermaid sees the inner `[` as an attempted node-label start
and raises `Expecting 'TAGEND', 'STR', ..., got 'SQS'`. Always quote
edge labels containing brackets, parentheses, colons, slashes, or
pipes.

### Inline `:::cssClass` fails in `classDiagram` on GitHub

Wrong: `LockFile *-- LockedDependency:::touched`
Right: separate `class LockedDependency:::touched` line.

This works in `flowchart` but fails in `classDiagram` on GitHub
(parser reports `Expecting 'NEWLINE', 'EOF', 'LABEL', got
'STYLE_SEPARATOR'`).

### Round brackets `()` in node labels need quoting

Wrong: `A[foo (bar)]`
Right: `A["foo (bar)"]`

### Pipes `|`, angle brackets `<>`, and double quotes inside labels

These are mermaid operators. Quote the label or HTML-escape:
`A["a &quot;b&quot; c"]`, `A["a | b"]`, `A["a &lt; b"]`.

### Semicolons in `classDiagram` link labels

Wrong: `A --> B : dispatches; verifies 3 artifacts`
Right: `A --> B : dispatches, verifies 3 artifacts` (use commas).

### Colons in flowchart edge labels

Wrong (ambiguous): `A --> B[trigger: received]`
Right: `A --> B : trigger received` (or quote: `A --> B["trigger: received"]`).

## Validation discipline (PR-body-specific)

The skill's existing `mmdc` step catches most parser errors. Add the
following on top:

1. **Dual-validate any execution-flow diagram.** Run `mmdc` AND paste
the block into <https://mermaid.live> to see GitHub's renderer
behavior. mmdc and GitHub drift; mermaid.live tracks GitHub more
closely.
2. **Eyeball the rendered output before saving.** A diagram that
parses but produces overlapping arrows or unreadable boxing is
not done. Re-run with `LR` instead of `TD`, split into two
diagrams, or simplify.
3. **Confirm on GitHub after the PR is opened.** If a block fails to
render after pushing, edit immediately. Unrendered mermaid blocks
on GitHub display as raw fenced code, which signals carelessness.

## Quick reference: when in doubt

- "Show me the order of operations" -> `sequenceDiagram`.
- "Show me the data path" -> `flowchart LR`.
- "Show me the new behavior at a glance" -> `rect rgb(...)` block in
`sequenceDiagram`, OR `classDef new stroke-dasharray: 5 5` +
`class N new` in `flowchart`.
- "Show me what state the resource is in" -> `stateDiagram-v2`.
- "Show me a class hierarchy" -> `classDiagram` (rare for PRs).

## Anti-patterns (refuse these)

- Using `flowchart` for what is fundamentally a temporal sequence
between distinct actors. The reader has to reconstruct the time
axis. Use `sequenceDiagram`.
- Marking new behavior with arbitrary colors like `style N fill:#f00`.
Stick to the `classDef new stroke-dasharray: 5 5` convention OR
`rect rgb(255, 247, 200)` blocks; reviewers learn the vocabulary
across PRs.
- Three diagrams when one suffices. The skill caps at 1-3; the
median PR needs ONE.
- Putting more than ~25 nodes in a single diagram. Split or
summarize -- a god-diagram signals an undecomposed PR.
48 changes: 27 additions & 21 deletions .github/skills/pr-description-skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ scannable.
| 3 | Problem (WHY) | Observed failure modes; max 6 bullets, max 3 quoted anchors |
| 4 | Approach (WHAT) | Table or 3-7 bullets; may say "additive: see Implementation" |
| 5 | Implementation (HOW) | One short paragraph per file or a table |
| 6 | Diagrams | 1-3 validated mermaid blocks, each with a legend |
| 6 | Diagrams | 1-3 validated mermaid blocks, each with a legend; diagram type chosen per intent (`assets/mermaid-conventions.md`) |
| 7 | Trade-offs | 3-5 bullets (1-2 if mechanical) |
| 8 | Benefits | 3-5 numbered, measurable items |
| 9 | Validation | Real command output, ideally inside `<details>` if long |
Expand Down Expand Up @@ -224,8 +224,12 @@ Run these steps in order. Tick each before moving on.
4. [ ] Fill in the template top-to-bottom using only facts from
the activation contract. Every WHY-claim gets a verbatim
quoted anchor. If you cannot anchor a claim, drop it.
5. [ ] Generate 1-3 mermaid diagrams. Add a one-sentence legend
above each.
5. [ ] Generate 1-3 mermaid diagrams. **Before drafting any block,
load `assets/mermaid-conventions.md`** to pick the right
diagram type per intent (sequenceDiagram for execution flow,
flowchart LR for pipeline / architecture, stateDiagram-v2 for
state machines) and apply the boxing convention for NEW
behavior. Add a one-sentence legend above each diagram.
6. [ ] **Validate every mermaid block deterministically (see
below). Do NOT save the draft until every block validates.**
7. [ ] Load `assets/section-rubric.md` and run the self-check pass.
Expand Down Expand Up @@ -255,24 +259,26 @@ done
If `mmdc` reports any error, fix the diagram and re-run. The skill
MUST NOT save the draft until every mermaid block validates.

### Common mermaid pitfalls

- **Semicolons in `classDiagram` link labels break the parser.** A
label like `dispatches; verifies 3 artifacts` errors at the
semicolon. Use commas or rephrase: `dispatches, verifies 3 artifacts`.
- **`note right of X` in `stateDiagram-v2`** must close with
`end note` on its own line. A note that bleeds into the next
state declaration is a parse error.
- **Round brackets `()` in flowchart node labels** need quoting:
write `A["foo (bar)"]`, not `A[foo (bar)]`.
- **Double quotes inside node labels** must be HTML-escaped as
`&quot;`. Mermaid does not support nested or escaped double
quotes inside `"..."` labels.
- **Pipes `|` and angle brackets `<>` inside labels** also need
quoting or HTML escapes; they are operators in mermaid syntax.
- **Edge labels with colons** can confuse `stateDiagram-v2`; prefer
arrow-then-label form: `A --> B : trigger received`, not
`A --> B[trigger: received]`.
### Diagram type and pitfalls reference

The full diagram-type-by-intent table, canonical templates, and the
GitHub-renderer gotcha list (`mmdc` does NOT always catch GitHub
rejections) live in `assets/mermaid-conventions.md`. Load it whenever
a PR body needs a mermaid block.

Critical drift-known gotcha (the one most likely to bite, captured
inline because it is not obvious from `mmdc` output):

- **Square brackets in flowchart edge labels MUST be quoted.**
`A -->|[EXEC] work| B` parses on `mmdc` but is rejected by
GitHub's renderer (`Expecting 'TAGEND', ..., got 'SQS'`). Quote
the label: `A -->|"[EXEC] work"| B`. The same rule applies to
parentheses, colons, slashes, and pipes in edge labels.

For everything else (semicolons in classDiagram links, `note right
of` closing rules, round brackets in node labels, inline
`:::cssClass` failing in classDiagram on GitHub), see
Comment on lines +278 to +280
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parenthetical contains inline-code spans that are split across lines (starts at `note right and ends at of` on the next line). That tends to render poorly/ambiguously in Markdown. Please keep each inline-code span on a single line (or rephrase to avoid splitting the code span).

Suggested change
For everything else (semicolons in classDiagram links, `note right
of` closing rules, round brackets in node labels, inline
`:::cssClass` failing in classDiagram on GitHub), see
For everything else (semicolons in classDiagram links, `note right of`
closing rules, round brackets in node labels, inline `:::cssClass`
failing in classDiagram on GitHub), see

Copilot uses AI. Check for mistakes.
`assets/mermaid-conventions.md`.

## Output contract

Expand Down
Loading
Loading