template-authoring — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited template-authoring (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
When guides conflict, apply this priority (highest first):
Before any template work, load the authoritative guides:
guide_get("openehr://guides/templates/principles")
guide_get("openehr://guides/templates/rules")Load additional guides as needed:
guide_get("openehr://guides/templates/oet-syntax") — OET authoring syntaxguide_get("openehr://guides/templates/oet-idioms-cheatsheet") — common OET patternsguide_get("openehr://guides/templates/cgem-framework") — full CGEM dataset-splitting framework (Step 6)guide_get("openehr://guides/templates/opt-structure") / guide_get("openehr://guides/templates/web-template") — runtime forms (OPT, web template) when discussing deployment or FLAT/STRUCTURED pathsSearch for existing templates first:
ckm_template_search("<use-case>")If creating a new template, search for archetypes to include:
ckm_archetype_search("<concept>")When CKM comes up empty, published-on-GitHub project content is a secondary channel — repositories tagged with the `openehr-content` topic (search topic:openehr-content, ~14 repos: freshEHR, Apperta-CKM projects, regional programmes, individual modellers). CKM holds relatively few templates, so this is more often useful for templates than for archetypes. Treat finds as leads, not governed artefacts: unlike CKM there is no editorial review, no reliable lifecycle_state, and no integrity guarantee, so cite the repo and commit you looked at, never present a find as "published". This needs web access (WebSearch/WebFetch/gh), which this skill does not hold — ask the main session to run the search.
Templates target particular clinical workflows. Define the use-case clearly:
Templates are rooted in a COMPOSITION archetype. Nest entry archetypes (OBSERVATION, EVALUATION, INSTRUCTION, ACTION) and CLUSTER archetypes within it.
Use type_specification_get to verify COMPOSITION structure when needed.
Templates constrain archetypes — they NEVER expand:
min=1 on optional fieldsmax=0 to hide fieldsA template's four jobs (Archetype Technology Overview): composition (fill slots), element choice (remove/mandate/leave optional), narrowing, and setting defaults.
Set a default value (OET: default="..." on a <Rule>) where the use case fixes or strongly implies a single value (e.g. setting, patient position). Defaults appear in the recorded data; archetype-level assumed values are semantic fallbacks for omitted optional items and do not appear in the data — never confuse the two.
Use CGEM (freshEHR's analysis method — a design aid, not an openEHR specification) to decide how a dataset splits across templates, and to set each template's composition category. Load guide_get("openehr://guides/templates/cgem-framework") for the definitions, mapping table and caveats:
| CGEM category | Data nature | COMPOSITION.category | Versioning behaviour |
|---|---|---|---|
| Global Background | True across all contexts for the patient's whole life (allergies, problem list, CPR/ReSPECT decision, current medications) | persistent (431) | One current version per patient, updated in place |
| Contextual Situation | Single source of truth for one care journey / episode / condition (diagnosis-and-staging summary, condition care plan) | episodic (451) | One current version per journey; a new journey creates a new instance |
| Event Assessment | Discrete, repeated recordings at a point in time (vitals at a visit, lab result, assessment score) | event (433) | New composition per submission; never overwritten |
| Managed Response | Formal order/fulfilment cycle tracked from request to completion (referral, prescription, investigation request) | not a category code — usually event (sometimes persistent) | Order state tracked across ACTIONs via the ISM |
Applying it: inventory the datapoints → categorise each C/G/E/M → group same-category datapoints into candidate templates → set each template's category to match → decide reuse (Global Background is usually already modelled and often only read by the form; Event templates are prime reuse candidates) → confirm Managed Response items genuinely need INSTRUCTION/ACTION + ISM and downgrade the rest to simple records.
Three things to state explicitly in any split report:
COMPOSITION.category; it is an event (or persistent) composition distinguished by its INSTRUCTION/ACTION entries and the ISM.persistent plus governance conventions is the common fallback.When the starting point is a clinical form to implement rather than a template design, load [`references/template-from-form.md`](references/template-from-form.md) and follow it: parse the form into a field inventory, run the CGEM dataset split (Step 6) first, then sketch each implied template — archetypes to aggregate, RM entry type per field group, narrowing notes. Step 1's mandatory guide loads still apply in this mode (plus the CGEM guide — the reference covers it). The output is a design sketch, never OET XML; once the user confirms the sketch, continue at Step 8b to emit the file.
terminology_resolve to verify openEHR terminology bindings inherited from archetypes — openEHR terminology only; it errors on external codes, so check SNOMED CT / LOINC / ICD bindings against the archetype's own term_bindings rubrics insteadOne design intent, four serialisations at three layers — not interchangeable, and only OET is hand-authorable:
| Format | Layer | Purpose |
|---|---|---|
OET (.oet) | source | Authoring format — human-editable XML referencing archetypes plus narrowing. The artefact to version |
| Archetype Designer `.t.json` | source | AOM2 differential template JSON (@type: TEMPLATE, parentArchetypeId, differential: true, templateOverlays) — the JSON analogue of OET, from Better's Archetype Designer ("Export Fileset"). Tool-managed: read and review it, but make design edits in the tool or in an OET |
OPT (.opt/.optx/.optj) | compiled | Operational Template — flattened, self-contained runtime artefact the CDR validates against (XML in ADL 1.4 practice; OPT2 adds ADL/XML/JSON, and raw vs profiled variants). Generated, never hand-authored |
| Web Template (JSON) | derived runtime | Better/EHRbase simplified projection of the OPT for UI generation; its node ids define the FLAT/STRUCTURED path schema. Derived, lossy, never authored |
OET (or .t.json) + archetypes ──► OPT ──► web template`.t.json` is not a web template — it sits at the source layer with slots intact, while a web template is flattened runtime JSON with aqlPath/inputs. Both come from Better, at opposite ends of the pipeline; "the Better template" is ambiguous, so always name which one.
For when each format is hand-authorable vs tool-generated and what checksums each carries, load guide_get("openehr://guides/templates/serialization-formats"); for the runtime forms in depth, guide_get("openehr://guides/templates/opt-structure") and guide_get("openehr://guides/templates/web-template"). Reference syntax guides:
guide_get("openehr://guides/templates/oet-syntax")
guide_get("openehr://guides/templates/oet-idioms-cheatsheet")Produce a real, slot-correct OET — not just a design sketch. (The from-form mode in Step 6b produces the sketch; this step turns a confirmed design into the file.) Following templates/oet-syntax:
<template> with a root COMPOSITION archetype reference and a fresh <id> (see UID note below).<Content> entry per included archetype, nested to mirror the COMPOSITION → SECTION → ENTRY → CLUSTER structure.<Rule path="…"> elements for each narrowing constraint (min/max, limitToList, unit hardening, hide_on_form, label overrides, default="…" for use-case-fixed values) — respecting the narrowing principle (Step 5).<Context> if the design needs composition context (e.g. /context/setting fixed to a code).There is no automated OET/OPT validator available, so validate manually against the loaded templates/oet-syntax guide and the Step 9 checklist; state any unconfirmed constraint rather than asserting validity.
Run through the quality checklist:
guide_get("openehr://guides/templates/checklist")Verify:
Generate valid OET files. Use the Write tool to create .oet files in the appropriate project location.
uid — mint a random UUID (v4). If a shell is available, uuidgen (or python3 -c 'import uuid; print(uuid.uuid4())') works; otherwise generate the UUID directly (this skill has no Bash tool, so don't assume shell access).MD5-CAM-*, build_uid) — they are tool-computed; a missing/stale checksum is advisory and never blocks authoring the OET.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.