Release v1.12.0 — Immunopeptidomics Measurements & Story Tracking Structure#1455
Closed
sven1103-agent wants to merge 19 commits into
Closed
Release v1.12.0 — Immunopeptidomics Measurements & Story Tracking Structure#1455sven1103-agent wants to merge 19 commits into
sven1103-agent wants to merge 19 commits into
Conversation
…try (#1433) * docs: add immunopeptidomics measurement requirements to PRD and registry - Update PRD §1 and §3 to include immunopeptidomics in measurement scope - Add MEASUREMENT-R-01 through R-04 for registration, editing, deletion, and viewing - Add DATA-R-01 through R-03 for raw dataset view, upload, and download Refs: #1412 * docs: add Features and User Stories Tracker Adds docs/features.md as the stakeholder-visible companion to the PRD, tracking active Features, their Stories, and their live GitHub status. Includes FEAT-IMMUNOPEPTIDOMICS-MEASUREMENT as the first tracked feature with all 5 Stories, 5 implementation Tasks, and 1 integration-test Task. Refs: #1412 --------- Co-authored-by: sven1103-agent <261423644+sven1103-agent@users.noreply.github.com>
Adds the stakeholder-provided Excel template and a diffable README manifest to docs/stakeholder-artifacts/measurement-metadata/. - immunopeptidomics-registration-spec-v1.0-2026-05-11.xlsx: Authoritative stakeholder artifact with 'Metadata' and 'Property information' sheets defining all 22 registration fields (14 mandatory, 8 optional), their allowed values, and descriptions. - README.md: Diffable manifest reproducing the 'Property information' sheet verbatim, sorted by provision (mandatory first) then alphabetically by column header. Includes traceability links to MEASUREMENT-R-01, MEASUREMENT-R-02, FEAT-IMMUNOPEPTIDOMICS-MEASUREMENT, and GitHub Stories #1428/#1429. Refs: MEASUREMENT-R-01, MEASUREMENT-R-02 Related: #1428, #1429, #1413, #1414
Adds the stakeholder-provided Excel template and a diffable README manifest to docs/stakeholder-artifacts/measurement-metadata/. - immunopeptidomics-registration-spec-v1.0-2026-05-11.xlsx: Authoritative stakeholder artifact with 'Metadata' and 'Property information' sheets defining all 22 registration fields (14 mandatory, 8 optional), their allowed values, and descriptions. - README.md: Diffable manifest reproducing the 'Property information' sheet verbatim, sorted by provision (mandatory first) then alphabetically by column header. Includes traceability links to MEASUREMENT-R-01, MEASUREMENT-R-02, FEAT-IMMUNOPEPTIDOMICS-MEASUREMENT, and GitHub Stories #1428/#1429. Refs: MEASUREMENT-R-01, MEASUREMENT-R-02 Related: #1428, #1429, #1413, #1414
* feat: register immunopeptidomics measurements via Excel template (#1413) Implements the registration of immunopeptidomics measurements following the existing NGS/proteomics parallel-stack pattern. Domain: - Add IP to MeasurementCode.MEASUREMENT_PREFIX - Create ImmunopeptidomicsMeasurement aggregate - Create IPMeasurementEntry embeddable metadata - Create IPMethodMetadata record Repository & OpenBIS: - Add ImmunopeptidomicsMeasurementJpaRepo - Extend MeasurementRepository with IP methods - Extend MeasurementDataRepo and OpenbisConnector with Q_IP_MEASUREMENT - Add IP support to MeasurementRepositoryImplementation Application: - Add MeasurementRegistrationInformationIP / MeasurementSpecificIP to AsyncProjectService - Add registerMeasurementIP and toDomain conversion to MeasurementService - Add MeasurementIPValidator with mandatory field checks - Wire IP validation into MeasurementValidationService UI & Parsing: - Add IMMUNOPEPTIDOMICS to MeasurementType - Add IPMeasurementRegisterColumn enum matching template fields - Add MeasurementRegistrationMetadataConverterIP - Add MeasurementRegistrationProcessorIP for pool merging - Register IP converter and processor - Add Immunopeptidomics template to MeasurementTemplateSelectionComponent - Wire IP submit flow in MeasurementMain and MeasurementUpload Infrastructure: - Add IpRegisterFactory and IPWorkbooks for template generation - Add immunopeptidomics_measurement_registration_sheet.xlsx template SQL: - Extend project_measurements view with amountIpMeasurements - Extend project_overview view with amountIpMeasurements Refs: #1413, #1428 * fix(schema): add missing ip_measurements and specific_measurement_metadata_ip tables Adds the required base tables for immunopeptidomics measurements: - ip_measurements: aggregate table for IP measurement entities - specific_measurement_metadata_ip: collection table for sample-specific IP metadata entries per measurement Refs: #1413 * refactor(ip): move all measurement fields to measurement level, simplify specific metadata For immunopeptidomics there is no per-sample metadata beyond the sample ID itself. All template fields are measurement-level (shared across all samples in a pool). Changes: - IPMethodMetadata: expanded to carry all measurement-level fields - ImmunopeptidomicsMeasurement: constructor now sets all fields from method - IPMeasurementEntry: simplified to just measuredSample (SampleId) - specific_measurement_metadata_ip table: reduced to measurement_id + sample_id - MeasurementService.toDomain: extracts measurement-level fields from the first MeasurementSpecificIP entry, creates simplified IPMeasurementEntry instances with only sample IDs Refs: #1413 * Add amountIpMeasurements to project_overview and project_measurements SQL views * fix: remove asterisk suffix from IP measurement column headers The IPMeasurementRegisterColumn enum in datamanager-app contained asterisk (*) suffixes in header names (e.g. 'QBiC Sample Id*'). This caused a mismatch with: - The template generator in project-management-infrastructure, which uses plain headers without * - The file parser's Sanitizer.headerEncoder(), which strips * - The validator's IP_PROPERTY labels, which also use plain names Because the parsed columnMap contained keys without * but the converter searched for keys with *, every lookup missed and returned empty strings. The validator then correctly reported all mandatory fields as missing even when they were provided. This fix removes the * suffixes from all 14 affected headers, aligning them with the template generator, parser, and validator. Closes #1413 * fix: add missing columns to ip_measurements DDL The ImmunopeptidomicsMeasurement JPA entity defines six fields that were not present in the ip_measurements CREATE TABLE statement: - sampleMass (double) - sampleVolume (double) - cycleFractionName (varchar) - prepDate (date) - msRunDate (date) - comment (varchar) Without these columns, Hibernate fails with SQLGrammarException 'Unknown column im1_0.comment in SELECT' (and similar for the other columns) when persisting or loading immunopeptidomics measurements. This fix aligns the DDL with the JPA entity so that measurement registration works end-to-end. Related to #1413 * Add immunopeptidomics measurement lookup and UI tab - Create IpMeasurementLookup API interface with MeasurementInfo, SampleInfo, Instrument, Organisation, IpSortKey, and MeasurementFilter - Create IpMeasurementJpaRepository with read-only JPA entities IpMeasurementInformation and IpSampleInfo, plus IpMeasurementFilter - Extend MeasurementLookup to implement IpMeasurementLookup - Extend MeasurementLookupService to count IP measurements and find by ID - Add deleteIpMeasurements to MeasurementService - Extend MeasurementDetailsComponent with Immunopeptidomics tab: grid, search, pooled sample dialog, delete, registration events - Wire IpMeasurementLookup and IP event handlers in MeasurementMain This makes IP- prefixed measurement codes user-facing and closes the gap between registration and display for immunopeptidomics measurements. * refactor(ip): align Excel column order with stakeholder spec and fix missing mandatory validations Aligns the immunopeptidomics measurement registration template column order with the authoritative stakeholder specification (docs/stakeholder-artifacts/measurement-metadata/README.md): - Reorder all 22 fields to match stakeholder positions exactly (e.g., Cycle/Fraction Name at 3, Sample Mass at 4, Facility at 10, Organisation URL at 11, Data Acquisition at 13, Charge range at 17, Mass range at 19, Retention time range at 20) - Add missing mandatory validations for Sample Mass and Sample Volume in MeasurementIPValidator (application layer) and ImmunopeptidomicsMeasurement.evaluateMandatoryMetadata (domain layer) - Add missing mandatory validation for Retention time range in domain model - Update tests to match new column order and expected failure counts Refs: MEASUREMENT-R-01, #1413, #1428 * feat(ip): align template descriptions with stakeholder spec and add template tests Updates the immunopeptidomics measurement registration template to use descriptions and example values that match the authoritative stakeholder specification exactly (docs/stakeholder-artifacts/measurement-metadata/README.md). Changes: - Fix instrument CURIE example from EFO:0008633 to EFO:0008637 in both enums - Update all 22 column descriptions to match stakeholder spec verbatim - Keep asterisks on mandatory headers (intentional UX choice) - Ensure both IPMeasurementRegisterColumn enums (infrastructure + datamanager-app) remain identical to prevent template/parser drift New tests: - IpRegisterFactorySpec (7 tests): validates column order, mandatory flags, example values, descriptions, and header names against the spec - IPMeasurementRegisterColumnSyncSpec (1 test): uses reflection to assert both enum copies are in sync (headerName, index, mandatory, readOnly, exampleValue, description) Refs: MEASUREMENT-R-01, #1413, #1428 * fix(ip): shorten sheet name and description to fit Excel/POI limits Fixes two runtime issues when downloading the immunopeptidomics registration template from the UI: 1. Crash: description exceeds POI's 255-char limit The SAMPLE_NAME column description was 261 characters, causing XSSFDataValidation.createPromptBox() to throw IllegalStateException. Truncated to 254 characters in both enum copies while preserving meaning. 2. Warning: sheet name exceeds Excel's 31-char limit Changed sheet name from "Immunopeptidomics Measurement Metadata" (38 chars) to "IP Measurement Metadata" (23 chars) to avoid POI silently trimming it. New tests: - IPMeasurementRegisterColumnDescriptionLengthSpec in both modules: asserts every column description is <= 255 chars, preventing future crashes if descriptions are updated from the stakeholder spec. Refs: MEASUREMENT-R-01, #1413, #1428 * feat(ip): add all available columns to the immunopeptidomics measurement grid Adds the 3 missing columns that were available in the backend lookup DTO but not shown in the UI grid: - MHC Typing Method - Retention Time Range - Ion Mobility Range Backend changes: - Added sort keys MHC_TYPING_METHOD, RETENTION_TIME_RANGE, ION_MOBILITY_RANGE to IpSortKey enum for server-side sorting - Added the 3 fields to the global search term filter so they are searchable UI changes: - Added the 3 columns to createIpGrid() in MeasurementDetailsComponent - Columns are sortable, auto-width, and resizable (matching existing columns) The FilterGrid component already provides a Show/Hide Columns menu via CheckboxGroup<Column<T>>, so users can toggle visibility of any column. Refs: MEASUREMENT-R-01, #1413, #1428 * fix(ip): handle Excel numeric cell formatting in retention time parsing When a user enters a whole number like '120' in the Excel template for 'Retention time range (min)', Excel stores it as a numeric cell. The XLSXParser reads numeric cells via Double.toString(), producing '120.0'. The existing parseIntegerOrNull() helper only used Integer.parseInt(), which throws NumberFormatException on '120.0', causing the value to become null. The domain model then rejected it as 'Missing metadata'. Fix: parseIntegerOrNull() now falls back to Double.parseDouble() when Integer.parseInt() fails, accepting the value only if it represents a whole number (e.g. '120.0' -> 120). True decimals like '120.5' are still rejected (return null). New test: MeasurementServiceIntegerParsingSpec validates that: - plain integers parse correctly ('120' -> 120) - Excel numeric formatting parses correctly ('120.0' -> 120) - true decimals are rejected ('120.5' -> null) - blank and non-numeric inputs return null Refs: MEASUREMENT-R-01, #1413, #1428 * fix(ip): add IP measurement lookup in UpdateProjectUponMeasurementCreation The background job 'Update project upon creation of measurement' was failing with 'Measurement not found' for all immunopeptidomics (IP) measurements because the handler only looked up NGS and Proteomics (PxP) measurements, never checking the IP repository. This was not a race condition. The event dispatch happens after the JPA transaction commits, so the measurement is in the DB when the JobRunr job runs. The issue was simply a missing lookup branch. Changes: - UpdateProjectUponMeasurementCreation.updateProjectModified() now also queries measurementLookupService.findIPMeasurementById() when both NGS and Proteomics lookups return empty. - Added Spock spec with 4 tests covering NGS, Proteomics, IP, and 'not found' paths. Refs: MEASUREMENT-R-01, #1413, #1428 * fix(ip): address reviewer findings for immunopeptidomics measurement registration - Add TEAL tag color for immunopeptidomics to distinguish from proteomics - Expose missing measurement-level fields in lookup/grid: prepDate, msRunDate, cycleFractionName, sampleMass, sampleVolume - Fix validator message format and add missing validations: * facility check, negative value checks for sampleMass/sampleVolume/retentionTimeRange * date format checks for prepDate/msRunDate (YYYY-MM-DD) * range format checks for massRange/chargeRange/ionMobilityRange - Add Spock tests for new validation rules - Implement export template backend pipeline for IP measurements: * MeasurementInformationIP/CollectionIP/SpecificIP records in TemplateProvider * IPMeasurementEditColumn enum and IpEditFactory for workbook generation * TemplateProviderOpenXML handling, TemplateService query+convert logic * AsyncProjectService measurementUpdateIP endpoint - Wire export button in UI: IpMeasurementExportRequested event, listener, and downloadIPMetadata handler in MeasurementMain Edit functionality intentionally out of scope (separate user story). * fix(ip): handle Excel numeric cell formatting in retention time validation Excel numeric cells are parsed as doubles (e.g. 90 -> "90.0"), which caused Integer.parseInt to throw NumberFormatException. Use the same Double.parseDouble + whole-number check pattern already employed by MeasurementService.parseIntegerOrNull().
…tidomics-measurements-via-excel-template
…r-immunopeptidomics-measurements-via-excel-template [Story] Register Immunopeptidomics Measurements via Excel Template (#1428)
…pre-filled Excel template Implements IP measurement editing following the same parallel-stack pattern used by NGS and Proteomics edit flows (Story #1429, Task #1414). ## Domain & Application Layer - AsyncProjectService: Added MeasurementUpdateInformationIP record with measurementId, organisationId, instrumentCURIE, facility, samplePoolGroup, specificMetadata (MeasurementSpecificIP), and measurementName. Extended MeasurementUpdateRequestBody and ValidationRequestBody sealed interfaces. - MeasurementService: Added updateMeasurementIP(), performUpdateIP(), toDomainUpdate() for ImmunopeptidomicsMeasurement updates with proper validation (missing ID, unknown measurement, org/instrument lookup). - MeasurementIPValidator: Added validateUpdate() with ValidationPolicy inner class validating measurementId, organisation, instrument, and all mandatory IP fields (sampleMass, sampleVolume, MHC antibody, etc.). - MeasurementValidationService: Added validateIP() overload for MeasurementUpdateInformationIP updates. - AsyncProjectServiceImpl: Wired IP update case in updateMeasurement() and validateRequest() switches; added updateMeasurementIP() and validateMeasurementMetadataIPUpdate() helpers. ## UI Layer - IPMeasurementEditColumn: New column enum mirroring infrastructure enum, with 25 columns (Measurement ID, QBiC Sample Id, Sample Name, etc.) - MeasurementUpdateMetadataConverterIP: New converter parsing Excel rows into MeasurementUpdateInformationIP, only mapping editable columns. - MeasurementUpdateProcessorIP: New processor grouping by measurementId and merging pooled IP measurements. - ConverterRegistry / ProcessorRegistry: Registered new IP update classes. - MeasurementUpload: Added case for MeasurementUpdateInformationIP. - MeasurementDetailsComponent: Added IpMeasurementEditRequested event with addIpEditListener(), plus Edit button on IP grid. - MeasurementMain: Added ipEditDialog() wired to addIpEditListener(), extended UpdateRequestPackage with IP support. ## Tests All tests pass (160 project-management, 29 datamanager-app). Requirement IDs: MEASUREMENT-R-02
…validator The validateMeasurementCode method in MeasurementIPValidator was calling measurementService.findIPMeasurementById(null, measurementCode), which triggered IllegalArgumentException: identifier required in Spring Security ACL's ObjectIdentityImpl because null projectId is not a valid ACL object identity. Fix: accept ProjectId parameter and pass projectId.value() to the lookup. The projectId was already available at the validateUpdate call site. All tests pass (160 project-management, 29 datamanager-app).
…lidator
MeasurementIPValidator.validateMeasurementCode was calling
findIPMeasurementById(projectId.value(), measurementCode), which parses
the input as a MeasurementId (internal UUID). However, the Excel template's
'Measurement ID' column contains the human-readable measurement CODE
(e.g. IP-001), not the internal UUID. MeasurementId.parse('IP-001') throws
IllegalArgumentException, which was caught silently, returning Optional.empty()
and causing valid measurements to be reported as 'Unknown measurement'.
Fix:
- Add findIPMeasurement(String) to MeasurementService and MeasurementLookupService
- Update validateMeasurementCode to use findIPMeasurement(measurementCode)
- Remove unnecessary ProjectId parameter from validateMeasurementCode
This follows the exact same pattern used by NGS (findNGSMeasurement)
and PxP (findProteomicsMeasurement) validators.
All tests pass (160 project-management, 29 datamanager-app).
Prevent NoSuchElementException when specificMetadata is empty by adding an explicit null/empty check before iterator().next(). All tests pass (160 project-management, 29 datamanager-app).
Add 6 tests covering the IP measurement update validation path: - Happy path: valid update returns successful result - Blank measurement ID: returns failure - Unknown measurement code: returns failure - Missing mandatory fields: returns failures - Unknown instrument: returns instrument failure - Invalid ROR organisation: returns ROR format failure All 21 tests pass (15 existing registration + 6 new update).
- Add comment field to edit template export data model (MeasurementInformationIP record)
- Add instrumentName field to update/registration data flow (MeasurementUpdateInformationIP and MeasurementRegistrationInformationIP records)
- Add date validation to update flow for prepDate and msRunDate
- Remove duplicate validation error messages for instrument, measurement ID, and organisation
- Fix capitalization inconsistency in error message ('Measurement ID' vs 'Measurement id')
- Update processor classes to include instrumentName parameter
- Update test specifications to reflect new record structures
Addresses bugs:
1. Missing comment field in edit template export
2. Instrument name not persisted (stored as empty string)
3. Missing date validation in update flow
4. Duplicate validation error for instrument
5. Duplicate validation error for measurementId
6. Instrument name in exported sheet
7. Comment in exported sheet
…munopeptidomics-measurements-via-pre-filled-excel-template feat: edit immunopeptidomics measurements via pre-filled Excel template
…idomics measurements (#1447) * Fixes #1430: Implement deletion guard and OpenBIS sync for Immunopeptidomics measurements * Fix compilation error: Correctly implement deleteAllIP with overloaded private method * Fix: Add deleteImmunopeptidomicsMeasurements to MockConnector * Fix: Add deletion success notification with count for all measurement types (Addresses AC)
* Story #1432: Implement Immunopeptidomics raw datasets view - Add LocalRawDatasetIpEntry and LocalRawDatasetIpJpaRepository - Extend LocalRawDatasetRepository and LocalRawDatasetLookupService with IP methods - Add RawDatasetInformationIp record and API methods in AsyncProjectService/Impl - Update RawDataDetailsComponent to include IP tab with filtering, grids, and export - Extend RemoteRawDataService.hasRawData() to check for IP measurements - Optimize v_ip_measurement_sample_json view to use ip_measurement_sample_summary table - Add sql/seed_ip_measurement_sample_summary.sql for one-time historical data migration - Update LocalRawDatasetCache to automatically sync the summary table on new data * refactor: remove materialized ip_measurement_sample_summary table, switch to correlated subquery view The materialized table was introduced as a performance optimization but had an inconsistency bug — deletions from ip_measurements were never reflected in the summary. Since IP has a 1:1 sample-to-measurement relationship, correlated subqueries (same pattern as NGS and PxP views) are performant. - Drop ip_measurement_sample_summary table - Rewrite v_ip_measurement_sample_json as a pure view with correlated subqueries (matching v_ngs_measurement_sample_json / v_pxp_measurement_sample_json) - Remove LocalRawDatasetCache.updateIpSummary() — no longer needed - Delete seed_ip_measurement_sample_summary.sql Additionally ensure FK and index exist on specific_measurement_metadata_ip to enable eq_ref joins (matching NGS/PxP query plan). * refactor: remove unnecessary composite indexes on specific_measurement_metadata_ip The composite index (measurement_id, sample_id) is not needed — the query plan uses measurement_id for the indexed lookup and the sample_id index (with FK) provides eq_ref joins. * refactor: remove unnecessary composite indexes on NGS and PxP specific measurement tables The composite indexes (measurement_id, sample_id) are not needed — the query plan uses the single-column measurement_id index for the correlated subquery lookup. * chore: add sample_id index and FK on NGS specific_measurement_metadata table NGS was missing both the sample_id index and the FK constraint to the sample table. This patch adds them for consistency with PxP and IP, ensuring FK insert/update performance and optimizer trust for joins. * docs: add migration guide for materialized table removal and index optimization Closes the gap where SQL schema changes had no deploy instructions for existing production databases. The migration document covers: - Dropping ip_measurement_sample_summary (was inconsistent on delete) - Recreating v_ip_measurement_sample_json as a pure view with correlated subqueries (same pattern as NGS/PxP) - Removing 3 unused composite indexes - Adding sample_id indexes to all 3 specific_measurement_metadata tables - Adding missing FK constraint on NGS table Includes pre-flight checks, step-by-step SQL, verification queries, and rollback plan. --------- Co-authored-by: Sven Fillinger <sven.fillinger@qbic.uni-tuebingen.de>
* fix: Add Immunopeptidomics domain tag to Project Summary view - Add GOLD color to TagColor enum (#FFF3CC fill, #A68500 text per Figma) - Add .tag.gold CSS rule in span.css - Fix ProjectSummaryComponent.buildTags() to include IP measurements - Update ProjectCollectionComponent to use GOLD instead of TEAL - Update TagFactory to use goldTag() for immunopeptidomics * chore: Remove .run/ directory from tracking
- Rewrite docs/features.md: story ID schema (FEAT-<SLUG>-<NN>), full story content with narrative and acceptance criteria, task section removed (tasks are GitHub-only) - Update AGENTS.md: Story ID Schema section, Story Lifecycle workflow, Creating Stories section, Key Files Quick Reference - Migrate FEAT-IP-MEAS-01 through FEAT-IP-MEAS-05 with complete story content from existing GitHub issues #1428-#1432
11076f7 to
34299c5
Compare
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Release Summary — v1.12.0
Feature: FEAT-IMMUNOPEPTIDOMICS-MEASUREMENT
What's included
All changes on
developmentsince the last release onmain— 18 commits — spanning two delivery streams:1. Immunopeptidomics Measurement Lifecycle (FEAT-IP-MEAS)
Full feature for managing immunopeptidomics measurements, covering all 5 stories:
FEAT-IP-MEAS-01IP-prefixed codesFEAT-IP-MEAS-02FEAT-IP-MEAS-03FEAT-IP-MEAS-04FEAT-IP-MEAS-05Bugfixes included: null-safety guard in update path, measurement code lookup fix, ACL-projectId fix, missing domain tag in Project Summary view.
OpenBIS integration: New dedicated object type for immunopeptidomics measurements (
LAB-C-01constraint — coordinated with lab integration team).2. Story Tracking Structure (#1452)
Stable tracking of user stories with IDs, lifecycle workflow, and stakeholder-facing documentation:
FEAT-<SLUG>-<NN>(e.g.,FEAT-IP-MEAS-01)docs/features.mdand GitHub)docs/features.mdrewritten with full story content, acceptance criteria, status trackingAGENTS.mdupdated with Story ID Schema, Story Lifecycle, and Creating Stories guidancePRs included
Changes
docs/features.mdAGENTS.mdNotes
IP-prefix inMeasurementCodeenum, newIMMUNOPEPTIDOMICSUI domain tagRelease checklist
maincreate-release.ymlworkflow (auto-generates GitHub release changelog from PR titles)