@smile-digital-health/crl 6.3.0 → 6.4.7

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.
Files changed (122) hide show
  1. package/README.md +4 -0
  2. package/dist/ast/guardDefines.d.ts +7 -1
  3. package/dist/ast/guardDefines.js +46 -8
  4. package/dist/ast/guardDefines.js.map +1 -1
  5. package/dist/ast/types.d.ts +4 -0
  6. package/dist/ast/types.js.map +1 -1
  7. package/dist/authoring-kit/audit.json +4 -4
  8. package/dist/authoring-kit/codedSourceExample.d.ts +2 -0
  9. package/dist/authoring-kit/codedSourceExample.js +40 -0
  10. package/dist/authoring-kit/codedSourceExample.js.map +1 -0
  11. package/dist/authoring-kit/index.js +63 -13
  12. package/dist/authoring-kit/index.js.map +1 -1
  13. package/dist/authoring-kit/navigation.js +8 -1
  14. package/dist/authoring-kit/navigation.js.map +1 -1
  15. package/dist/authoring-kit/query.d.ts +5 -5
  16. package/dist/cel/sourceMembership.d.ts +5 -1
  17. package/dist/cel/sourceMembership.js +1 -0
  18. package/dist/cel/sourceMembership.js.map +1 -1
  19. package/dist/cli/run-apply-session.d.ts +2 -0
  20. package/dist/cli/run-apply-session.js +86 -0
  21. package/dist/cli/run-apply-session.js.map +1 -0
  22. package/dist/cli/run-package-fhir.d.ts +2 -0
  23. package/dist/cli/run-package-fhir.js +37 -0
  24. package/dist/cli/run-package-fhir.js.map +1 -0
  25. package/dist/cql-emitter/catalog/CRLCommon.cql +1 -1
  26. package/dist/cql-emitter/catalog/CaseFeatureCommon.cql +1 -1
  27. package/dist/cql-emitter/emitCQL.js +30 -14
  28. package/dist/cql-emitter/emitCQL.js.map +1 -1
  29. package/dist/cql-emitter/layeredEmit.js +5 -6
  30. package/dist/cql-emitter/layeredEmit.js.map +1 -1
  31. package/dist/cql-emitter/lowerLocalCodes.js +1 -1
  32. package/dist/cql-emitter/lowerLocalCodes.js.map +1 -1
  33. package/dist/cql-emitter/renderPublicationObservation.d.ts +5 -0
  34. package/dist/cql-emitter/renderPublicationObservation.js +44 -0
  35. package/dist/cql-emitter/renderPublicationObservation.js.map +1 -0
  36. package/dist/cql-emitter/renderPublicationQuantity.d.ts +0 -2
  37. package/dist/cql-emitter/renderPublicationQuantity.js +1 -34
  38. package/dist/cql-emitter/renderPublicationQuantity.js.map +1 -1
  39. package/dist/cre/recordCollections.d.ts +7 -0
  40. package/dist/cre/recordCollections.js +109 -0
  41. package/dist/cre/recordCollections.js.map +1 -0
  42. package/dist/cre/run.js +58 -5
  43. package/dist/cre/run.js.map +1 -1
  44. package/dist/editing/presentationEdit.d.ts +154 -0
  45. package/dist/editing/presentationEdit.js +365 -0
  46. package/dist/editing/presentationEdit.js.map +1 -0
  47. package/dist/editing/presentationFile.d.ts +112 -0
  48. package/dist/editing/presentationFile.js +297 -0
  49. package/dist/editing/presentationFile.js.map +1 -0
  50. package/dist/emit/booleanTotality.d.ts +1 -1
  51. package/dist/emit/booleanTotality.js +2 -0
  52. package/dist/emit/booleanTotality.js.map +1 -1
  53. package/dist/emit/publicationProgram.js +7 -2
  54. package/dist/emit/publicationProgram.js.map +1 -1
  55. package/dist/emit/publicationSource.d.ts +2 -1
  56. package/dist/emit/publicationSource.js +5 -4
  57. package/dist/emit/publicationSource.js.map +1 -1
  58. package/dist/emit/resourceEmitRegistry.js +1 -1
  59. package/dist/emit/resourceEmitRegistry.js.map +1 -1
  60. package/dist/emit-bundle.d.ts +19 -0
  61. package/dist/emit-bundle.js +42 -0
  62. package/dist/emit-bundle.js.map +1 -0
  63. package/dist/fhir-emitter/closureOrchestrator.js +2 -0
  64. package/dist/fhir-emitter/closureOrchestrator.js.map +1 -1
  65. package/dist/fhir-emitter/decision.js +23 -68
  66. package/dist/fhir-emitter/decision.js.map +1 -1
  67. package/dist/fhir-emitter/planExpressionInvariant.d.ts +4 -0
  68. package/dist/fhir-emitter/planExpressionInvariant.js +58 -0
  69. package/dist/fhir-emitter/planExpressionInvariant.js.map +1 -0
  70. package/dist/fhir-package/index.d.ts +18 -0
  71. package/dist/fhir-package/index.js +269 -0
  72. package/dist/fhir-package/index.js.map +1 -0
  73. package/dist/fhir-package/r4-spdx-license-codes.json +348 -0
  74. package/dist/flags/flagVocab.d.ts +2 -1
  75. package/dist/flags/flagVocab.js +13 -3
  76. package/dist/flags/flagVocab.js.map +1 -1
  77. package/dist/flags/mvFlag.js.map +1 -1
  78. package/dist/imports/emit.js +12 -6
  79. package/dist/imports/emit.js.map +1 -1
  80. package/dist/index.d.ts +3 -0
  81. package/dist/index.js +6 -2
  82. package/dist/index.js.map +1 -1
  83. package/dist/language-services/index.d.ts +2 -0
  84. package/dist/language-services/index.js +2 -0
  85. package/dist/language-services/index.js.map +1 -1
  86. package/dist/mcp/presentationEditing.d.ts +2 -0
  87. package/dist/mcp/presentationEditing.js +98 -0
  88. package/dist/mcp/presentationEditing.js.map +1 -0
  89. package/dist/mcp/server.js +44 -3
  90. package/dist/mcp/server.js.map +1 -1
  91. package/dist/results/driver/ApplyDriver.build.json +8 -0
  92. package/dist/results/driver/ApplyDriver.class +0 -0
  93. package/dist/results/driver/ApplyDriver.java +37 -6
  94. package/dist/results/driver.d.ts +6 -0
  95. package/dist/results/driver.js +1 -0
  96. package/dist/results/driver.js.map +1 -1
  97. package/dist/results/runProducer.d.ts +1 -0
  98. package/dist/results/runProducer.js +32 -14
  99. package/dist/results/runProducer.js.map +1 -1
  100. package/dist/results/runtimeFingerprint.d.ts +1 -1
  101. package/dist/results/runtimeFingerprint.js +3 -3
  102. package/dist/results/runtimeFingerprint.js.map +1 -1
  103. package/dist/results/session.d.ts +72 -0
  104. package/dist/results/session.js +191 -0
  105. package/dist/results/session.js.map +1 -0
  106. package/dist/results/sessionErrors.d.ts +7 -0
  107. package/dist/results/sessionErrors.js +49 -0
  108. package/dist/results/sessionErrors.js.map +1 -0
  109. package/dist/results/sessionJson.d.ts +20 -0
  110. package/dist/results/sessionJson.js +82 -0
  111. package/dist/results/sessionJson.js.map +1 -0
  112. package/dist/results/sessionResponse.d.ts +15 -0
  113. package/dist/results/sessionResponse.js +87 -0
  114. package/dist/results/sessionResponse.js.map +1 -0
  115. package/dist/results/sessionValidation.d.ts +12 -0
  116. package/dist/results/sessionValidation.js +111 -0
  117. package/dist/results/sessionValidation.js.map +1 -0
  118. package/dist/results/spawn.d.ts +6 -6
  119. package/dist/results/spawn.js +6 -6
  120. package/dist/results/spawn.js.map +1 -1
  121. package/docs/apply-session.md +87 -0
  122. package/package.json +142 -132
package/README.md CHANGED
@@ -617,3 +617,7 @@ compiled-CQL caching.
617
617
  CLI SIGINT/SIGTERM and MCP shutdown await owned-process cleanup. On POSIX,
618
618
  forcibly killing the Node owner (for example SIGKILL) cannot run that cleanup;
619
619
  Windows additionally detects owner loss through the Job Object supervisor.
620
+
621
+ ### FHIR NPM packaging
622
+
623
+ After emitting definitions, run `crl-package-fhir --project <directory>` or the `package_fhir` MCP tool. See [package metadata, contents and validation boundaries](../../docs/fhir-npm-packaging.md).
@@ -1,10 +1,16 @@
1
- import type { BranchCondition, CRL, Criterion, Decision } from "./types";
1
+ import type { ActionGuard, BranchCondition, CRL, Criterion, Decision } from "./types";
2
2
  import type { CRLError } from "../types/errors";
3
3
  export interface SyntheticGuardDefine {
4
4
  readonly name: string;
5
5
  readonly condition: BranchCondition;
6
+ readonly planCondition?: {
7
+ negated: boolean;
8
+ carrier: "branch" | "action";
9
+ };
6
10
  }
7
11
  export declare function needsGuardDefine(g: BranchCondition): boolean;
12
+ export declare function planConditionDefineName(condition: BranchCondition, negated?: boolean, carrier?: "branch" | "action"): string;
13
+ export declare function actionGuardCondition(guard: ActionGuard): BranchCondition;
8
14
  export declare function guardDefineName(g: BranchCondition): string;
9
15
  export declare function collectGuardDefines(decision: Decision): SyntheticGuardDefine[];
10
16
  export declare function synthesizeGuardCriteria(ast: CRL): Criterion[];
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.needsGuardDefine = needsGuardDefine;
4
+ exports.planConditionDefineName = planConditionDefineName;
5
+ exports.actionGuardCondition = actionGuardCondition;
4
6
  exports.guardDefineName = guardDefineName;
5
7
  exports.collectGuardDefines = collectGuardDefines;
6
8
  exports.synthesizeGuardCriteria = synthesizeGuardCriteria;
@@ -20,6 +22,14 @@ function directLowerablePriorGuard(g) {
20
22
  function needsGuardDefine(g) {
21
23
  return !directLowerablePriorGuard(g);
22
24
  }
25
+ function planConditionDefineName(condition, negated = false, carrier = "branch") {
26
+ const pos = condition.location.start;
27
+ return (negated ? "Not " : "") + "CRL " + carrier + " " + condition.type.replace("BranchCondition", "") +
28
+ " L" + pos.line + "C" + pos.column;
29
+ }
30
+ function actionGuardCondition(guard) {
31
+ return { type: "BranchConditionRef", ref: guard.conceptName, location: guard.location };
32
+ }
23
33
  function guardDefineName(g) {
24
34
  return `Guard L${g.location.start.line}C${g.location.start.column}`;
25
35
  }
@@ -28,26 +38,53 @@ function collectGuardDefines(decision) {
28
38
  const seen = new Set();
29
39
  const add = (g) => {
30
40
  const name = guardDefineName(g);
31
- if (seen.has(name))
41
+ const identity = name + "\0" + JSON.stringify(g);
42
+ if (seen.has(identity))
32
43
  return;
33
- seen.add(name);
44
+ seen.add(identity);
34
45
  out.push({ name, condition: g });
35
46
  };
47
+ const addCondition = (condition, carrier) => {
48
+ for (const negated of [false, true]) {
49
+ const name = planConditionDefineName(condition, negated, carrier);
50
+ const identity = name + "\0" + JSON.stringify(condition);
51
+ if (!seen.has(identity)) {
52
+ seen.add(identity);
53
+ out.push({ name, condition, planCondition: { negated, carrier } });
54
+ }
55
+ }
56
+ };
57
+ const walkCondition = (condition) => {
58
+ addCondition(condition, "branch");
59
+ if (condition.type === "BranchConditionNot")
60
+ walkCondition(condition.operand);
61
+ else if (condition.type === "BranchConditionAnd" || condition.type === "BranchConditionOr")
62
+ condition.operands.forEach(walkCondition);
63
+ };
36
64
  const walkBlock = (statements, qualifier) => {
37
65
  statements.forEach((stmt, i) => {
66
+ if (stmt.type === "ActionStatement") {
67
+ if (stmt.guard)
68
+ addCondition(actionGuardCondition(stmt.guard), "action");
69
+ return;
70
+ }
38
71
  if (stmt.type !== "WhenBlock" && stmt.type !== "OtherwiseBlock")
39
72
  return;
40
- const isPrior = i < statements.length - 1;
41
- if (qualifier === "first" && isPrior && stmt.type === "WhenBlock" && needsGuardDefine(stmt.condition)) {
42
- add(stmt.condition);
73
+ if (stmt.type === "WhenBlock") {
74
+ walkCondition(stmt.condition);
75
+ if (qualifier === "first" && i < statements.length - 1 && needsGuardDefine(stmt.condition))
76
+ add(stmt.condition);
43
77
  }
44
78
  walkBody(stmt.body);
45
79
  });
46
80
  };
47
81
  const walkBody = (body) => {
48
- if (body === undefined || body.type !== "BlockBody")
82
+ if (body === undefined)
49
83
  return;
50
- walkBlock(body.statements, body.qualifier);
84
+ if (body.type === "BlockBody")
85
+ walkBlock(body.statements, body.qualifier);
86
+ else if (body.guard)
87
+ addCondition(actionGuardCondition(body.guard), "action");
51
88
  };
52
89
  walkBlock(decision.body.statements, decision.body.qualifier);
53
90
  return out;
@@ -59,6 +96,7 @@ function synthesizeGuardCriteria(ast) {
59
96
  name: g.name,
60
97
  condition: g.condition,
61
98
  location: g.condition.location,
99
+ ...(g.planCondition ? { __planCondition: g.planCondition } : {}),
62
100
  }));
63
101
  }
64
102
  function guardDefineNameCollisions(ast) {
@@ -66,7 +104,7 @@ function guardDefineNameCollisions(ast) {
66
104
  const errors = [];
67
105
  for (const g of synthesizeGuardDefinesFor(ast)) {
68
106
  const prior = generated.get(g.name);
69
- if (prior !== undefined && prior !== g.condition) {
107
+ if (prior !== undefined && JSON.stringify(prior) !== JSON.stringify(g.condition)) {
70
108
  errors.push({
71
109
  type: "Validation",
72
110
  kind: "guard-define-name-collision",
@@ -1 +1 @@
1
- {"version":3,"file":"guardDefines.js","sourceRoot":"","sources":["../../src/ast/guardDefines.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"guardDefines.js","sourceRoot":"","sources":["../../src/ast/guardDefines.ts"],"names":[],"mappings":"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"}
@@ -74,6 +74,10 @@ export interface Criterion extends ASTNode {
74
74
  name: string;
75
75
  condition: BranchCondition;
76
76
  location: Location;
77
+ __planCondition?: {
78
+ negated: boolean;
79
+ carrier: "branch" | "action";
80
+ };
77
81
  }
78
82
  export type BlockQualifier = "first" | "any" | "all";
79
83
  export type BranchBlock = WhenBlock | OtherwiseBlock;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ast/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ast/types.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
- "auditedRevision": "3bf25ef2420f7d52d39161292973333860827f26",
3
- "auditedSchemaVersion": "2.9",
4
- "auditedContentHash": "46d007bb22697b3ae67ebff58ed74157b9e48b785a95c7ab17c7151c314af826",
5
- "scope": "Kit schema 2.9 release 6.3.0 maintenance from 510c931f2323c89f9822592e01668112dd6ff795 through 3bf25ef2420f7d52d39161292973333860827f26. Complete changed-path inventory and dispositions in coverage.md. Typed text/dateTime selected values, generic presence guards, exact policy entry-point identities, full generated-directory replacement, Description creation contract, MV-only launch and KE Accept/Reject are mapped to owning tests. Full core5059 and extension1285 pass, real MCP and typechecks pass. Native plan/code coverage converged; external Description plan and release code initial round completed, follow-up blocked by automatic approval review. Prior semantic sessions remain separately identified; installed delivery is still a release gate. No clinical certification or migration of existing flags is asserted.",
2
+ "auditedRevision": "bc05b043dc660b422e9e03b450b70506e8ad540c",
3
+ "auditedSchemaVersion": "2.17",
4
+ "auditedContentHash": "b94d87cf2fd940d71c56017b8e172e8d877f7fef80982808bdea84f64a7d9813",
5
+ "scope": "Kit schema 2.17 delta audit: Bounded flat/grouped native selected Observation question-association correction. Full baseline delta and canonical payload reviewed; 83 kit tests, 3 owning association tests and both retained native Boolean Q/QR pairs passed. No runtime changes. Grouped/flat identity, wording ownership and QR association are covered; arbitrary hierarchies and native description rendering remain unqualified. Installed delivery qualification is recorded separately.",
6
6
  "evidence": "packages/crl/src/authoring-kit/tests/coverage.md"
7
7
  }
@@ -0,0 +1,2 @@
1
+ export declare const CODED_SOURCE_POLICY = "library \"Coded Source\".\nterminology \"Tests\":\n- system is `urn:synthetic:test`.\n- code is `result`.\nterminology \"Results\":\n- system is `urn:synthetic:result`.\n- code is `negative` display is `Negative`.\n- code is `positive` display is `Positive`.\nterminology \"Negative\":\n- system is `urn:synthetic:result`.\n- code is `negative`.\nconcept \"Result\":\n- shape is Record.\n- type is Observation.\n- value type is CodeableConcept.\n- value domain is \"Results\".\n- shape reduction is most recent.\n- source representation:\n - type is Observation.\n - coded from \"Tests\".\nconcept \"Is Negative\":\n- shape is Record.\n- type is Observation.\n- value type is boolean.\n- definition is \"Result\" in \"Negative\".\n- shape reduction is most recent.\nactivity \"Yes\": - request CPGCommunicationRequest. - with `YES`.\nactivity \"No\": - request CPGCommunicationRequest. - with `NO`.\ndecision \"D\": first:\n- when \"Is Negative\" then recommend activity \"Yes\".\n- otherwise then recommend activity \"No\".\n";
2
+ export declare const CODED_SOURCE_WITH_ANSWERS: string;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CODED_SOURCE_WITH_ANSWERS = exports.CODED_SOURCE_POLICY = void 0;
4
+ exports.CODED_SOURCE_POLICY = `library "Coded Source".
5
+ terminology "Tests":
6
+ - system is \`urn:synthetic:test\`.
7
+ - code is \`result\`.
8
+ terminology "Results":
9
+ - system is \`urn:synthetic:result\`.
10
+ - code is \`negative\` display is \`Negative\`.
11
+ - code is \`positive\` display is \`Positive\`.
12
+ terminology "Negative":
13
+ - system is \`urn:synthetic:result\`.
14
+ - code is \`negative\`.
15
+ concept "Result":
16
+ - shape is Record.
17
+ - type is Observation.
18
+ - value type is CodeableConcept.
19
+ - value domain is "Results".
20
+ - shape reduction is most recent.
21
+ - source representation:
22
+ - type is Observation.
23
+ - coded from "Tests".
24
+ concept "Is Negative":
25
+ - shape is Record.
26
+ - type is Observation.
27
+ - value type is boolean.
28
+ - definition is "Result" in "Negative".
29
+ - shape reduction is most recent.
30
+ activity "Yes": - request CPGCommunicationRequest. - with \`YES\`.
31
+ activity "No": - request CPGCommunicationRequest. - with \`NO\`.
32
+ decision "D": first:
33
+ - when "Is Negative" then recommend activity "Yes".
34
+ - otherwise then recommend activity "No".
35
+ `;
36
+ exports.CODED_SOURCE_WITH_ANSWERS = exports.CODED_SOURCE_POLICY
37
+ .replace('concept "Result":', 'concept "Result":\n- code is `result`.')
38
+ .replace('- value domain is "Results".', '- value domain is answer options.\n- value from is "Results".')
39
+ .replace('concept "Is Negative":', 'presentation for "Result":\n- question text is "Which synthetic result was reported?".\nconcept "Is Negative":');
40
+ //# sourceMappingURL=codedSourceExample.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codedSourceExample.js","sourceRoot":"","sources":["../../src/authoring-kit/codedSourceExample.ts"],"names":[],"mappings":";;;AACa,QAAA,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BlC,CAAC;AAGW,QAAA,yBAAyB,GAAG,2BAAmB;KACzD,OAAO,CAAC,mBAAmB,EAAE,wCAAwC,CAAC;KACtE,OAAO,CAAC,8BAA8B,EAAE,+DAA+D,CAAC;KACxG,OAAO,CAAC,wBAAwB,EAAE,gHAAgH,CAAC,CAAC"}
@@ -9,6 +9,7 @@ const intakeExample_1 = require("./intakeExample");
9
9
  const selectionExample_1 = require("./selectionExample");
10
10
  const quantityExample_1 = require("./quantityExample");
11
11
  const decisionExamples_1 = require("./decisionExamples");
12
+ const codedSourceExample_1 = require("./codedSourceExample");
12
13
  const sourceOrderExample_1 = require("./sourceOrderExample");
13
14
  const audit_json_1 = __importDefault(require("./audit.json"));
14
15
  const navigation_1 = require("./navigation");
@@ -20,7 +21,7 @@ const conceptTypes_1 = require("../grammar/conceptTypes");
20
21
  const conceptValueTypes_1 = require("../grammar/conceptValueTypes");
21
22
  const spawn_1 = require("../results/spawn");
22
23
  const reference_1 = require("./reference");
23
- const SCHEMA_VERSION = "2.9";
24
+ const SCHEMA_VERSION = "2.17";
24
25
  const FEEDBACK_URL = "https://github.com/alphora/clinical-reasoning-language/issues/new";
25
26
  const SUMMARY = "Local decision support: express clinical intent through coded answers, supported source representations and explicit computed publications. Author decision/criterion structure for distinct criteria, named terminology for coded answer choices, and presentations for question wording. Validate and compare CRE predictions with emitted CQL/FHIR and native $apply. Supported age, request, qualification, threshold and finite-code BMI forms are in scope; broader #320 limitations are listed separately.";
26
27
  const FORCE_MODEL = {
@@ -79,7 +80,7 @@ const CONCEPT_LAYER_MODEL = [
79
80
  },
80
81
  {
81
82
  form: '- source representation: - type is <Resource>. - [ coded from "Value Set" ] - [ value projection is <phrase> ].',
82
- meaning: "Write every concept-level field before the first source representation; source representations come last, and indentation does not close them. A source representation declares its resource type, optional coded from membership and value projection. Model information supplies the datum carrier; do not author value element is or value type is on the representation. coded from retrieves matching source records; value from is binds offered answers. Supported publication forms include Patient age projection, matching ServiceRequest with value projection is exists this, and finite-code Observation Quantity sources. Source and local contributions join before the final authored selector. Patient age has its own daily recalculation/same-day assertion policy; no universal local-wins rule follows. Opaque ValueSet retrieval and arbitrary projection/producer combinations remain unsupported in this publication path; parsing a phrase is not proof of emission.",
83
+ meaning: "Write every concept-level field before the first source representation; source representations come last, and indentation does not close them. A source representation declares its resource type, optional coded from membership and value projection. Model information supplies the datum carrier; do not author value element is or value type is on the representation. coded from retrieves matching source records; value from is binds offered answers. Supported publication forms include Patient age projection, matching ServiceRequest with value projection is exists this, and finite-code Observation Quantity and CodeableConcept sources. CodeableConcept sources preserve the complete coded value and validity; a named value domain interprets the selected value. Missing records or values remain unknown, recognized nonmembers are false, and unrecognized or conflicting interpretations are errors. Final selection precedes domain interpretation, so an older unrecognized value does not defeat a newer valid one. Source and local contributions join before the final authored selector. Patient age has its own daily recalculation/same-day assertion policy; no universal local-wins rule follows. Opaque ValueSet retrieval and arbitrary projection/producer combinations remain unsupported in this publication path; parsing a phrase is not proof of emission.",
83
84
  scope: "in",
84
85
  },
85
86
  {
@@ -110,12 +111,12 @@ const RULES = [
110
111
  id: "concept-form",
111
112
  applicability: "All CRL authoring",
112
113
  category: "concept-model",
113
- rule: "For selected concepts declare shape is Record, type is Observation, value type is and shape reduction is most recent. Supply data with code is, a supported source representation or a supported definition is producer. code is provides the local answer representation; an uncoded calculation has no local answer slot. Coded answers use value domain is answer options and value from is \"Named Terminology\". Presentations separate questions from concept names. Supported patterns include Patient age, ServiceRequest existence, finite-code Quantity sources, answer qualification, thresholds and BMI with explicit validity. These are bounded contracts; unsupported composition is a capability gap, not a reason to copy legacy Scalar content. Missing evidence for an answerable determination stays unknown; false needs an explicit negative or a computation establishing it. For selected-datum membership, an interpretable known non-member yields false; no selected datum or value leaves it unknown. Membership of one selected datum is not existence of any matching record: a selected non-repair request cannot establish that no repair was requested elsewhere. Inferring a broader negative from absent records requires an explicit completeness assumption for subject, scope and time. The completeness language/enforcement remains #320 design work; neither code is nor receipt of a data bundle supplies that contract.",
114
+ rule: "For selected concepts declare shape is Record, type is Observation, value type is and shape reduction is most recent. Supply data with code is, a supported source representation or a supported definition is producer. code is provides the local answer representation; an uncoded calculation has no local answer slot. Coded answers use value domain is answer options and value from is \"Named Terminology\". Presentations separate questions from concept names. Supported patterns include Patient age, ServiceRequest existence, finite-code Quantity and CodeableConcept sources, answer qualification, thresholds and BMI with explicit validity. These are bounded contracts; unsupported composition is a capability gap, not a reason to copy legacy Scalar content. Missing evidence for an answerable determination stays unknown; false needs an explicit negative or a computation establishing it. For selected-datum membership, an interpretable known non-member yields false; no selected datum or value leaves it unknown. Membership of one selected datum is not existence of any matching record: a selected non-repair request cannot establish that no repair was requested elsewhere. Inferring a broader negative from absent records requires an explicit completeness assumption for subject, scope and time. The completeness language/enforcement remains #320 design work; neither code is nor receipt of a data bundle supplies that contract.",
114
115
  why: "Separate what supplies data, what computes a candidate, what selects the published record and what expresses the decision. A kit scope label must not forbid forms that the same kit teaches. Preserve distinct source criteria as auditable decision operands; do not infer one fact merely from a shared label.",
115
116
  ref: "concept-layer-model; publication-reference.crl; named-answer-options",
116
117
  clauses: [
117
118
  {
118
- "text": "For selected concepts declare shape is Record, type is Observation, value type is and shape reduction is most recent. Supply data with code is, a supported source representation or a supported definition is producer. code is provides the local answer representation; an uncoded calculation has no local answer slot. Coded answers use value domain is answer options and value from is \"Named Terminology\". Presentations separate questions from concept names. Supported patterns include Patient age, ServiceRequest existence, finite-code Quantity sources, answer qualification, thresholds and BMI with explicit validity. These are bounded contracts; unsupported composition is a capability gap, not a reason to copy legacy Scalar content. Missing evidence for an answerable determination stays unknown; false needs an explicit negative or a computation establishing it. For selected-datum membership, an interpretable known non-member yields false; no selected datum or value leaves it unknown. Membership of one selected datum is not existence of any matching record: a selected non-repair request cannot establish that no repair was requested elsewhere. Inferring a broader negative from absent records requires an explicit completeness assumption for subject, scope and time. The completeness language/enforcement remains #320 design work; neither code is nor receipt of a data bundle supplies that contract.",
119
+ "text": "For selected concepts declare shape is Record, type is Observation, value type is and shape reduction is most recent. Supply data with code is, a supported source representation or a supported definition is producer. code is provides the local answer representation; an uncoded calculation has no local answer slot. Coded answers use value domain is answer options and value from is \"Named Terminology\". Presentations separate questions from concept names. Supported patterns include Patient age, ServiceRequest existence, finite-code Quantity and CodeableConcept sources, answer qualification, thresholds and BMI with explicit validity. These are bounded contracts; unsupported composition is a capability gap, not a reason to copy legacy Scalar content. Missing evidence for an answerable determination stays unknown; false needs an explicit negative or a computation establishing it. For selected-datum membership, an interpretable known non-member yields false; no selected datum or value leaves it unknown. Membership of one selected datum is not existence of any matching record: a selected non-repair request cannot establish that no repair was requested elsewhere. Inferring a broader negative from absent records requires an explicit completeness assumption for subject, scope and time. The completeness language/enforcement remains #320 design work; neither code is nor receipt of a data bundle supplies that contract.",
119
120
  "force": "default"
120
121
  },
121
122
  {
@@ -204,6 +205,10 @@ const RULES = [
204
205
  "text": "Presentation is optional for any concept declaring code is, across answer types; missing presentation warns even if the concept is not reached. Presentation on an uncoded concept errors. Without presentation, the emitted input has no question-text extension and the tested engine uses the concept name; description is absent, not a repeated name. Authored text maps to cpg-input-text. Authored description is preserved in cpg-input-description but the delivered CQFramework does not yet display it. Verify emitted description separately from native question text and pause/leaf behavior. Co-occurring occurrences of the same input profile must resolve compatible wording, including authored text versus concept-name fallback. A scoped presentation without a base can therefore conflict with an unpresented occurrence (presentation-overlap); identical effective text is compatible.",
205
206
  "force": "default"
206
207
  },
208
+ {
209
+ "text": "For the tested selected Observation inputs, identify exactly one non-group answer item whose definition is the exact input profile plus #Observation.value[x]. When there is no owning input group, verify authored question text on that answer item. If a group with definition equal to the exact input profile is present, require exactly one such group, verify its question text, and require it to contain the identified answer. Match the QuestionnaireResponse item by both linkId and definition. Reject missing or misassociated wording, duplicate associations, and wording borrowed from unrelated ancestors or siblings. These checks cover the tested selected Observation shape, not arbitrary Questionnaire hierarchies. Continue verifying authored descriptions in emitted extensions; native description rendering remains unqualified.",
210
+ "force": "default"
211
+ },
207
212
  {
208
213
  "text": "Imported questions inherit their owning library's presentation. Importing-library presentation overrides are deferred to issue #321; do not author unsupported overrides. The future rule is most local presentation wins by import hierarchy, not textual order.",
209
214
  "force": "default"
@@ -315,7 +320,7 @@ const RULES = [
315
320
  "force": "default"
316
321
  },
317
322
  {
318
- "text": "Publication-reachable branch guards preserve the whole Boolean expression in one text/cql-expression applicability condition, including references through criteria, with dependency input[]. Naming a criterion supports reuse and readability; the number of condition entries is not a source-fidelity test.",
323
+ "text": "Publication-reachable branch guards preserve the whole Boolean expression in a named CQL definition referenced by one text/cql-identifier applicability condition, including references through criteria, with dependency input[]. Naming a criterion supports reuse and readability; the number of condition entries is not a source-fidelity test.",
319
324
  "force": "default"
320
325
  }
321
326
  ],
@@ -366,7 +371,7 @@ const RULES = [
366
371
  id: "branch-guards",
367
372
  applicability: "All CRL authoring",
368
373
  category: "guards",
369
- rule: "A when branch condition combines concept/criterion references with and, or, not and parentheses. A homogeneous chain may be bare; mixed and/or requires parentheses, as does not over a compound operand. Strong Kleene applies: not unknown is unknown. Publication-reachable branch guards, including references through a criterion, preserve the whole Boolean expression in one text/cql-expression applicability condition, with dependency input[] and null-propagating priority exclusions. Legacy guards use per-atom condition[] and DNF arms. Both retain source criteria in decision logic; the number of condition[] entries is not a source-fidelity test. Per-action only when / unless is a separate restricted menu construct (see guards). Publication-reachable means at least one operand in the guard dependency closure is an admitted selected publication: follow criterion references and imported operands too. This is an implementation choice, not a separate authored switch; migrating a dependency can change the lowering. Whole-expression evaluation prevents a true alternative from hiding an evaluated publication error (for example ambiguous selection or uninterpretable data). An evaluated error fails the case and cannot be bypassed by later first: branches; it is different from unknown and must not be treated as a pause. DNF arm-count relief is irrelevant for a guard already using whole-expression lowering. Logical grouping is not record identity: (recipient finding AND recipient assessment) OR (caregiver finding AND caregiver assessment) prevents mixing the two Boolean pairs, but each pair must already refer to the same identified person. Parentheses do not join arbitrary clinical records. The emitted dependency input[] retains the compound guard operands, including through named criteria. Do not infer native question suppression from a known truth value or from MV path display; inspect the actual native Questionnaire for the policy. CRE truth evaluation alone does not prove native question visibility.",
374
+ rule: "A when branch condition combines concept/criterion references with and, or, not and parentheses. A homogeneous chain may be bare; mixed and/or requires parentheses, as does not over a compound operand. Strong Kleene applies: not unknown is unknown. Publication-reachable branch guards, including references through a criterion, preserve the whole Boolean expression in a named CQL definition referenced by one text/cql-identifier applicability condition, with dependency input[] and null-propagating priority exclusions. Legacy guards use per-atom condition[] and DNF arms. Both retain source criteria in decision logic; the number of condition[] entries is not a source-fidelity test. Per-action only when / unless is a separate restricted menu construct (see guards). Publication-reachable means at least one operand in the guard dependency closure is an admitted selected publication: follow criterion references and imported operands too. This is an implementation choice, not a separate authored switch; migrating a dependency can change the lowering. Whole-expression evaluation prevents a true alternative from hiding an evaluated publication error (for example ambiguous selection or uninterpretable data). An evaluated error fails the case and cannot be bypassed by later first: branches; it is different from unknown and must not be treated as a pause. DNF arm-count relief is irrelevant for a guard already using whole-expression lowering. Logical grouping is not record identity: (recipient finding AND recipient assessment) OR (caregiver finding AND caregiver assessment) prevents mixing the two Boolean pairs, but each pair must already refer to the same identified person. Parentheses do not join arbitrary clinical records. The emitted dependency input[] retains the compound guard operands, including through named criteria. Do not infer native question suppression from a known truth value or from MV path display; inspect the actual native Questionnaire for the policy. CRE truth evaluation alone does not prove native question visibility.",
370
375
  why: "Distinct policy criteria belong in auditable decision/criterion expressions. Keep source operands and dependencies traceable while preserving unknown and authored precedence; do not assert that one applicability condition necessarily hides the decision.",
371
376
  ref: "docs/decision-shapes.md; #224",
372
377
  clauses: [
@@ -375,7 +380,7 @@ const RULES = [
375
380
  force: "validator-enforced",
376
381
  },
377
382
  {
378
- text: "Publication-reachable branch guards, including references through a criterion, preserve the whole Boolean expression in one text/cql-expression applicability condition, with dependency input[] and null-propagating priority exclusions. Legacy guards use per-atom condition[] and DNF arms. Both retain source criteria in decision logic; the number of condition[] entries is not a source-fidelity test. A single-determination first: exclusion uses branch not, not menu-only unless.",
383
+ text: "Publication-reachable branch guards, including references through a criterion, preserve the whole Boolean expression in a named CQL definition referenced by one text/cql-identifier applicability condition, with dependency input[] and null-propagating priority exclusions. Legacy guards use per-atom condition[] and DNF arms. Both retain source criteria in decision logic; the number of condition[] entries is not a source-fidelity test. A single-determination first: exclusion uses branch not, not menu-only unless.",
379
384
  force: "default",
380
385
  },
381
386
  {
@@ -614,6 +619,18 @@ const RULES = [
614
619
  { text: "Verify the actual entry point, complete case/output inventory and native outcomes. Normal commands publish the whole MV suite, while regression uses isolated output. Route-focused MV does not discharge native verification or source-fidelity obligations.", force: "invariant", test: "verifyLoop:native-outcome-verification" },
615
620
  ],
616
621
  },
622
+ {
623
+ id: "shared-wording-editing",
624
+ applicability: "Editing locally owned CRL question wording",
625
+ category: "process",
626
+ rule: "Use CRL: Edit Question Wording in the owning CRL editor, or MCP preview_presentation_edit followed by apply_presentation_edit. Select by library/concept identity and an existing default or scope, supply only changed fields, and review the old/new text, per-field owner impact and source diff. Editing an inherited field edits its actual shared owner; it does not create a new per-use override. External consumers are unknown. The tools preserve ordinary CRL, comments and unrelated computation rather than inventing another authoring format.",
627
+ ref: "docs/shared-presentation-editing.md; concept-presentation; mv-wording-patches",
628
+ clauses: [
629
+ { text: "MCP works on saved files within the explicit owning package. It refuses packaged/generated/linked targets, unsupported intent and stale source/project snapshots; apply requires the exact preview token. Omitted fields stay unchanged. Empty description requests removal, but removal exposing unexpected inherited wording is refused. Unsupported literal text, ambiguous ownership and source validation failures are errors, not permission to overwrite the file. Re-preview current source after a conflict.", force: "default" },
630
+ { text: "The human editor includes participating unsaved CRL buffers, refreshes untouched fields and retains edited drafts on conflict. Apply uses one ordinary editor undo step and leaves the document unsaved. MCP cannot see other editors' unsaved buffers; save/reconcile those before using it. MCP revert_presentation_edit accepts its original receipt only against the exact resulting source, validates the reversal, and refuses intervening changes. Use Git for broader recovery; neither adapter promises a cross-process transaction.", force: "default" },
631
+ { text: "This is source/import/presentation validation, not full emission compatibility or native acceptance. Regenerate CRL/CQL/FHIR and native results, verify group/answer associations and behavior, then renew review. Source edits do not resolve flags, mark verdicts or apply/dispose MV proposals. MV's pencil remains a proposal-only handoff to the source owner, who explicitly reconciles and records its disposition.", force: "default" }
632
+ ]
633
+ },
617
634
  {
618
635
  id: "mv-wording-patches",
619
636
  applicability: "Question wording proposed during Medical Validation",
@@ -727,6 +744,16 @@ const RULES = [
727
744
  rule: "Verify with the MCP tools in order: validate_crl(path) clean → validate_cel(path) clean → run_decision(path) with every case's `result is` passing. MV file validation checks the MV set; regression file validation checks both sets. For the complete engineering check, use crl-run-regression to run MV plus regression once each. validate_cel and run_decision need FILES under a project root (a package.json) — they do not accept inline code. For a COMPOUND-GUARD branch, cite the run_decision `conditionTrace` (the per-operand truth-table) as the audit surface, and demonstrate that each conjunct is load-bearing; the DROP-ONE battery (see cel-cases) is recommended, and equivalent proof is acceptable. A satisfying case alone is insufficient.",
728
745
  ref: "verifyLoop",
729
746
  clauses: [
747
+ {
748
+ "text": "CRE/MV preview evaluates explicit Condition and Observation RecordSet retrieves against the emitted CEL patient resources, matching resource type and exact system/code. Unary Condition active and verified filters compose on the same records; Observation verified accepts final, amended and corrected. An explicit existence test returns false for an empty resulting set and true for a matching record even when its Boolean value is false. This answers existence within the authored set, not a selected answer value or a broader clinical negative; preserve the required scope/completeness assumption. These preview checks do not replace independent native execution.",
749
+ "force": "default",
750
+ "test": "verify-loop:record-status-preview"
751
+ },
752
+ {
753
+ "text": "This RecordSet preview supports unprojected coded retrieves and a local collection with one unprojected source representation of the same declared type. Reached unsupported operations, temporal/multi-operand status filters, selections/projections, ambiguous owners, cycles, multiple source representations, and locally coded or Boolean-annotated narrative RecordSet filters produce an evaluation error, not false. Unused unsupported collections do not fail an otherwise supported path. Treat these as bounded runtime limitations; retain the faithful authored criteria and record any unverified cases rather than weakening the model to make preview pass.",
754
+ "force": "default",
755
+ "test": "verify-loop:record-status-boundaries"
756
+ },
730
757
  {
731
758
  "text": "Validate CRL and CEL, compare supported CRE predictions with independent native activity/pause expectations, and record unsupported or unexecuted cases as unverified. Establish that each distinct criterion is consequential and relevant unknown behavior is correct; equivalent proof methods are acceptable.",
732
759
  "force": "invariant",
@@ -761,6 +788,28 @@ const RULES = [
761
788
  }
762
789
  ],
763
790
  },
791
+ {
792
+ id: "fhir-packaging",
793
+ applicability: "Distributing existing FHIR definitions as an NPM package",
794
+ category: "process",
795
+ rule: "For a definitions-only FHIR collection Bundle, call emit_crl_bundle with an absolute CRL path, or SDK emitCrlBundle(path). It emits the dependency closure and embeds local CQL in Library.content.data without writing files or adding patient data or a static Questionnaire. Inspect success and diagnostics; emission errors, unresolved references, filename collisions and missing CQL refuse the Bundle. External dependencies such as hl7.fhir.uv.cql.FHIRHelpers still need runtime resolution. This is not native execution or FHIR/profile validation. After emitting and verifying definitions, call package_fhir with an absolute projectRoot, or crl-package-fhir --project <path>. This packages existing src/fhir; it does not emit, publish, or run $apply. Configure package.json name (the policy ID), exact SemVer version, author, description and crl.canonicalBase, plus a separate dotted crl.packageId (at most 64 characters) and exact crl.fhirDependencies for external FHIR packages. packageId/--package-id can override the package ID. The R4 core dependency is 4.0.1. An optional license must be a single FHIR R4 SPDX code; no license is invented. The default output/package.tgz contains package/package.json, an ImplementationGuide resource inventory, a v2 .index.json and the canonical definitions. Existing resource identities and versions are preserved. Local Library attachments within src are embedded only in the archive copy; source files are unchanged. Only the chosen archive is replaced. Optional outputFile/--out selects its destination outside src. Patient examples and MV/regression data are refused under src/fhir. Duplicate identities, unsafe paths and invalid metadata are errors. Identical inputs produce identical archive bytes. Known CPG, CRMI, SDC, CQL and terminology dependencies are checked, but packaging does not resolve transitive dependencies or prove FHIR/profile/CQL executable validity. Inspect the archive's package/.index.json and ImplementationGuide inventory and independently validate content for its intended use. A separate CRMI asset-collection manifest Library is not required merely to create an NPM package; this tool does not implement a server $package operation.",
796
+ ref: "docs/fhir-npm-packaging.md; fhir-package/index.test.ts",
797
+ clauses: [
798
+ { text: "Provide valid package metadata and keep patient/case data outside src/fhir; the packager refuses invalid metadata, duplicate identities and unsafe paths.", force: "validator-enforced" },
799
+ { text: "Verify emitted definitions before packaging and independently validate the resulting package for its intended consumer; packaging success is not executable or clinical validation.", force: "default" },
800
+ ],
801
+ },
802
+ {
803
+ id: "native-apply-session",
804
+ applicability: "Applications submitting successive native QuestionnaireResponse edits",
805
+ category: "process",
806
+ rule: "Use @smile-digital-health/crl/session applySession or crl-apply-session for one stateless native R4 $r5.apply request. Supply schemaVersion 1, request/case/step IDs, PlanDefinition ID, subject, immutable repository JSON and explicit current request-data JSON; the CLI accepts JSON file paths instead. Include the matching returned Questionnaire with a submitted response. buildSessionResponse requires the exact response SHA256, authored time and mode: full reasserts supplied contents; edits-only submits explicit edits and ancestors, omitting untouched answers. Set native value[x] answers; clear retains an item without its answer. False is a value. No date coercion or timestamp inference occurs. Edits-only under repeating groups or answer children is refused; full mode preserves supplied hierarchy but does not establish persistence identity. The caller owns resource replacement, retained extracted state and acceptance of successful results; no hidden state or universal merge rule exists. Error/fatal native outcomes, invalid inputs, process failures, timeout, cancellation, output limits or unconfirmed cleanup fail the request. Raw input/output artifacts, hashes and runtime identity remain available. A returned Questionnaire or ok:true alone does not prove a clinical disposition; inspect expected actions and answers. Use JRE17+ and the pinned engine. See packages/crl/docs/apply-session.md for the exact API and limits. Native engine question structure is consumed as returned, not repaired by this adapter.",
807
+ ref: "packages/crl/docs/apply-session.md; results/tests/sessionResponse.test.ts; results/tests/session.test.ts",
808
+ clauses: [
809
+ { text: "Choose full or edits-only explicitly and distinguish omission from clear; retain prior successful caller state on failure.", force: "default" },
810
+ { text: "Verify native actions, answers and errors independently from adapter success; repeated-resource reconciliation remains caller-owned.", force: "default" },
811
+ ],
812
+ },
764
813
  {
765
814
  id: "produce-results",
766
815
  applicability: "All CRL authoring",
@@ -794,8 +843,8 @@ const RULES = [
794
843
  "contradicts itself (source-vs-source); `@open-fork` — an INTERNAL modeling fork you encoded one way but did not " +
795
844
  "settle (`chosen`/`alternatives` fields); `@fidelity-defect` — a known encoding≠source defect, with a REQUIRED " +
796
845
  "`direction` = `over-reach|criterion-drop` (over-reach = you ADDED logic the source doesn't support; criterion-drop = " +
797
- "you OMITTED a source-required criterion). Use a short `gist` title and put the source detail, options, reasoning, consequences and MV question in top-level `description`. " +
798
- "Description is plain text displayed in MV; `fields.description` is rejected: use the top-level parameter. Description is trimmed at the edges, omitted when blank, and permits newlines, semicolons and backticks. Description does not participate in retry identity; retrying with changed detail returns the existing record without overwriting it. There is no MCP amend operation for an existing Description; fix it through the KE-owned record workflow, not by filing a duplicate with a changed gist. An optional issue link belongs in `fields.ref` (e.g. `#207`). " +
846
+ "you OMITTED a source-required criterion). Use a short `title` and put the source detail, options, reasoning, consequences and MV question in top-level `description`. " +
847
+ "Title is the flag header; Description is the separate explanation. The API accepts `title` (preferred) or legacy `gist`; when both are supplied they must match after trimming. Records keep schema1 `gist` and `description`: no stored-record rename or migration. Verify the persisted record and rendered header/Description after authoring. Description is plain text displayed in MV; `fields.description` is rejected: use the top-level parameter. Description is trimmed at the edges, omitted when blank, and permits newlines, semicolons and backticks. Description does not participate in retry identity; retrying with changed detail returns the existing record without overwriting it. There is no MCP amend operation for an existing Description; fix it through the KE-owned record workflow, not by filing a duplicate with a changed gist. An optional issue link belongs in `fields.ref` (e.g. `#207`). " +
799
848
  "Accept flag moves an open KE flag into MV with the same ID/content/anchor; Reject flag closes it without conversion. Author flags `status open` (the default). An open flag blocks Medical Validation " +
800
849
  "completion. Separately, `@gap-filed` IS still a `.crl` meta tag (NOT a flag) — a durable `- meta is `@gap-filed: …; " +
801
850
  "ref <issue>`.` pointer to an already-filed gap, REQUIRED `; ref`; it ships fine and does not gate. The four flag " +
@@ -840,7 +889,7 @@ const RULES = [
840
889
  },
841
890
  {
842
891
  text: "How to WRITE flags — use the `crl` MCP tools; they write the store directly. `create_flag` authors a flag on a " +
843
- "concept, decision, or library (pass `kind`, `name`, the `tag`, a short `gist`, optional plain-text `description`, and required extra `fields` " +
892
+ "concept, decision, or library (pass `kind`, `name`, the `tag`, a short `title`, optional plain-text `description`, and required extra `fields` " +
844
893
  "like `direction`, and the optional issue link as `fields.ref`); `set_flag_status` flips one flag " +
845
894
  '`open`<->`resolved` by selector. This KE automation API remains distinct from human MV Accept/Reject: resolving an extraction flag leaves it KE-owned and creates no MV flag. Pass `tag` as the BARE tag id — `"open-fork"`, `"fidelity-defect"` (the `@` ' +
846
895
  'prefix is display-only prose; `tag: "@open-fork"` is an `unknown-tag`). Both REQUIRE a `path` to a `.crl` file ' +
@@ -894,6 +943,7 @@ const TYPE_ALLOWLIST = {
894
943
  const EXAMPLES = [
895
944
  { id: "datetime-answer", title: "Date/time answer", language: "crl", valid: true, snippet: intakeExample_1.DATETIME_ANSWER, note: "Selected Observation dateTime answer. Add to a CRL library with crl.canonicalBase for emission; pair with a has-value predicate when a Boolean guard is needed. Native intake acceptance verifies the actual generated dateTime question, calendar precision, timestamps and clear. Client picker behavior is a separate boundary." },
896
945
  { id: "source-field-order", title: "source-field-order", language: "crl", valid: true, snippet: sourceOrderExample_1.SOURCE_ORDER_EXAMPLE, note: "Exact declaration shared with concept-body-order-independence.test.ts: all concept fields precede the trailing source block. The owning test checks AST ownership and publication preparation, not native execution." },
946
+ { id: "coded-observation-source", title: "Selected coded Observation source", language: "crl", valid: true, snippet: codedSourceExample_1.CODED_SOURCE_POLICY, note: "Complete synthetic source-only policy shared with the coded-source emitter and CRE tests. Declare the tested source and result terminology; do not replace it with clinical codes without source justification. Supply package.json name coded-source and crl.canonicalBase https://example.org/coded-source. No local code means no editable question. Interpretation follows final selection; no extra indeterminate modifier is introduced. These source tests do not certify a customer policy or native execution." },
897
947
  { id: "quantity-declaration", title: "quantity-declaration", language: "crl", valid: true, snippet: quantityExample_1.QUANTITY_EXAMPLE_DECLARATION, note: "Exact current Quantity declaration from the owning CEL numeric-literal test. Supply package.json crl.canonicalBase for emission. This example defines a measurement, not a Boolean decision guard." },
898
948
  { id: "quantity-answer", title: "quantity-answer", language: "cel", valid: true, snippet: quantityExample_1.QUANTITY_EXAMPLE_FACT, note: "Fact excerpt shared verbatim with numericValueRules.test.ts. Use within a CEL library covering L with a Patient subject and case referencing F. The owning test checks numeric-literal diagnostics; this excerpt does not establish BMI, unit conversion or native execution." },
899
949
  {
@@ -957,14 +1007,14 @@ const EXAMPLES = [
957
1007
  {
958
1008
  id: "open-fork-flag", title: "Review flag: an @open-fork on the concept it concerns (via create_flag — short title, detail in Description)",
959
1009
  language: "text",
960
- snippet: 'create_flag(\n path: "<policy>/src/crl/coverage-policy.crl",\n kind: "concept", name: "BMI Threshold",\n tag: "open-fork",\n gist: "Eligibility threshold",\n description: "Encoded BMI-40-only provisionally. The source also allows 35-plus-comorbidity. This changes who qualifies; which reading should apply?",\n fields: { chosen: "bmi-40-only", alternatives: "bmi-35-plus-comorbidity", ref: "#207" }\n)\n→ writes <policy>/src/medical-validation/flags/<id>.json (status defaults to open)',
1010
+ snippet: 'create_flag(\n path: "<policy>/src/crl/coverage-policy.crl",\n kind: "concept", name: "BMI Threshold",\n tag: "open-fork",\n title: "Eligibility threshold",\n description: "Encoded BMI-40-only provisionally. The source also allows 35-plus-comorbidity. This changes who qualifies; which reading should apply?",\n fields: { chosen: "bmi-40-only", alternatives: "bmi-35-plus-comorbidity", ref: "#207" }\n)\n→ writes <policy>/src/medical-validation/flags/<id>.json (status defaults to open)',
961
1011
  valid: true,
962
1012
  note: "The flag is a STORE record, not a `.crl` line: a short gist + detailed `description` + `chosen`/`alternatives` (semantic, optional) + an optional issue `ref`. `create_flag` writes `medical-validation/flags/<id>.json`; it does NOT touch the `.crl`. An open flag blocks Medical Validation completion.",
963
1013
  },
964
1014
  {
965
1015
  id: "fidelity-defect-flag", title: "Review flag: an @fidelity-defect on a DECISION (required `direction` field)",
966
1016
  language: "text",
967
- snippet: 'create_flag(\n path: "<policy>/src/crl/coverage-decision.crl",\n kind: "decision", name: "Coverage Decision",\n tag: "fidelity-defect",\n gist: "the encoding reads an axillary-only finding the source does not require",\n fields: { direction: "over-reach", ref: "#207" }\n)',
1017
+ snippet: 'create_flag(\n path: "<policy>/src/crl/coverage-decision.crl",\n kind: "decision", name: "Coverage Decision",\n tag: "fidelity-defect",\n title: "the encoding reads an axillary-only finding the source does not require",\n fields: { direction: "over-reach", ref: "#207" }\n)',
968
1018
  valid: true,
969
1019
  note: 'Anchor at the narrowest faithful scope — here `kind: "decision"`. `@fidelity-defect` REQUIRES a `direction` = over-reach|criterion-drop; omitting it → `create_flag` returns `reason: missing-field` and writes nothing.',
970
1020
  },
@@ -978,7 +1028,7 @@ const EXAMPLES = [
978
1028
  {
979
1029
  id: "library-flag", title: "Review flag at LIBRARY scope: an @internal-inconsistency spanning the whole policy (via create_flag)",
980
1030
  language: "text",
981
- snippet: 'create_flag(\n path: "<policy>/src/crl/policy.crl",\n kind: "library", name: "Coverage Policy",\n tag: "internal-inconsistency",\n gist: "the eligibility section requires prior imaging, but the exclusions section forbids it",\n fields: { ref: "#207" }\n)',
1031
+ snippet: 'create_flag(\n path: "<policy>/src/crl/policy.crl",\n kind: "library", name: "Coverage Policy",\n tag: "internal-inconsistency",\n title: "the eligibility section requires prior imaging, but the exclusions section forbids it",\n fields: { ref: "#207" }\n)',
982
1032
  valid: true,
983
1033
  note: 'Use `kind: "library"` (name = the library name) for a contradiction that isn\'t about one concept or decision. `@internal-inconsistency` = the SOURCE contradicts itself. The flag anchors to the library; nothing is written into the `.crl`.',
984
1034
  },