openehr-rails 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0bdb58aed10113d7fae2a48ef3819f0d999d8f9b5bc03adc8647eef8b357371
4
- data.tar.gz: 78416c8a3208456cd7cc3d33a66354b623404a29044a78f94020d5098ac9faa0
3
+ metadata.gz: 49c5536ccdf6abee6fb03aea4a4ed6002fc6402e6551d6f234b0e6a1a7b9200c
4
+ data.tar.gz: c36b2b1b58f60d22c2cbbbcb5754108bb3235f12737bd573103d2a3463a70618
5
5
  SHA512:
6
- metadata.gz: 4e2a343f8b63041b84dc4e364bb1f2d6a6bf4c586d377b43cd5e79c082dc7cb90c114084ddb325e3468d118b8d5fafef8c2171126d056ab02cf21282f2e0e2af
7
- data.tar.gz: 6f90fd8358d753c85bcc3271830804e47837191c40b115058c75f1f53aae9995bc5f9e60919337df08d9367c81483fae3df5eec0b73084b0e94dc3277432ce17
6
+ metadata.gz: 0651aa4386933ccff02d230ab06d1eda996ca102da9b99ba2ebf09d3fde233ce7f08cea00b26644b744b92b647f917fe0e80dd6169fa158d9af19759c7db7f1b
7
+ data.tar.gz: 4358f499a80546004d5ca80b1ec542f2fe2d977a674461be36ee1afb288322717b71507978a50b1f7560edf1248835783f29e60b0bc874f164d8c4141bcc06a8
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: Bug report
3
+ about: Something behaves incorrectly
4
+ title: ''
5
+ labels: bug
6
+ assignees: ''
7
+ ---
8
+
9
+ ## Summary
10
+
11
+ <!-- One or two sentences: what's wrong. -->
12
+
13
+ ## Environment
14
+
15
+ - `openehr-rails` version: <!-- e.g. 0.4.1 -->
16
+ - `openehr` version: <!-- e.g. ~> 2.3 -->
17
+ - Rails version: <!-- e.g. 8.1 -->
18
+ - Ruby version: <!-- e.g. 3.3, 3.4, 4.0 -->
19
+
20
+ ## Reproduction
21
+
22
+ <!-- Minimal runnable code (a generator invocation, a snippet against a model, an
23
+ .opt/.adl fixture) that reproduces the bug from a clean checkout. -->
24
+
25
+ ```ruby
26
+ ```
27
+
28
+ ## Expected vs Actual
29
+
30
+ - Expected:
31
+ - Actual:
32
+
33
+ ## Root cause
34
+
35
+ <!-- file:line, if known. Leave blank if not yet investigated -- explore/plan happens
36
+ after filing, not before. -->
37
+
38
+ ## Proposed fix
39
+
40
+ <!-- Optional at filing time; fill in once a plan exists. -->
41
+
42
+ ## Acceptance criteria
43
+
44
+ <!-- Spec-verifiable. E.g.: -->
45
+ - [ ] A reproduction spec for this bug goes red on the current code, then green after
46
+ the fix (see CLAUDE.md's "Ticket-driven workflow": bug = red-first).
@@ -0,0 +1 @@
1
+ blank_issues_enabled: true
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: Enhancement
3
+ about: Propose new behavior or a change to existing behavior
4
+ title: ''
5
+ labels: enhancement
6
+ assignees: ''
7
+ ---
8
+
9
+ ## Motivation
10
+
11
+ <!-- Why this is needed -- what's painful or missing today, and for whom. -->
12
+
13
+ ## Current behavior
14
+
15
+ <!-- What happens now. file:line references if known. -->
16
+
17
+ ## Proposed behavior
18
+
19
+ <!-- What should happen instead/additionally. -->
20
+
21
+ ## Acceptance criteria
22
+
23
+ <!-- Spec-verifiable. E.g.: -->
24
+ - [ ] A spec for the new behavior goes red on the current code, then green once
25
+ implemented (see CLAUDE.md's "Ticket-driven workflow": enhancement = red-first).
26
+
27
+ ## Compatibility notes
28
+
29
+ <!-- Surface this change touches -- check all that apply, and say how: -->
30
+ - [ ] Runtime behavior
31
+ - [ ] Public API
32
+ - [ ] Install-time dependency (gemspec, supported Ruby/Rails versions)
33
+ - [ ] Generator output (`lib/generators/**/templates/` -- migrations/scaffolding
34
+ shipped to and expanded inside host applications; counts as shipped product, see
35
+ CLAUDE.md)
36
+
37
+ <!-- semver impact, if known: -->
@@ -18,7 +18,7 @@ jobs:
18
18
  env:
19
19
  BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/rails_${{ matrix.rails }}.gemfile
20
20
  steps:
21
- - uses: actions/checkout@v4
21
+ - uses: actions/checkout@v7
22
22
  - uses: ruby/setup-ruby@v1
23
23
  with:
24
24
  ruby-version: ${{ matrix.ruby }}
@@ -31,7 +31,7 @@ jobs:
31
31
  runs-on: ubuntu-latest
32
32
  needs: spec
33
33
  steps:
34
- - uses: actions/checkout@v4
34
+ - uses: actions/checkout@v7
35
35
  - uses: ruby/setup-ruby@v1
36
36
  with:
37
37
  ruby-version: '4.0'
@@ -49,7 +49,7 @@ jobs:
49
49
  runs-on: ubuntu-latest
50
50
  needs: spec
51
51
  steps:
52
- - uses: actions/checkout@v4
52
+ - uses: actions/checkout@v7
53
53
  - uses: ruby/setup-ruby@v1
54
54
  with:
55
55
  ruby-version: '4.0'
@@ -12,20 +12,22 @@ jobs:
12
12
  ci:
13
13
  uses: ./.github/workflows/ci.yml
14
14
 
15
- release:
16
- name: Release to RubyGems
15
+ build:
16
+ name: Build gem artifact
17
17
  needs: ci
18
18
  runs-on: ubuntu-latest
19
- permissions:
20
- id-token: write # required for RubyGems Trusted Publishing (OIDC)
21
- contents: read
22
19
  steps:
23
- - uses: actions/checkout@v4
20
+ - uses: actions/checkout@v7
24
21
  - uses: ruby/setup-ruby@v1
25
22
  with:
26
23
  ruby-version: '4.0'
27
24
  bundler-cache: true
28
25
  - name: release:check (clean tree, sibling-file tracking, gemspec validity)
29
26
  run: bundle exec rake release:check
30
- - name: Release
31
- uses: rubygems/release-gem@v1
27
+ - name: Build gem
28
+ run: bundle exec rake build
29
+ - name: Upload gem artifact
30
+ uses: actions/upload-artifact@v7
31
+ with:
32
+ name: gem
33
+ path: pkg/*.gem
data/CHANGELOG.md CHANGED
@@ -7,8 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0] - 2026-08-25
11
+
12
+ ### Added
13
+ - `FieldExtractor` fields now always include `value_set_uri` for external
14
+ `C_CODE_REFERENCE` value sets and `code_bindings` for ontology-level fixed-code
15
+ bindings. `OpenehrRails::Opt::Parser` temporarily enriches OPT terminology objects
16
+ with `term_bindings` until `skoba/openehr-ruby#31` is available upstream.
17
+
18
+ ### Fixed
19
+ - `ProfileGenerator` now emits a required FHIR `binding.valueSet` for
20
+ `DV_CODED_TEXT` fields constrained by `C_CODE_REFERENCE`; these fields previously
21
+ received no binding. Existing local-code-list bindings remain strength-only. Host
22
+ applications must regenerate cached `app/fhir/profiles/*.json` files to receive
23
+ the new bindings.
24
+ - For multi-alternative `value` constraints, `FieldExtractor` now prefers a
25
+ `C_CODE_REFERENCE`-backed alternative. This can change the extracted `rm_type` and
26
+ scaffold column behavior from `DV_TEXT` to `DV_CODED_TEXT` for affected templates.
27
+
28
+ ### Changed
29
+ - Raised the `openehr` dependency floor to 2.3.1 because 2.3.0 cannot parse
30
+ `C_CODE_REFERENCE` constraints (`skoba/openehr-ruby#30`).
31
+
10
32
  ## [0.4.1] - 2026-08-22
11
33
 
34
+ Errata: this release includes minor-level changes (Ruby >= 3.3 requirement,
35
+ OpenehrRails namespace consolidation) and should be treated as a minor release
36
+ when upgrading from 0.4.0.
37
+
12
38
  ### Fixed
13
39
  - `FieldExtractor` now resolves embedded-archetype element terminology in the nearest
14
40
  enclosing `C_ARCHETYPE_ROOT`, preventing both silent at-code collisions with the outer
data/CLAUDE.md CHANGED
@@ -16,12 +16,92 @@ Follow the TDD framework as advocated by t-wada:
16
16
  - Write tests for areas of concern first
17
17
  - opt files must not be changed automatically.
18
18
 
19
+ ## Ticket-driven workflow
20
+
21
+ - A change touching runtime behavior, public API, or install-time dependencies requires
22
+ a GitHub Issue filed before work starts — no code-change commit without one. Changes
23
+ limited to docs, CI, or dev-tooling config are Issue-optional.
24
+ - **This repo's surface for that rule is not just `lib/`**: `lib/generators/**/templates/`
25
+ (the migrations and scaffolding code shipped to, and expanded inside, host
26
+ applications) is shipped product too. Changes there are Issue-required and subject to
27
+ the same semver judgment as any other runtime-behavior change.
28
+ - Write Acceptance criteria in a spec-verifiable form.
29
+ - Three resolution kinds, signaled in the PR body and in spec comments:
30
+ - **bug** — a reproduction spec goes red first, then gets fixed green.
31
+ - **enhancement** — a new-behavior spec goes red first, then gets implemented green.
32
+ - **pin/hardening** — fixing an existing property in place, where red isn't possible.
33
+ Mark this `regression pin` in a spec comment instead of staging a fake red.
34
+ - 1 issue = 1 branch = 1 PR (reaffirms the existing convention); the PR closes with
35
+ `Fixes #N`. A `docs/design/` plan doc opens with the issue number.
36
+
19
37
  ## Working with implementation agents (e.g. Codex)
20
38
 
21
39
  Codex delivers only working-tree changes; it does not commit. Claude Code reviews the
22
40
  diff, then commits, recording the implementer in a commit message trailer (e.g.
23
41
  `Implemented-by: Codex`).
24
42
 
43
+ ## Release convention
44
+
45
+ Before tagging, make the final semver determination from the actual content of
46
+ `[Unreleased]`, not from a pre-assigned version number. If the instructed version number
47
+ contradicts the actual content, stop instead of tagging and ask for re-arbitration.
48
+
49
+ ## Verification
50
+
51
+ - **Verify against the repo before recording a fact in it**, even when a prompt or an
52
+ earlier report already stated it as true - a premise that went unverified once tends
53
+ to get repeated, not corrected, if the next write also skips checking (e.g. "CI is
54
+ unconfigured" repeated across two turns before anyone ran `gh run list`).
55
+ - **The document a gate report points to must be pushed**, not just committed locally,
56
+ before the report is sent - a local-only SHA is unverifiable by anyone reading the
57
+ report. (Added 2026-08-25, after a gate report cited two docs-only commits - the #30
58
+ issue-filing log and its design doc - that were still local-only `master` commits,
59
+ not yet on `origin/master`.)
60
+ - **After a git command appears to lose a file, search git's own storage
61
+ (`git stash show`/`stash@{n}^3`, `git reflog`, `git fsck --unreachable`) before
62
+ reconstructing content from memory.** Reconstruction from a model's own memory of
63
+ a file it recently read is a last resort, and if used, the result must be
64
+ independently diffed against the recovered original before trusting it - matching
65
+ by eye is not enough. (Added 2026-08-25, after a `git stash push -u` with a
66
+ multi-pathspec argument printed a pathspec error for one untracked file and that
67
+ file appeared to vanish from both the working tree and the stash's summary output;
68
+ it was in fact captured in the stash's untracked-files commit the whole time - the
69
+ error was cosmetic. The file was reconstructed from the session's own recent read
70
+ before that was confirmed, and only verified byte-identical against the actual
71
+ stashed copy afterward - the right outcome, but by the wrong order of operations.)
72
+
73
+ ## Repository-context-dependent commands confirm their target explicitly
74
+
75
+ A command whose target (repository, branch, or resumed session) is decided by
76
+ ambient state - cwd, current branch, or session history - rather than an
77
+ explicit argument, must have that target pinned before it runs; never assume
78
+ the shell or session is still where an earlier step left it.
79
+
80
+ - If the tool has an explicit target option, always use it: `git` takes a `cd`
81
+ to the intended directory on the same command line (or `-C <path>`); `gh`
82
+ takes `-R <owner>/<repo>` (or `--repo`) on every invocation.
83
+ - If the tool has no such option (e.g. `codex exec`, `codex exec resume`),
84
+ print `pwd` immediately before the call and confirm it names the intended
85
+ repository first.
86
+ - Before adopting a new repository-context-dependent command for the first
87
+ time, decide how this principle applies to it before using it.
88
+
89
+ (Generalized 2026-08-24, consolidating this repo's prior narrower
90
+ `checkout`/`pull` rule with `openehr-ruby`'s branch-confirmation rule, after a
91
+ third incident of the same class surfaced the need for one shared principle
92
+ covering non-git tools too. Three incidents on record: (1) this repo,
93
+ 2026-08-22 - a mistaken `checkout`/`pull` ran against the wrong repo, caught
94
+ and self-reported immediately, no lasting effect; (2) `openehr-ruby`,
95
+ 2026-08-23 - a docs-only commit intended for `master` landed on a
96
+ checked-out PR feature branch instead; (3) `anlage`, 2026-08-24 - `codex exec
97
+ resume --last`, run after cwd had silently drifted back to `openehr-ruby`,
98
+ resumed an unrelated stale session in the wrong repo instead of the intended
99
+ one; Codex itself detected the mismatch and made no changes, so there was no
100
+ lasting effect, but the near-miss is what prompted this generalization. See
101
+ `openehr-ruby`'s own copy of this rule and its `docs/backlog.md` entry
102
+ logging the underlying structural fix under consideration - one
103
+ worktree/session per repo instead of per-command vigilance.)
104
+
25
105
  ## Project Overview
26
106
 
27
107
  This is `openehr-rails`, a Rails engine gem that turns an openEHR Operational Template (`.opt`, ADL2/XML) into a working Rails resource in one command: `rails generate openehr:scaffold path/to/template.opt --fhir` emits a model, migration, controller, views, i18n locale, and (with `--fhir`) HL7 FHIR R5 `StructureDefinition` profiles. Generated models persist both as typed columns (for forms/search) and as full openEHR RM data (canonical JSON + a typed node graph with immutable-append versioning), and are queryable via a growing AQL surface. A mountable admin engine (`/openehr`) provides template upload/management, runtime scaffolding, and a FHIR R5 facade. Legacy ADL-archetype-only generators (model/controller/migration/helper/assets/i18n/template/template_model, based on `Openehr::Generators::ArchetypedBase`) have been removed — OPT is the only supported input format for scaffolding.
@@ -69,6 +149,28 @@ This is `openehr-rails`, a Rails engine gem that turns an openEHR Operational Te
69
149
  - `spec/openehr_rails/{opt,rm,fhir}/`, `spec/openehr_rails/*_spec.rb` - runtime library specs.
70
150
  - `spec/models/openehr_template_spec.rb`, `spec/unit/opt_parser_spec.rb` - registry model and parser specs.
71
151
  - OPT fixtures live in `spec/generators/templates/` and `spec/templates/`; do not hand-edit an existing `.opt` fixture (add a new one instead) — **opt files must not be changed automatically.**
152
+ - Fixtures fall into four kinds; each fixture's leading comment must say which kind it is:
153
+ - **real** — a genuine artifact (CKM export, Archetype Designer output, a real host-app
154
+ template), used as-is.
155
+ - **reduced** — a trimmed-down real artifact; the comment must name the real source it
156
+ was reduced from.
157
+ - **synthetic** — hand-authored, not derived from any real artifact. real/reduced are
158
+ preferred by default; synthetic is only for structural test cases whose reproduction
159
+ conditions can't be controlled with a real artifact. The leading comment must say it's
160
+ synthetic and cite its design authority (e.g. a design doc section). Archetype
161
+ IDs/at-codes should use self-evidently invented names that can't be mistaken for real
162
+ ones — don't rename an existing fixture to fix this after the fact; its at-codes/
163
+ archetype IDs are reference anchors other specs/docs already point to, and freezing
164
+ those anchors takes priority.
165
+ - **security** — built to exercise an attack/abuse case; the comment must say it is not
166
+ a clinical artifact.
167
+ - A fixture's provenance comment must describe its lineage as measured (checked against
168
+ the actual design/implementation record), not as instructed — if an instructed lineage
169
+ doesn't match what actually went into the fixture, write it to match reality instead.
170
+ - Example: `spec/templates/lab_result_report_reduced.opt` is **synthetic** (design
171
+ authority: `docs/design/fix-terminology-scope-plan.md` §4; lineage confirmed
172
+ 2026-08-22) — its filename says "reduced" for historical reasons, but per this
173
+ convention its actual kind is synthetic; the name stays as-is (reference anchor).
72
174
 
73
175
  ## Development Notes
74
176
 
data/docs/backlog.md ADDED
@@ -0,0 +1,140 @@
1
+ # Backlog
2
+
3
+ Non-blocking follow-ups noted during work on the upstream sprint queue. Not scheduled;
4
+ pick up when the relevant gate opens or when convenient alongside other work in the same
5
+ area. No code changes accompany entries here — this file is a record only.
6
+
7
+ ## CI status (verified, not a follow-up item)
8
+
9
+ Both `.github/workflows/ci.yml` (`rspec` matrix on Ruby 3.3/3.4/4.0 x Rails
10
+ 7.2/8.0/8.1, plus `demo-smoke` and `application template smoke test` jobs; triggers
11
+ on `push` to `master`, all `pull_request`s, and `workflow_call`) and
12
+ `.github/workflows/release.yml` (triggers on `v*` tags, reuses `ci.yml` via
13
+ `workflow_call`, then runs a RubyGems release job) exist on `master` — introduced at
14
+ `412712d` (2026-08-12) and `2263298` (2026-08-13) respectively — and were confirmed
15
+ actually running, not just present:
16
+
17
+ - PR #26 (`fix/field-extractor-terminology-scope`): `pull_request` runs `32549486071`
18
+ and `32550157259` (2026-08-22, both success), post-merge `master` `push` run
19
+ `32550193330` (success). The merge landed (03:53:04Z) about 1m43s before the final
20
+ PR run finished (03:54:47Z) — CI ran and passed, but this doesn't demonstrate
21
+ merge-blocking enforcement.
22
+ - Tag `v0.4.1`: `release.yml` run `32550344344` (2026-08-22T03:56:26Z) — all 11 reused
23
+ CI jobs green, but the run's overall conclusion is **failure**: the `Release to
24
+ RubyGems` job's `Release` step (`rubygems/release-gem@v1`) fails at "Configure
25
+ trusted publishing credentials" ("No trusted publisher configured for this workflow
26
+ found on https://rubygems.org for audience rubygems.org"); the actual gem-push
27
+ sub-steps are skipped, so CI never attempted to publish. rubygems.org's 0.4.1
28
+ listing was published by the human running `gem push` manually — no harm to the
29
+ actual release, only to the workflow run's color. Same failure shape on every tag
30
+ to date: v0.3.0 (runs `31655140867`, `31655495221`, `31655778244`) and v0.4.0 (run
31
+ `31660884406`), both failure. **This is structural, not incidental**: as long as
32
+ `release.yml` keeps a live RubyGems-publish step while the actual publish stays a
33
+ manual human `gem push` (the current, intended operating model), every future tag
34
+ push will reproduce the same red run. See "Release automation" below.
35
+ - Most recent `master` push at the time of this record (`4055ec3`): CI run
36
+ `32569774700`, success.
37
+
38
+ Recorded here after this file previously claimed "this repo currently has no CI
39
+ workflow gating pull requests" — wrong on both existence and execution. This file is
40
+ the primary record for openehr-rails CI/release facts; openehr-ruby's own
41
+ `docs/backlog.md` defers to it rather than duplicating (see that file's 2026-08-23
42
+ correction, commit `bf17be7`) — do not duplicate this record back into openehr-ruby.
43
+
44
+ **Release automation fix landed (2026-08-23, PR #28, `Fixes #27`)**: `release.yml`'s
45
+ RubyGems-publish job is gone; tag pushes now run `ci` + `rake build` +
46
+ `actions/upload-artifact` only (see "Release automation" below for the item this
47
+ closes). Also bumped `actions/checkout` v4 -> v7 to clear the Node 20 deprecation
48
+ warning noted in the v0.4.1 entry above. Verified, not just green: PR #28's own
49
+ `pull_request` run `32611109196` — all 11 `ci.yml` jobs success, and the Node 20
50
+ deprecation annotation is gone from every one of those 11 jobs (checked via the
51
+ GitHub check-runs annotations API, not just the run log — each job's annotations
52
+ array is empty, `[]`). Post-merge `master` `push` run `32611237453` — success. The
53
+ renamed `build` job in `release.yml` (with `actions/checkout@v7` and the new
54
+ `actions/upload-artifact@v7` step) is tag-triggered only and was not exercised by
55
+ either of those runs; per PR #28's own body, no test tag was pushed to verify it —
56
+ that verification is deferred to the next real release (>= 0.5.0), not simulated.
57
+
58
+ ## Release automation
59
+
60
+ **Done (2026-08-23, PR #28)** — kept below for the original rationale; see the CI
61
+ status entry above for verification details.
62
+
63
+ - **Unify the release path**: remove `release.yml`'s RubyGems-publish job/step and
64
+ change tag-push handling to CI + `gem build` + artifact upload only, so the workflow
65
+ matches how releases are actually done today (human-gated `gem push`) and stops
66
+ going red on every tag for a step that was never meant to run automatically.
67
+ Automatic publishing via RubyGems Trusted Publishing can be re-evaluated when the
68
+ project's planned December public release and external-contributor model are
69
+ actually being designed — revisit the tag-before-inventory convention (`CLAUDE.md`'s
70
+ "Release convention" section) together with that decision at the same time, since
71
+ automatic publishing changes what "ready to tag" needs to mean. Timing: before the
72
+ next release (>= 0.5.0, per the "Versioning" item below). Out of scope for this
73
+ docs-only pass — implementing the workflow change goes through an Issue (once
74
+ ticket-driven work applies to it) plus the normal explore → plan → approval gate,
75
+ not a direct docs commit.
76
+
77
+ ## From #25 / PR #26 (FieldExtractor terminology scope fix, 2026-08-22)
78
+
79
+ - **Multi-level nesting regression test (CLUSTER in CLUSTER)**: the 0.4.1 fix and its
80
+ regression spec (`spec/openehr_rails/opt/field_extractor_embedded_archetype_spec.rb`)
81
+ cover one level of embedding (entry -> embedded CLUSTER). The underlying walk in
82
+ `FieldExtractor#collect_elements` is recursive and should handle a CLUSTER embedded
83
+ inside another embedded CLUSTER the same way, but this is currently unverified by any
84
+ test. Add a fixture/spec covering two levels of `C_ARCHETYPE_ROOT` nesting (openehr-ruby's
85
+ `spec/lib/openehr/opt_parser/eReferral.opt` already has a real two-level case:
86
+ `OBSERVATION.lab_test` -> `OBSERVATION.imaging` -> `CLUSTER.imaging`, per
87
+ `docs/design/fix-terminology-scope-plan.md` section 4). Suitable for a follow-on PR, not
88
+ urgent.
89
+
90
+ ## Compatibility
91
+
92
+ - **STRICT-incompatible fixture: 1 known case** — `spec/templates/lab_result_report_reduced.opt`'s
93
+ leading comment uses `--` as an em dash (a double hyphen, invalid inside an XML comment);
94
+ under STRICT-mode XML parsing this file would fail to parse at all. See
95
+ openehr-ruby#36. Not fixed now — the current form is a live reproduction case for #36; if
96
+ #36 moves toward making STRICT the default, this comment's punctuation is the prerequisite
97
+ fix on this repo's side.
98
+
99
+ ## Fixture conventions
100
+
101
+ - **Licensed terminology-code literals in spec expectations: keep minimal, cite the
102
+ source fixture's file:line.** Adopted from Anlage's C2 firewall precedent (SNOMED
103
+ CT is a licensed terminology; reproducing its codes verbatim in more places than
104
+ necessary widens exposure for no test-coverage benefit). Applies to SNOMED CT
105
+ specifically; **LOINC is exempt** (permissively licensed). Current count (#30,
106
+ 2026-08-25): **2 SNOMED literal occurrences** in spec expectation code, both the
107
+ same code value `60621009`, both traceable to the same source fixture line --
108
+ `spec/openehr_rails/opt/field_extractor_binding_spec.rb:40` and
109
+ `spec/openehr_rails/opt/parser_term_bindings_spec.rb:28`, both citing
110
+ `spec/templates/bmi_calculation_without_uid.opt:1689` (and the identical
111
+ `spec/generators/templates/bmi_calculation.opt:1692`). No new SNOMED literal was
112
+ introduced by #30 -- reused the code already present in these existing fixtures.
113
+
114
+ ## Versioning
115
+
116
+ - **Next release must be >= 0.5.0, regardless of its own content**, to retroactively
117
+ acknowledge in the version series that 0.4.1 was substantively a minor release (see the
118
+ errata in `CHANGELOG.md`'s `[0.4.1]` entry and the release convention added to
119
+ `CLAUDE.md`). Applies even if the next release's own changes would otherwise only
120
+ warrant a patch bump.
121
+
122
+ ## December public release prep
123
+
124
+ - **Issue templates: done (2026-08-23, #29)** — `.github/ISSUE_TEMPLATE/` (bug_report,
125
+ enhancement, config.yml) is in place, along with `CLAUDE.md`'s "Ticket-driven
126
+ workflow" section.
127
+ - **demo_assets README**: deferred to December prep. Note: no prior record of this
128
+ deferral was found anywhere in this repo's docs (`docs/`, `CLAUDE.md`,
129
+ `demo_assets/`) at the time of writing this entry — `demo_assets/` currently has no
130
+ README at all, only `demo_seed.rb` and `templates/`. Recording it here now as the
131
+ first record, not as confirmation of an earlier one.
132
+
133
+ ## Queue gating (do not start without an explicit go-ahead)
134
+
135
+ - **#3** (registry checksum/version/status): gated on Anlage Slice 1 operational experience,
136
+ targeted around October.
137
+ - **#4** (ValueBuilders extraction): gated on Anlage Slice 4 stabilizing and Anlage's
138
+ duplicate-method inventory being produced first.
139
+ - **#2** (constraint -> HTML attribute mapping extraction): gated on a generality decision
140
+ after Anlage Slice 4; whether to even start is undecided.