You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Smartphrase: estimands and intercurrent events as smartphrases
Sub-issue of #9. The smartphrase layer demonstrated in #9 expresses an analysis; this extends it to express an estimand.
Purpose
Make ICH E9(R1) estimands a first-class thing the smartphrase layer can author and read back, so that an SAP passage carrying an estimand description and the model instance behind it remain two views of one thing — the same claim #9 makes for analyses.
The motivating observation is that four of the five E9(R1) attributes are already covered by the v0.7 phrase roles, without anyone having designed for it: treatment maps onto grouping, variable onto endpoint/parameter/timepoint, population onto population. The gaps are attribute 4 (intercurrent-event handling) and attribute 5 (the summary measure). That makes this a targeted extension rather than a new workstream.
Requirements
The extension succeeds if these are true. Solution choices are separate — see "Proposed approach", which is a design input, not a constraint.
Intercurrent-event handling is explicit and typed. Each declared ICE carries exactly one ICH E9(R1) strategy per estimand, drawn from the typed enum rather than free text, and the prose states it in language a reviewer would accept.
Strategy is connected to what actually implements it. A strategy is not merely asserted in prose; it resolves to the transformation(s) that operationalise it, so "hypothetical" in a sentence and an imputation step in the model cannot drift apart.
The summary measure is verifiable, not decorative. The summary named in prose must be an output the bound method provably produces.
Per-estimand strategy overrides work. The same ICE handled one way for the primary estimand and another for a sensitivity estimand is expressible without duplicating the ICE.
Zero-install still. Static files, file://, no build step, no server.
Proposed approach
Recorded in smartphrase/DESIGN.md under "Planned extension — estimands and intercurrent events", written during #9 and revisable. Summary:
The estimand is the instance level, not a phrase. The analysis instance grounds in a usdm:Estimand IRI as it grounds in an objective today. A correction falls out: the instance's free-string sentenceRole should bind to the typed Analysis.analysisRole (MainEstimator | SensitivityAnalysis | SupplementaryAnalysis).
Two new roles — a library minor-version event: ice_handling (repeating, like covariate) and summary_measure, the latter binding to a method output via the summarizedByOutputClass hook (e.g. M.ANCOVA's contrasts_t becomes "difference in least-squares means").
One smartphrase per strategy, strategy carried in anchors: SP_ICE_TREATMENT_POLICY ("regardless of {ice}"), SP_ICE_HYPOTHETICAL ("as if {ice} had not occurred"), SP_ICE_COMPOSITE ("with {ice} treated as {outcome}"), SP_ICE_WHILE_ON_TREATMENT ("using measurements taken prior to {ice}"), SP_ICE_PRINCIPAL_STRATUM ("in the stratum of participants in whom {ice} would not occur"). {ice} is a concept reference to a new registry kind IntercurrentEvent.
Strategy phrases change the shape of the instantiated model, not just slice values — the first phrases to do so, and the main thing to scrutinise. TreatmentPolicy modifies nothing; Hypothetical inserts an imputation transformation; Composite redefines the variable via a derivation producing a composite endpoint concept; WhileOnTreatment adds a timing-bounded slice constraint; PrincipalStratum changes the population definition.
Estimand-aware validation: one strategy phrase per declared ICE; exactly one MainEstimator per estimand; the summary phrase names a real method output; conditional template validity (e.g. SP_ICE_HYPOTHETICAL only where an imputation transformation exists to implement it).
Target prose:
Change from baseline in ADAS-Cog(11) at Week 24 in the efficacy population comparing treatment groups, as if discontinuation of study treatment had not occurred and regardless of use of concomitant AD medication, using ANCOVA … summarised as the difference in least-squares means, will be assessed as the primary estimand's main estimator.
The model side already exists
Verified on methods_02 (model/linkML/study_esap.schema.yaml, plus intercurrent-event-derivation.md for the ascertainment-versus-handling split):
The ICE itself, referenced by id and never modified
IceAscertainment
eSAP-owned overlay: study-default strategy, event-driven ScheduleTimeline, and ascertainedBy — either OccurrenceCriterions naming a BC ▸ property ▸ code path, or a derivation. Strategy-independent, which is what makes the ICE trace a separate axis.
IceHandling
Reified (Estimand, IntercurrentEvent, Strategy) triple with implementedBy — precisely the hook requirement 3 needs, and why requirement 6 works without duplicating the ICE
Notably IceHandling.implementedBy's own documentation already lists the per-strategy transformation patterns the proposed approach assumes (Composite → folding derivation, Hypothetical → imputation, TreatmentPolicy → omitted, WhileOnTreatment → censoring, PrincipalStratum → population subsetting). The model and phrase layers already agree on the semantics — this extension is a surface over them, not a redesign.
Suggested worked example — PrE0102
The breast-cancer SAP converted in #9 (smartphrase/SAP/) carries real intercurrent events rather than illustrative ones, in §4.4–4.5: everolimus discontinued for suspected toxicity while fulvestrant continues; treatment interruption capped at 3 weeks with permanent discontinuation beyond it; discontinuation at the subject's request; and disease progression itself. That supports a genuine Hypothetical-versus-TreatmentPolicy contrast on the same event, on a real document, in a therapeutic area where estimand framing is actively contested.
Known implementation consequences
This one does touch the language packs. Unlike the Kaplan-Meier work in Smartphrase: demonstrate SAP <-> AC/DC model linkage (PoC for the working group) #9, which needed no new role, adding ice_handling and summary_measure is a library minor-version event — and because each pack's sentence_template enumerates role tokens explicitly, a role absent from a template is dropped from the rendered sentence entirely. All three packs (EN/FR/DE) need their word order revised: ice_handling after grouping, summary_measure after the method qualifiers.
i18n stress test. The hypothetical strategy wants the German subjunctive — "als ob … nicht aufgetreten wäre" — inside the existing wird … untersucht verb bracket. Per-language phrase templates (decision D7) should accommodate this; it is a good test of whether they really do.
Regression surface.Smartphrase: demonstrate SAP <-> AC/DC model linkage (PoC for the working group) #9 leaves three runnable gates (tools/verify.mjs with 69 pinned outputs across two studies, tools/build-library-subset.mjs --check, tools/verify-ui.mjs). All existing output must stay byte-identical except where a change is intended and justified.
Out of scope
Estimand selection guidance — which strategy is appropriate clinically. This is about expressing a chosen estimand, not recommending one.
The standard SAP document structure (owned by the sister project).
Branches off smartphrase_01, not main — this work builds directly on Smartphrase: demonstrate SAP <-> AC/DC model linkage (PoC for the working group) #9's engine generalisation (decision D10, the slot-name join), the STUDY_GRAPHS registry (D9), the proposed-additions overlay (D8) and the PrE0102 study layer. Base commit at time of writing: afffb84.
Smartphrase: estimands and intercurrent events as smartphrases
Sub-issue of #9. The smartphrase layer demonstrated in #9 expresses an analysis; this extends it to express an estimand.
Purpose
Make ICH E9(R1) estimands a first-class thing the smartphrase layer can author and read back, so that an SAP passage carrying an estimand description and the model instance behind it remain two views of one thing — the same claim #9 makes for analyses.
The motivating observation is that four of the five E9(R1) attributes are already covered by the v0.7 phrase roles, without anyone having designed for it: treatment maps onto
grouping, variable ontoendpoint/parameter/timepoint, population ontopopulation. The gaps are attribute 4 (intercurrent-event handling) and attribute 5 (the summary measure). That makes this a targeted extension rather than a new workstream.Requirements
The extension succeeds if these are true. Solution choices are separate — see "Proposed approach", which is a design input, not a constraint.
illustrative.file://, no build step, no server.Proposed approach
Recorded in
smartphrase/DESIGN.mdunder "Planned extension — estimands and intercurrent events", written during #9 and revisable. Summary:usdm:EstimandIRI as it grounds in an objective today. A correction falls out: the instance's free-stringsentenceRoleshould bind to the typedAnalysis.analysisRole(MainEstimator|SensitivityAnalysis|SupplementaryAnalysis).ice_handling(repeating, likecovariate) andsummary_measure, the latter binding to a method output via thesummarizedByOutputClasshook (e.g.M.ANCOVA'scontrasts_tbecomes "difference in least-squares means").anchors:SP_ICE_TREATMENT_POLICY("regardless of {ice}"),SP_ICE_HYPOTHETICAL("as if {ice} had not occurred"),SP_ICE_COMPOSITE("with {ice} treated as {outcome}"),SP_ICE_WHILE_ON_TREATMENT("using measurements taken prior to {ice}"),SP_ICE_PRINCIPAL_STRATUM("in the stratum of participants in whom {ice} would not occur").{ice}is a concept reference to a new registry kind IntercurrentEvent.MainEstimatorper estimand; the summary phrase names a real method output; conditional template validity (e.g.SP_ICE_HYPOTHETICALonly where an imputation transformation exists to implement it).Target prose:
The model side already exists
Verified on
methods_02(model/linkML/study_esap.schema.yaml, plusintercurrent-event-derivation.mdfor the ascertainment-versus-handling split):EstimandvariableOfInterest,analysisPopulation,interventions,intercurrentEventsIntercurrentEventIceAscertainmentScheduleTimeline, andascertainedBy— eitherOccurrenceCriterions naming a BC ▸ property ▸ code path, or a derivation. Strategy-independent, which is what makes the ICE trace a separate axis.IceHandling(Estimand, IntercurrentEvent, Strategy)triple withimplementedBy— precisely the hook requirement 3 needs, and why requirement 6 works without duplicating the ICEIchE9R1StrategyAnalysis.analysisRole/AnalysisRoleAnalysis.summarizedByOutputClassNotably
IceHandling.implementedBy's own documentation already lists the per-strategy transformation patterns the proposed approach assumes (Composite → folding derivation, Hypothetical → imputation, TreatmentPolicy → omitted, WhileOnTreatment → censoring, PrincipalStratum → population subsetting). The model and phrase layers already agree on the semantics — this extension is a surface over them, not a redesign.Suggested worked example — PrE0102
The breast-cancer SAP converted in #9 (
smartphrase/SAP/) carries real intercurrent events rather than illustrative ones, in §4.4–4.5: everolimus discontinued for suspected toxicity while fulvestrant continues; treatment interruption capped at 3 weeks with permanent discontinuation beyond it; discontinuation at the subject's request; and disease progression itself. That supports a genuine Hypothetical-versus-TreatmentPolicy contrast on the same event, on a real document, in a therapeutic area where estimand framing is actively contested.Known implementation consequences
ice_handlingandsummary_measureis a library minor-version event — and because each pack'ssentence_templateenumerates role tokens explicitly, a role absent from a template is dropped from the rendered sentence entirely. All three packs (EN/FR/DE) need their word order revised:ice_handlingaftergrouping,summary_measureafter the method qualifiers.wird … untersuchtverb bracket. Per-language phrase templates (decision D7) should accommodate this; it is a good test of whether they really do.IntercurrentEventconcepts, asEventwas added for time-to-event endpoints in Smartphrase: demonstrate SAP <-> AC/DC model linkage (PoC for the working group) #9.tools/verify.mjswith 69 pinned outputs across two studies,tools/build-library-subset.mjs --check,tools/verify-ui.mjs). All existing output must stay byte-identical except where a change is intended and justified.Out of scope
MultiplicityStrategy,Hypothesisand the testing hierarchy: adjacent in the eSAP model, deliberately not bundled here.Dependencies and branching
smartphrase_01, notmain— this work builds directly on Smartphrase: demonstrate SAP <-> AC/DC model linkage (PoC for the working group) #9's engine generalisation (decision D10, the slot-name join), theSTUDY_GRAPHSregistry (D9), the proposed-additions overlay (D8) and the PrE0102 study layer. Base commit at time of writing:afffb84.methods_02(81a04b1at time of writing; Smartphrase: demonstrate SAP <-> AC/DC model linkage (PoC for the working group) #9's library subset is generated fromffee5df).Inherited open questions from #9
These are working-group decisions that bear on this extension and are not resolved yet:
illustrativeidentifiers, including a term for Kaplan-Meier estimation.