Skip to content
8 changes: 5 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ ai-plugins/
├── docs/ # Contributor and user documentation
├── scripts/validate.py # Manifest, frontmatter and template-set validation (CI)
├── scripts/test_scaffold.py # Unit tests for the scaffold skill's script (CI)
├── scripts/test_check_bmm.py # Unit tests for the bmm-authoring skill's checker (CI)
├── CHANGELOG.md # Release notes per plugin
└── plugins/<plugin-name>/ # One directory per plugin
├── .claude-plugin/plugin.json # Claude Code plugin manifest
Expand Down Expand Up @@ -44,20 +45,21 @@ Full details: [docs/skill-authoring.md](docs/skill-authoring.md)

## Development

Pure-content repository (JSON manifests + markdown skills) — no build step or package manager. The one script, the `scaffold` skill's `scripts/scaffold.py`, has unit tests: `python3 -m unittest discover -s scripts -p 'test_*.py'` (runs in CI).
Pure-content repository (JSON manifests + markdown skills) — no build step or package manager. Two skills bundle a script, each with unit tests: `scaffold` (`scripts/scaffold.py`) and `bmm-authoring` (`scripts/check_bmm.py`). Run them with `python3 -m unittest discover -s scripts -p 'test_*.py'` (runs in CI).

- **Validation**: `python3 scripts/validate.py` (Claude + Cursor manifests, version sync, required skill/agent frontmatter fields, component paths, and the `scaffold` template set's integrity — runs in CI; it does not check description length, inventories, or the release tag)
- **Local testing**: [docs/testing.md](docs/testing.md); **versioning/releases**: [docs/versioning.md](docs/versioning.md)
- **End-user installation**: [docs/install.md](docs/install.md)

## Component Dependencies

The skills are pure content; the subagents and the `publish`, `regen-classes` and `scaffold` action skills rely on external tools and degrade
gracefully when one is absent (each says so in its prompt):
The skills are pure content, except that `bmm-authoring` runs a bundled checker; the subagents and the `publish`, `regen-classes` and `scaffold` action skills rely on external tools. All of them degrade
gracefully when a tool is absent (each says so in its prompt):

- **`spec-reviewer`, `xref-auditor`** — need a `specifications-XX` checkout and (for attribute resolution) the sibling `specifications-AA_GLOBAL`.
- **`xref-auditor`, `identifier-grounding`** — use **WebFetch** to read spec Markdown twins (`.html` → `.md`); `identifier-grounding` additionally prefers the **`openehr-assistant` MCP** (`type_specification_get`) when connected, falling back to the twin.
- **`regen-classes`** — needs **Docker** (`ghcr.io/openehr/bmm-publisher`).
- **`bmm-authoring`** — needs **`python3`** (standard library only) to run its read-only `scripts/check_bmm.py`; without it, it says so, reports the schema as unchecked and reviews the change by hand against its reference.
- **`scaffold`** — needs **`python3`** (standard library only) to run its bundled `scripts/scaffold.py`, and says so and stops when it is missing. It writes into the repository it is run in, so it plans first and never overwrites a hand-edited file without being told to. For a new repository's BMM schema it asks **Docker** for the schemas the local `ghcr.io/openehr/bmm-publisher` image bundles, and never pulls the image. Without Docker or the image that one file is reported as blocked, and the rest are still written.
- **`publish`** — needs **Docker** and sibling `specifications-AA_GLOBAL` and component checkouts. It runs the published `ghcr.io/openehr/asciidoctor` image, which bundles the toolchain and `spec_publish.sh`; the boilerplate and references are still read from the AA_GLOBAL checkout. It checks that each HTML output was rebuilt and that the log has no missing includes, because the script reports success even when it built nothing or dropped the class tables.

Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,24 @@ Notable changes to the plugins in this repository. The format follows [Keep a Ch

### Added

- `bmm-authoring` skill: write a component's BMM schema (the P_BMM JSON in `computable/BMM/`) from scratch, or change one.
- The reference covers every class, property, type and function kind, and the spec features `bmm-publisher` ignores.
- `assets/openehr_demo_0.1.0.bmm.json` is a worked example with one of each common construct.
- `scripts/check_bmm.py` (read-only, Python 3.8+) reports mistakes that `bmm-publisher` accepts without a warning, such as a misspelt `_type` or key.
- Names from an included schema not loaded with `-d` go unchecked, and a run with no errors then exits 3, not 0.
- CI runs its unit tests in the root `scripts/test_check_bmm.py`.
- `scaffold` template set revision 3: a new repository also gets `computable/BMM/<id>.bmm.json` (file id `bmm`, strategy `bmm-seed`).
- The script lists the schemas the local `ghcr.io/openehr/bmm-publisher` image bundles (`docker run --pull never`, so nothing is downloaded) and copies the highest version for the component.
- When the image bundles none, it writes an empty schema `openehr_<component>_<first_release>`. The schema has one root package `org.openehr.<name>`, no classes, and BASE in `includes` for other components. bmm-publisher refuses a schema without a package.
- Without Docker or the image the file is reported as `blocked` and the other files are still written; `--var bmm_schema_id=<id>` creates the empty schema anyway.
- Existing repositories are not offered a schema; `--overwrite bmm` asks for one.
- Derived variables can take a regex group (`match` + `group`), which gives the new `bmm_schema_name` and `bmm_rm_release`.
- The `AGENTS.md` task table and build region send BMM schema edits to `bmm-authoring`.

### Changed

- `class-generation`, `authoring` and `scaffold` send BMM schema edits to `bmm-authoring`.
- `docs/prompting-guide.md` sends the class-change prompts to `bmm-authoring` and adds a section for a new component's schema.

## openehr-specs 0.5.0 (2026-10-08)

Expand Down
21 changes: 18 additions & 3 deletions docs/prompting-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ In the prompts, `<XX>` is a component id such as `RM`, `BASE` or `AM`, and `<spe
| [Add or change a chapter, figure or link](#add-or-change-a-chapter-figure-or-link) | `authoring` |
| [Draft or improve spec prose](#draft-or-improve-spec-prose) | `content-patterns` |
| [Record a change in the amendment record](#record-a-change-in-the-amendment-record) | `amendment-record` |
| [Change a class, attribute or invariant](#change-a-class-attribute-or-invariant) | `class-generation`, `/openehr-specs:regen-classes` |
| [Change a class, attribute or invariant](#change-a-class-attribute-or-invariant) | `bmm-authoring`, `class-generation`, `/openehr-specs:regen-classes` |
| [Write the BMM schema for a new component](#write-the-bmm-schema-for-a-new-component) | `bmm-authoring` |
| [Review before you merge](#review-before-you-merge) | `review`, `spec-reviewer`, `xref-auditor`, `identifier-grounding` |
| [Preview the HTML](#preview-the-html) | `/openehr-specs:publish` |
| [Releases, status changes and the CR/PR process](#releases-status-changes-and-the-crpr-process) | `governance` |
Expand Down Expand Up @@ -80,12 +81,16 @@ To put two changes under one version, say so: "same version as the top entry".

## Change a class, attribute or invariant

Class tables in `docs/UML/classes/` are generated from the BMM schema, so the change goes in the BMM and the tables are regenerated. Editing the BMM follows the repository's own `AGENTS.md`; the plugin's skills cover the generation.
Class tables in `docs/UML/classes/` are generated from the BMM schema, so the change goes in the BMM and the tables are regenerated. `bmm-authoring` edits the BMM and runs a bundled checker on it, which needs `python3`. The checker catches mistakes that `bmm-publisher` accepts without a warning, such as a misspelt key. `class-generation` regenerates the tables.

```text
In the BMM for this repo, add an optional attribute <name> of type <Type> to class <CLASS>, with documentation, following this repo's AGENTS.md.
In the BMM for this repo, add an optional attribute <name> of type <Type> to class <CLASS>, with documentation, and run the BMM checker.
```

Claude edits the JSON in place and raises the build number in `schema_revision`. It runs the checker before and after the change, so findings that were already in the schema are not mixed up with yours. If a sibling clone such as `specifications-BASE` is missing, it tells you the check is incomplete.

Then regenerate the tables:

```text
Regenerate the class tables for <XX> from the BMM in this checkout, not the copy bundled in the publisher image. Compare with docs/UML/classes and copy over only the tables that changed.
```
Expand All @@ -100,6 +105,16 @@ To see what the image's bundled schemas produce, type:

It writes to `out/` in the working directory and places nothing in a repository, so run it from a scratch directory. Its output reflects the bundled schemas; for tables to commit, use the previous prompt.

## Write the BMM schema for a new component

Give the release, the BASE version it builds on, and the classes:

```text
Write the BMM schema for the new <XX> component, release <x.y.z>, building on BASE <base-version>, with these classes: <...>.
```

If `/openehr-specs:scaffold` already created an empty schema, Claude fills that one; otherwise it starts from the skill's worked example. Either way, it asks you for the schema author. It checks the new schema as it would a change, so the sibling `specifications-BASE` clone is needed for a complete check.

## Review before you merge

One chapter, inline:
Expand Down
4 changes: 2 additions & 2 deletions docs/testing.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Testing and Validation

This is a pure-content repository: JSON manifests plus markdown skills (including user-only action skills) and subagents. There is no build step or package manager, and the only automated tests cover the `scaffold` skill's script. Testing means installing the marketplace locally and validating structure and skill quality.
This is a pure-content repository: JSON manifests plus markdown skills (including user-only action skills) and subagents. There is no build step or package manager, and the only automated tests are for the scripts bundled with the `scaffold` and `bmm-authoring` skills. Testing means installing the marketplace locally and validating structure and skill quality.

## Local Testing

Expand All @@ -22,7 +22,7 @@ For Cursor, copy `plugins/openehr-specs` to `~/.cursor/plugins/local/openehr-spe
## Validation

- **Manifest and frontmatter validation**: `python3 scripts/validate.py` (CI runs it on every PR) checks the Claude and Cursor JSON manifests, name and version sync, declared component paths, and the marketplace `owner.name`. For every skill and subagent it checks that `name` and `description` exist and that `name` matches the directory or file name. It also runs the `scaffold` template-set check (`scaffold.py check`: templates exist and render, revisions are contiguous, every revision has a migration file, and the template digest matches the latest revision). It does not check description length, `disable-model-invocation`, the README inventories, or the release tag.
- **Script tests**: `python3 -m unittest discover -s scripts -p 'test_*.py'` (CI runs it on every PR) covers the `scaffold` script: the template engine, each file strategy, variable inference, and the upgrade path across revisions, all in temporary directories. Run it after changing the script or the template set.
- **Script tests**: `python3 -m unittest discover -s scripts -p 'test_*.py'` (CI runs it on every PR) tests both bundled scripts in temporary directories. For `scaffold` it covers the template engine, each file strategy, variable inference, and upgrades across revisions. For the `bmm-authoring` checker it covers each finding and exit code, a clean run on the worked example, and a wrongly typed value at any node of the worked example, which must give a finding and not a traceback. Run it after changing either script, the template set, or the worked example.
- **Built-in manifest check**: `claude plugin validate plugins/openehr-specs` validates the plugin manifest; add `--strict` to treat warnings as errors.
- **Structural validation**: after creating or modifying plugin components, run the `plugin-dev:plugin-validator` agent. It checks `plugin.json`, the marketplace entry, directory layout, and frontmatter. The agent comes from the `plugin-dev` plugin, which this repo enables in `.claude/settings.json`.
- **Skill quality review**: run the `plugin-dev:skill-reviewer` agent (also from `plugin-dev`). It checks description triggering quality, progressive disclosure, and content structure.
Expand Down
3 changes: 2 additions & 1 deletion plugins/openehr-specs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# openEHR Specifications

Skills and subagents for authors working in `specifications-XX` and `specifications-ITS-REST` repositories — AsciiDoc structure, amendment records, governance, quality review, prose patterns, ITS-REST OpenAPI sources, and BMM-based class documentation generation.
Skills and subagents for authors working in `specifications-XX` and `specifications-ITS-REST` repositories — AsciiDoc structure, amendment records, governance, quality review, prose patterns, ITS-REST OpenAPI sources, BMM schemas, and the class documentation generated from them.

## Installation

Expand Down Expand Up @@ -28,6 +28,7 @@ Add the marketplace from this repository (or a fork), then install `openehr-spec
| `content-patterns` | Prose patterns for spec chapters and sections |
| `its-rest` | ITS-REST OpenAPI YAML and operation descriptions |
| `class-generation` | Generate class tables and UML diagrams from BMM via `bmm-publisher` |
| `bmm-authoring` | Write or change a component's BMM schema (P_BMM JSON) and check it before rendering (needs `python3`) |

### User-only action skills

Expand Down
6 changes: 4 additions & 2 deletions plugins/openehr-specs/skills/authoring/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ description: >
to scaffold a new spec, add or edit a chapter, set up `master.adoc`, add a cross-reference or
figure, or build a local HTML preview. Not for amendment records (amendment-record), prose
style (content-patterns), releases or manifest release entries (governance), ITS-REST OpenAPI
(its-rest), class tables (class-generation), or archetype/AQL work (openehr-assistant plugin).
(its-rest), the class model or its tables (bmm-authoring, class-generation), or archetype/AQL
work (openehr-assistant plugin).
---

# openEHR Specification Document Authoring
Expand All @@ -26,6 +27,7 @@ in `specifications-XX` repositories (RM, AM, BASE, LANG, PROC, SM, QUERY, CDS, C
- **its-rest** — for OpenAPI YAML and Markdown in the ITS-REST repo
- **governance** — release management, change requests, lifecycle governance
- **class-generation** — regenerate the class-definition tables and UML diagrams in `docs/UML/` from BMM via `bmm-publisher`
- **bmm-authoring** — write or change the component's BMM schema (classes, attributes, functions, invariants) and check it

For attribute naming patterns, read `references/cross-references.md`. To verify that every
`{openehr_*}` attribute and deep-link anchor resolves, dispatch the `xref-auditor` subagent.
Expand Down Expand Up @@ -248,7 +250,7 @@ that the log has no `ERROR` or `include file not found` lines. The build rewrite

### Conventions

- **Chapter files**: Edit `masterNN-*.adoc` files directly. Never edit files under `docs/UML/` — those are generated from the component's BMM schema by `bmm-publisher` (see the **class-generation** skill); change the BMM and regenerate.
- **Chapter files**: Edit `masterNN-*.adoc` files directly. Never edit files under `docs/UML/` — those are generated from the component's BMM schema by `bmm-publisher` (see the **class-generation** skill); change the BMM (see the **bmm-authoring** skill) and regenerate.
- **Cross-references within spec**: Use `<<anchor_name>>` or `<<anchor_name, display text>>`.
- **Cross-references to other specs**: Use the URL attributes from `reference_definitions.adoc`:
```asciidoc
Expand Down
Loading
Loading