@case-framework/survey-assistant 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/dist/{authoring-references-DbuOKerg.mjs → authoring-references-CmwLc_C8.mjs} +40 -32
  2. package/dist/authoring-references-CmwLc_C8.mjs.map +1 -0
  3. package/dist/capabilities-D55dq-fO.mjs +582 -0
  4. package/dist/capabilities-D55dq-fO.mjs.map +1 -0
  5. package/dist/capabilities-default.d.mts +4 -12
  6. package/dist/capabilities-default.d.mts.map +1 -1
  7. package/dist/capabilities-default.mjs +2 -2
  8. package/dist/capabilities-z95e1mti.d.mts +117 -0
  9. package/dist/capabilities-z95e1mti.d.mts.map +1 -0
  10. package/dist/{constants-B6HzpEsx.d.mts → constants-HL_klgJl.d.mts} +4 -4
  11. package/dist/{constants-B6HzpEsx.d.mts.map → constants-HL_klgJl.d.mts.map} +1 -1
  12. package/dist/{controller-proxy-DEeFl9IA.mjs → controller-proxy-BQ1YsVxJ.mjs} +4 -3
  13. package/dist/controller-proxy-BQ1YsVxJ.mjs.map +1 -0
  14. package/dist/{controller-proxy-D7uQfm5f.d.mts → controller-proxy-Cmzdr9tV.d.mts} +4 -4
  15. package/dist/{controller-proxy-D7uQfm5f.d.mts.map → controller-proxy-Cmzdr9tV.d.mts.map} +1 -1
  16. package/dist/default-D22AKTqE.mjs +233 -0
  17. package/dist/default-D22AKTqE.mjs.map +1 -0
  18. package/dist/{digest-C39WyAWG.d.mts → digest-FnTTDBq2.d.mts} +2 -2
  19. package/dist/digest-FnTTDBq2.d.mts.map +1 -0
  20. package/dist/digest.d.mts +1 -1
  21. package/dist/engine-D950TfvC.mjs +3098 -0
  22. package/dist/engine-D950TfvC.mjs.map +1 -0
  23. package/dist/engine.d.mts +4 -3
  24. package/dist/engine.mjs +3 -3
  25. package/dist/{index-WB5kfnz0.d.mts → index-B8TLBd1G.d.mts} +8 -6
  26. package/dist/index-B8TLBd1G.d.mts.map +1 -0
  27. package/dist/index-CaX3hZmr.d.mts +23813 -0
  28. package/dist/index-CaX3hZmr.d.mts.map +1 -0
  29. package/dist/{index-r5riv4md.d.mts → index-CeUlGkoU.d.mts} +27 -6
  30. package/dist/index-CeUlGkoU.d.mts.map +1 -0
  31. package/dist/{index-D7wT6P3t.d.mts → index-DYHdvSE8.d.mts} +83 -41
  32. package/dist/index-DYHdvSE8.d.mts.map +1 -0
  33. package/dist/lifecycle-DFzxVxpq.d.mts +54346 -0
  34. package/dist/lifecycle-DFzxVxpq.d.mts.map +1 -0
  35. package/dist/{memory-thread-repository-DAnOGIB3.mjs → memory-thread-repository-DmLadygY.mjs} +15 -9
  36. package/dist/{memory-thread-repository-DAnOGIB3.mjs.map → memory-thread-repository-DmLadygY.mjs.map} +1 -1
  37. package/dist/protocol-BQ7uIDYT.mjs +569 -0
  38. package/dist/protocol-BQ7uIDYT.mjs.map +1 -0
  39. package/dist/protocol.d.mts +4 -4
  40. package/dist/protocol.mjs +3 -2
  41. package/dist/{react-C_GY-Fsc.mjs → react-DybJ5pWw.mjs} +17 -11
  42. package/dist/react-DybJ5pWw.mjs.map +1 -0
  43. package/dist/react-integration.d.mts +1 -1
  44. package/dist/react-integration.mjs +1 -1
  45. package/dist/react.d.mts +2 -2
  46. package/dist/react.mjs +2 -2
  47. package/dist/references/assistant-operations.md +190 -215
  48. package/dist/references/core-rules.md +2 -2
  49. package/dist/references/element-types.md +189 -0
  50. package/dist/references/expressions.md +215 -238
  51. package/dist/references/follow-ups.md +151 -0
  52. package/dist/references/localization.md +26 -12
  53. package/dist/references/response-variables.md +3 -3
  54. package/dist/references/rich-text-content.md +22 -43
  55. package/dist/references/source-material-surveys.md +20 -25
  56. package/dist/references/survey-data-model.md +36 -117
  57. package/dist/{request-context-Dg4jSwN1.mjs → request-context-KVh8VjgH.mjs} +4 -4
  58. package/dist/request-context-KVh8VjgH.mjs.map +1 -0
  59. package/dist/server-agent.d.mts +28 -7
  60. package/dist/server-agent.d.mts.map +1 -1
  61. package/dist/server-agent.mjs +33 -25
  62. package/dist/server-agent.mjs.map +1 -1
  63. package/dist/server-runtime.d.mts +6 -5
  64. package/dist/server-runtime.d.mts.map +1 -1
  65. package/dist/server-runtime.mjs +3 -3
  66. package/dist/server-tasks.d.mts +1 -1
  67. package/dist/server-tasks.mjs +1 -1
  68. package/dist/server-tools.d.mts +1 -1
  69. package/dist/server-tools.mjs +1 -1
  70. package/dist/server.d.mts +7 -6
  71. package/dist/server.d.mts.map +1 -1
  72. package/dist/server.mjs +3 -3
  73. package/dist/{tasks-BZEiwgxA.mjs → tasks-Coh5N027.mjs} +16 -15
  74. package/dist/tasks-Coh5N027.mjs.map +1 -0
  75. package/dist/{tasks-B9h3LPam.d.mts → tasks-wb9M-bak.d.mts} +11 -11
  76. package/dist/{tasks-B9h3LPam.d.mts.map → tasks-wb9M-bak.d.mts.map} +1 -1
  77. package/dist/{thread-handlers-Bef0td9N.d.mts → thread-handlers-C3Iya92v.d.mts} +6 -5
  78. package/dist/thread-handlers-C3Iya92v.d.mts.map +1 -0
  79. package/dist/{tools-CEsv-WoO.mjs → tools-D0KBDolR.mjs} +435 -408
  80. package/dist/tools-D0KBDolR.mjs.map +1 -0
  81. package/dist/turn-survey-draft-B34lggSG.d.mts +185 -0
  82. package/dist/turn-survey-draft-B34lggSG.d.mts.map +1 -0
  83. package/dist/ui.d.mts +3 -3
  84. package/dist/ui.d.mts.map +1 -1
  85. package/dist/ui.mjs +35 -23
  86. package/dist/ui.mjs.map +1 -1
  87. package/package.json +7 -7
  88. package/dist/authoring-references-DbuOKerg.mjs.map +0 -1
  89. package/dist/capabilities-CmeeAjEc.d.mts +0 -192
  90. package/dist/capabilities-CmeeAjEc.d.mts.map +0 -1
  91. package/dist/capabilities-DCMA71PP.mjs +0 -58
  92. package/dist/capabilities-DCMA71PP.mjs.map +0 -1
  93. package/dist/controller-proxy-DEeFl9IA.mjs.map +0 -1
  94. package/dist/default-fhSon2RM.mjs +0 -760
  95. package/dist/default-fhSon2RM.mjs.map +0 -1
  96. package/dist/digest-C39WyAWG.d.mts.map +0 -1
  97. package/dist/engine-nXoCWYpQ.mjs +0 -6888
  98. package/dist/engine-nXoCWYpQ.mjs.map +0 -1
  99. package/dist/index-Ciq7vHIs.d.mts +0 -716
  100. package/dist/index-Ciq7vHIs.d.mts.map +0 -1
  101. package/dist/index-D7wT6P3t.d.mts.map +0 -1
  102. package/dist/index-WB5kfnz0.d.mts.map +0 -1
  103. package/dist/index-r5riv4md.d.mts.map +0 -1
  104. package/dist/lifecycle-Dm8u7QFh.d.mts +0 -545
  105. package/dist/lifecycle-Dm8u7QFh.d.mts.map +0 -1
  106. package/dist/protocol-CF4Bh_Ch.mjs +0 -1255
  107. package/dist/protocol-CF4Bh_Ch.mjs.map +0 -1
  108. package/dist/react-C_GY-Fsc.mjs.map +0 -1
  109. package/dist/references/embedded-forms.md +0 -146
  110. package/dist/references/item-types.md +0 -641
  111. package/dist/request-context-Dg4jSwN1.mjs.map +0 -1
  112. package/dist/tasks-BZEiwgxA.mjs.map +0 -1
  113. package/dist/thread-handlers-Bef0td9N.d.mts.map +0 -1
  114. package/dist/tools-CEsv-WoO.mjs.map +0 -1
@@ -0,0 +1,151 @@
1
+ # Option-inline follow-ups
2
+
3
+ A follow-up is a composition body directly below the visible option that triggers it, keeping the option-to-input connection clear. Use it for “Other, please specify”, “Yes, explain”, or option-specific quantities and dates. It is stored as `config.options[index].followUp` on a radio or checkbox **choice element**. There is no form wrapper, `allowOther` flag or simple/custom authoring mode.
4
+
5
+ ## Structure and mutations
6
+
7
+ A follow-up has the same `{ "blocks": [...] }` structure as an item body. It can contain layouts, elements and semantic sections. It cannot contain another follow-up, even indirectly through sections or custom elements. The owning element occupies a full row. Dropdowns cannot own follow-ups; put another conditionally visible element after the dropdown instead.
8
+
9
+ For a new element, include the complete option and follow-up in its creation payload, with owner-role translations in the same operation. For an existing element, inspect its exact option index and current config, then use `patch-element-config` to add or update the option's `followUp`. Once the body exists, `insert-blocks` can target its triggering option's `bodyOwnerId`, and `insert-element` targets a layout ID. Use shared move/remove operations for existing children so rules, identities and owned content stay consistent. Load the focused operation contract before writing payloads.
10
+
11
+ Example follow-up value:
12
+
13
+ ```json
14
+ {
15
+ "blocks": [
16
+ {
17
+ "kind": "layout",
18
+ "id": "other-layout",
19
+ "layout": { "mode": "automatic", "maxColumns": 1 },
20
+ "elements": [
21
+ {
22
+ "kind": "element",
23
+ "id": "other-details",
24
+ "elementType": "text",
25
+ "config": {
26
+ "slotId": "other-details-slot",
27
+ "variableName": "other_details",
28
+ "presentation": "short",
29
+ "required": true
30
+ }
31
+ }
32
+ ]
33
+ }
34
+ ]
35
+ }
36
+ ```
37
+
38
+ Translate `option-other` role `label` as “Other” and `other-details` role `label` as “Please specify”. Avoid repeating the completion cue in both labels. Every input needs a usable accessible label, explicit or unambiguously inherited; supply an explicit label when the enclosing question would be ambiguous.
39
+
40
+ ## Activation and answers
41
+
42
+ The choice must be active, the option visible, and that option present in the checked stored selection. Sibling option visibility is not a dependency of this gate. No separate visibility expression is needed just to activate a follow-up. Hidden or unselected follow-up answers are retained in session storage but absent from active expressions, validation and submission. Showing the same follow-up again restores its answer.
43
+
44
+ Disabling does not close an otherwise active follow-up or erase answers. Ancestor locks prevent participant edits and make its validation non-blocking; active disabled answers still participate in expressions and submission. Use visibility for inapplicability, disabling for locking. Follow-up inputs retain their own persistent slot IDs through movement, copying with remapping, and localization.
45
+
46
+ Custom elements may own follow-ups only when their installed capability explicitly declares the same trigger and activation contract. Do not invent custom container semantics or bypass the one-level rule.
47
+
48
+ ## Full worked example: multiple choice with an Other input
49
+
50
+ Create the option, follow-up and their wording together. The text input's required rule applies only while its follow-up is active and changeable. Replace `<root-group-id>` with the current root; use unused IDs.
51
+
52
+ ```json
53
+ {
54
+ "kind": "create-item",
55
+ "target": {
56
+ "parentItemId": "<root-group-id>"
57
+ },
58
+ "item": {
59
+ "id": "transport",
60
+ "itemType": "content",
61
+ "config": {
62
+ "body": {
63
+ "blocks": [
64
+ {
65
+ "kind": "layout",
66
+ "id": "transport-layout",
67
+ "layout": {
68
+ "mode": "automatic",
69
+ "maxColumns": 1
70
+ },
71
+ "elements": [
72
+ {
73
+ "kind": "element",
74
+ "id": "transport-choice",
75
+ "elementType": "choice",
76
+ "config": {
77
+ "slotId": "transport-slot",
78
+ "variableName": "transport",
79
+ "presentation": "checkbox",
80
+ "maxSelection": null,
81
+ "options": [
82
+ {
83
+ "id": "transport-walk",
84
+ "code": "WALK"
85
+ },
86
+ {
87
+ "id": "transport-other",
88
+ "code": "OTHER",
89
+ "followUp": {
90
+ "blocks": [
91
+ {
92
+ "kind": "layout",
93
+ "id": "transport-other-layout",
94
+ "layout": {
95
+ "mode": "automatic",
96
+ "maxColumns": 1
97
+ },
98
+ "elements": [
99
+ {
100
+ "kind": "element",
101
+ "id": "transport-other-text",
102
+ "elementType": "text",
103
+ "config": {
104
+ "slotId": "transport-other-slot",
105
+ "variableName": "transport_other",
106
+ "presentation": "short",
107
+ "required": true
108
+ }
109
+ }
110
+ ]
111
+ }
112
+ ]
113
+ }
114
+ }
115
+ ]
116
+ }
117
+ }
118
+ ]
119
+ }
120
+ ]
121
+ }
122
+ }
123
+ },
124
+ "translations": [
125
+ {
126
+ "ownerId": "transport",
127
+ "role": "title",
128
+ "locale": "en",
129
+ "plainText": "How do you travel? Select all that apply."
130
+ },
131
+ {
132
+ "ownerId": "transport-walk",
133
+ "role": "label",
134
+ "locale": "en",
135
+ "plainText": "On foot"
136
+ },
137
+ {
138
+ "ownerId": "transport-other",
139
+ "role": "label",
140
+ "locale": "en",
141
+ "plainText": "Other"
142
+ },
143
+ {
144
+ "ownerId": "transport-other-text",
145
+ "role": "label",
146
+ "locale": "en",
147
+ "plainText": "Please specify"
148
+ }
149
+ ]
150
+ }
151
+ ```
@@ -4,6 +4,7 @@ Use this reference when the user asks to translate, localize, add a language, or
4
4
 
5
5
  ## Locale Lifecycle
6
6
 
7
+ - When continuing a retained UI task, check the live locale list. If its target was removed, ask whether to restore it before writing unless the current message explicitly asks to add or restore that language.
7
8
  - A target locale may be absent. That is a normal starting state, not an error and not a reason to inspect a nonexistent translation branch.
8
9
  - An unqualified request to "add a German localization", "add German", or translate/localize the survey means make the existing respondent-facing content available in that language. Registering an empty locale does not complete that request.
9
10
  - Use `add-survey-locale` only when the user explicitly wants the language registered before it has translated content. It rejects blank and already-present locale codes.
@@ -14,18 +15,31 @@ Use this reference when the user asks to translate, localize, add a language, or
14
15
  - Never put target-language respondent text into an existing source-language locale just because that locale already exists.
15
16
  - Coding keys and editor-only item labels are not respondent translations. Translate them only when the user explicitly asks.
16
17
 
17
- ## Scope A Complete Localization Correctly
18
+ ## Scope and reference languages
18
19
 
19
- 1. Use `survey_inspect` with `action: "localization"`, the source locale, and the target locale. Page until `nextCursor` is absent; this covers existing respondent-visible item and survey translation surfaces without one item-details call per item.
20
- 2. Treat `sourceText` and `targetText` as previews. When `sourceTruncated` is true for plain text, retrieve `sourceTextPath` through `survey_inspect` action `raw-json`, then follow `nextTextOffset` using `textOffset` and that same path until all segments are read. Translate the complete source, never only the preview. Rich-text `sourceContent` already contains the full canonical value. `targetPresent` proves presence, not translation fidelity or completeness.
21
- 3. Inspect item configuration separately only when the localization surface result or an audit indicates that the source survey itself is missing a visible content key. This includes choice-option labels, form-field labels, select-option labels, embedded-form labels, and validation copy.
22
- 4. Preserve the source language while writing each target-language value under the target locale. Do not replace source content or translation containers.
23
- 5. Use `update-item-translation` for ordinary item content. Use typed choice operations only when also changing the choice structure. Use a focused raw patch only for a supported survey-level translation surface that has no typed operation.
24
- 6. Before proposing, check that every visible label implied by the inspected item configuration has a target-locale translation. A title alone is not a complete localization of a choice or form item.
20
+ Translation-workspace launches state the request briefly and attach its exact parameters as the UI-launched task: `kind` is `localization.translate-missing` or `localization.review-existing`, and `data` holds `targetLocale`, `scope` (`survey`, `item`, or `fields`), `itemId` for an item scope, and `localizationRefs` for selected fields. Use these values exactly; the visible message names the fields only for the user.
25
21
 
26
- ## Bounded Execution
22
+ The task is retained with the thread and replayed on follow-ups and reopened chats. Continue within that original scope unless the user explicitly changes it; a different current UI selection does not change the task.
27
23
 
28
- - Prefer one atomic proposal for a coherent localization when it fits the advertised operation limit. The limit is a hard safety bound, not a target chunk size.
29
- - Split only an oversized localization into independent, coherent chunks by section or item set. Each successful chunk updates the request-scoped draft for the next inspection.
30
- - After each chunk, call the localization inspection again with `missingOnly: true` and no cursor, because a draft change invalidates offsets into the previous missing-only result. Completion means it returns no remaining source surfaces for the target locale.
31
- - If live inspection or a source translation cannot determine a phrase accurately, ask a focused clarification rather than inventing domain-specific wording.
24
+ 1. Use `survey_inspect` with `action: "localization"` and `targetLocale`. Omit `sourceLocale` unless the user explicitly chose an authoritative source language. All available non-target language versions are returned as `references`; the UI's selected language and visible columns are not a source-language instruction.
25
+ 2. Pass `itemRef` as an existing canonical item id for a content item or flow group. This includes its descendants and excludes survey-level texts. For selected text fields, pass their exact `localizationRefs` (at most 200 per request; split larger selections and track every group). The result lists unavailable exact refs separately. Continue with available refs, report unavailable refs, and never widen the scope. An invalid item scope is an error. Entries without reference text in another language cannot be translated or comparatively reviewed; report them separately.
26
+ 3. Read complete reference texts and complete targets before judging meaning. Each reference and target has a `text` preview and canonical `path`. For truncated plain or md values, inspect `raw-json` with `paths: [textPath]`, following `nextTextOffset` with `textOffset` until complete. Rich-text `content` is the complete canonical value, including links, images, templates, and metadata. Never translate or review just the preview.
27
+ 4. Cross-check references for terminology, register, omitted clauses, negation, numbers, units, and response-option meaning. If versions disagree materially and the user did not establish authority, ask a focused question. Do not silently choose a source or blend contradictory meanings. Existing target wording is context, not proof of correctness.
28
+ 5. Use `update-content` with the inspected owner/role localization ref, or `update-survey-translation` with the exact destination locale. Preserve other languages, item structure, option identifiers, links, templates, extensions, and metadata. Use canonical rich `content` to retain rich text; `plainText` is not a replacement for rich content.
29
+
30
+ ## Translate missing
31
+
32
+ - Inspect with `missingOnly: true`. Only add missing target texts; do not revise existing translations.
33
+ - Work in coherent chunks within the advertised operation limit. Each successful change updates the same-turn draft.
34
+ - After a chunk, re-inspect missing texts without a cursor until the complete scope is covered. Completion means no remaining missing texts that have a usable reference, not merely the last page being empty.
35
+ - Report completed work, remaining entries, unresolved conflicts, or failures honestly. Do not introduce dummy translations to reach zero missing.
36
+
37
+ ## Review and correct
38
+
39
+ - Inspect with `missingOnly: false`. Skip entries with `targetPresent: false` (including stored empty content). Review complete references and target, correct concrete problems, and leave acceptable translations unchanged. Do not fill missing values during a review.
40
+ - Traverse every page. Apply corrections per page, then continue with the returned cursor. Cursors survive target-text edits, including translating the anchor; they reject changes to reference content, order, scope, and query.
41
+ - A rejected cursor starts a fresh review pass: recompute the initial translated count, reset reviewed/changed counts, and report corrections retained from earlier passes separately. Never combine counts from incompatible passes.
42
+ - `translatedCount` supplies the initial number of present targets for that pass. Count an entry as reviewed only after reading complete content and reaching a judgment. Count changed entries only after successful application. Failed reads, unapplied corrections, interruptions, or unresolved disagreements mean a partial result, not a completed review.
43
+ - Report which texts changed and why, how many were reviewed, and what remains. Presence counts do not establish accuracy, completeness within a text, approval, or freshness.
44
+
45
+ Authoring readiness uses the currently selected locale. A usable source translation does not make an empty target translation ready. Translation coverage is reported separately; do not turn missing content in unrelated locales into structural failures. Content owner IDs and roles survive moves without path rewriting.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Items have stable IDs and resolved editor names. Use exact item IDs in operation targets; inspect names, breadcrumbs and response-variable metadata to find them. Duplicate display names are legal and never identify a unique item by themselves. Editing an editor name does not rename data.
4
4
 
5
- A response variable has a persistent survey-unique slotId, itemId owner, primitiveId, variableName, valueType, and optional finite allowedValues, naming source, option codes, labels, scores, and computed dependencies. Inspect response slots or item details; never construct slot IDs from names, paths, or suffixes. Form and embedded-field slots use field.id; consent uses config.slotId; matrix computed slots are persisted separately.
5
+ A response variable has a persistent survey-unique slotId, itemId owner, elementId, variableName, valueType, and optional finite allowedValues, naming source, option codes, labels, scores, and computed dependencies. Inspect response slots or item details; never construct slot IDs from names, paths, or suffixes. Scalar elements declare config.slotId; matrix rows/cells and computed scores declare their own persistent IDs. Follow-up inputs use the same element contracts as root inputs.
6
6
 
7
7
  Expressions use {"type":"responseVariable","variableRef":{"slotId":"exact-slot-id","method":"get"}} or method "isDefined". Categorical values and constants use stable option IDs, not labels or export codes. Dropdowns are reference-valued too. False, zero, empty selection, and missing are distinct; do not introduce sentinel answers. The host supplies schema-bound flat answers[slotId] values.
8
8
 
@@ -29,9 +29,9 @@ Use survey_change with kind "update-response-settings", naming and settings arra
29
29
  }
30
30
  ```
31
31
 
32
- Scalar naming: {slotId,variableName}. Matrix naming: {primitiveId,prefix?,rows?:{rowId:rowName},columns?:{columnId:columnName}}. A matrix cell name is derived from its prefix, row and column; choice matrices derive row answers and computed scores from the same family. Never set per-cell names or export headers. Preview all affected family names and edit components together. Configuration overrides remain supported for form-matrix cells.
32
+ Scalar naming: {slotId,variableName}. Matrix naming: {elementId,prefix?,rows?:{rowId:rowName},columns?:{columnId:columnName}}. A matrix cell name is derived from its prefix, row and column; choice matrices derive row answers and computed scores from the same family. Never set per-cell names or export headers. Preview all affected family names and edit components together. Configuration overrides remain supported for form-matrix cells.
33
33
 
34
- Settings: {slotId,optionCodes?,exportSettings?}. optionCodes changes source option export codes by stable option ID; it does not change IDs, labels or scores. Shared matrix/dropdown options affect every slot that uses them. exportSettings replaces that slot's defaults: include, mode (default/dateFormat/mask), categorical (codes/labels/ids), multiple (json/delimited/indicators), delimiter, locale, optionCodes, optionLabels, booleanValues {true,false}, precision, durationUnit, dateFormat {pattern}, maskChar. Inspect existing settings first and retain settings you are not asked to change. Profiles override these defaults outside authoring. Defaults are codes, JSON arrays, TRUE/FALSE, seconds and excluded computed slots.
34
+ Settings: {slotId,optionCodes?,exportSettings?}. optionCodes changes source option export codes by stable option ID; it does not change IDs, labels or scores. Shared matrix/dropdown options affect every slot that uses them. exportSettings replaces that slot's defaults: include, mode (default/dateFormat/mask), categorical (codes/labels/ids), multiple (json/delimited/indicators), delimiter, locale, optionCodes, optionLabels, booleanValues {true,false}, precision, durationUnit, dateFormat {pattern}, maskText. Inspect existing settings first and retain settings you are not asked to change. Profiles override these defaults outside authoring. Defaults are codes, JSON arrays, TRUE/FALSE, seconds and excluded computed slots.
35
35
 
36
36
  The shared core validates survey-wide variable-name and projected-header uniqueness, typed domains, and matrix restrictions. Coding changes preserve answer/expression identities and apply through normal editor history. Do not use raw patches to bypass these constraints. Wording, translation, movement, layout, and editor-name changes preserve existing variable names and codes.
37
37
 
@@ -5,12 +5,11 @@ Do not use markdown syntax for formatting; `md` content is displayed as plain te
5
5
 
6
6
  Use typed translation operations for formatted text. Prefer `plainText` for all unformatted text, including a simple title, label, or one-paragraph info item. Use richText only when formatting carries meaning or structure. In canonical operation payloads, a complete structured value belongs in `content`. Use `survey-json-patch` for rich text only when you need to edit raw paths that typed translation operations cannot address.
7
7
 
8
- For `survey_change`, compact `richTextBlocks` shorthand is accepted wherever a typed translation accepts structured `content`. This includes translation entries on `create-item`, `upsert-form-field-group`, `upsert-form-field`, and `set-embedded-form`, plus the top level of `update-item-translation` and `update-survey-translation`. It is normalized to canonical `content` before validation. This is an input convenience, not evidence that every accepting surface renders formatting. For an item surface whose capability profile marks `format=rich`, prefer the shorthand when creating or replacing its complete formatted value because it avoids unnecessary deeply nested payloads. It is especially useful for source-document imports:
8
+ For `survey_change`, compact `richTextBlocks` shorthand is accepted wherever a typed translation accepts structured `content`. This includes translation entries on `create-item`, `insert-element`, `insert-blocks`, and configuration edits, plus the top level of `update-content` and `update-survey-translation`. It is normalized to canonical `content` before validation. This is an input convenience, not evidence that every accepting surface renders formatting. For an owner role whose declared inline/block policy permits the intended formatting, prefer the shorthand when creating or replacing its complete formatted value because it avoids unnecessary deeply nested payloads. It is especially useful for source-document imports:
9
9
 
10
10
  ```json
11
11
  {
12
12
  "locale": "en",
13
- "contentKey": "content",
14
13
  "richTextBlocks": [
15
14
  { "type": "heading", "level": 2, "text": "How should I complete this survey?" },
16
15
  { "type": "paragraph", "text": "Read each question carefully before answering." },
@@ -32,7 +31,7 @@ Provide exactly one representation for a translation: `plainText`, canonical `co
32
31
  model-facing `richTextBlocks` shorthand. Never combine them. `richTextBlocks` must contain at least
33
32
  one block. Put it at the same level where the canonical `content` property would appear: inside a
34
33
  translation entry for operations with a `translations` array, or at the operation top level for
35
- `update-item-translation` and `update-survey-translation`. Do not nest shorthand nodes inside a
34
+ `update-content` and `update-survey-translation`. Do not nest shorthand nodes inside a
36
35
  canonical `content.doc` tree. The shorter `blocks` property is accepted as a compatibility alias at
37
36
  the same locations, but prefer `richTextBlocks` in new operations.
38
37
 
@@ -45,7 +44,8 @@ The shorthand also supports inline runs through `children`. Use it when a paragr
45
44
  ```json
46
45
  {
47
46
  "locale": "en",
48
- "contentKey": "title",
47
+ "ownerId": "<item-id>",
48
+ "role": "title",
49
49
  "richTextBlocks": [
50
50
  {
51
51
  "type": "paragraph",
@@ -139,7 +139,7 @@ Style values:
139
139
  Supported block types:
140
140
 
141
141
  - `paragraph`
142
- - `heading` with `level` 1 for section headings or `level` 2 for subsection headings. Do not author levels 3 through 6; the player offsets/clamps these stored levels to semantic page headings.
142
+ - `heading` with `level` 1 for section headings or `level` 2 for subsection headings. Do not author levels 3 through 6; the player offsets/clamps these stored levels to semantic page headings. Any other level, in canonical blocks or `richTextBlocks` shorthand alike, is rejected rather than rounded.
143
143
  - `bulletList` with `listItem` entries
144
144
  - `image` with `source: { "type": "asset", "assetId": "..." }` or `source: { "type": "external", "url": "..." }`
145
145
  - `infoBox` with `tone: "info"` or `"warning"`
@@ -147,19 +147,12 @@ Supported block types:
147
147
 
148
148
  ## Where Rich Text Is Used
149
149
 
150
- For item translations, the installed item capability manifest is authoritative. Load
151
- `assistant-operations` with both `operationKind` and `itemType`; its item capability profile labels
152
- every fixed and dynamic content surface as `format=rich` or `format=plain`. Use rich text only for a
153
- surface marked `format=rich`. This covers custom item capabilities and avoids maintaining a second
154
- hardcoded surface list in guidance.
150
+ For owner-role content, inspect the installed schema's declared roles via item-details. Each role has `policy: "inline"` or `"block"`; custom elements use the same contract. Load `assistant-operations` with `operationKind` and `elementType` for its schema and focused guidance. A typed field accepting structured content does not authorize arbitrary formatting on every surface.
155
151
 
156
- For the built-in item types, these additional rendering constraints apply:
157
-
158
- - Info items: content key `content`; full block editor with paragraphs, headings, bullet lists, images, separators, and info boxes.
159
- - Choice item `topContent` / `bottomContent`: block rich text with paragraphs, headings, bullet lists, images, separators, and info boxes.
160
- - Form item `topContent` / `bottomContent`: block rich text with paragraphs, bullet lists, images, and separators only. Do not use headings or info boxes there.
161
- - Question `title` and `cardFooter`: compact rich text with paragraph blocks only. Inline styles may use bold, italic, underline, and color.
162
- - Question `subtitle`: compact rich text with paragraph blocks only. Inline styles may use bold, underline, and color. Do not rely on italic in subtitles.
152
+ - `inline` roles support paragraph text and inline styles/links; do not put headings, lists or images into a compact label. Item/section titles, input labels, option labels and consent headings use this policy.
153
+ - `block` roles support structured paragraphs, headings, lists, images, separators and info boxes. Information and consent bodies, item subtitles/footers, input help and section descriptions use this policy.
154
+ - Place the complete source document in the information/consent element's `body` role; keep the identifying title on its item/section or explicit element label. Avoid repeating the same heading inside the body unless the source or user calls for it.
155
+ - Content addresses are `{scope: "content", ownerId, role}`; creation translations carry `ownerId`, `role` and `locale`. An option's label belongs to the option ID, not a dotted key on the containing item. Inspect roles rather than inventing topContent/bottomContent or form fields.
163
156
 
164
157
  Survey-level `surveyCardContent`, `navigationContent`, and `validationMessages` are not item
165
158
  capability surfaces. Use `plainText` for them. They are metadata and interface-copy surfaces rather
@@ -172,14 +165,13 @@ the nearest supported representation.
172
165
 
173
166
  ## Updating Existing Rich Text
174
167
 
175
- Inspect the item first, then use `update-item-translation`. When replacing the complete surface with the common structures above, prefer `richTextBlocks`:
168
+ Inspect the item first, then use `update-content`. When replacing the complete surface with the common structures above, prefer `richTextBlocks`:
176
169
 
177
170
  ```json
178
171
  {
179
- "kind": "update-item-translation",
180
- "itemId": "info_1",
172
+ "kind": "update-content",
173
+ "ref": { "scope": "content", "ownerId": "info_1", "role": "body" },
181
174
  "locale": "en",
182
- "contentKey": "content",
183
175
  "richTextBlocks": [
184
176
  { "type": "heading", "level": 2, "text": "Instructions" },
185
177
  {
@@ -194,33 +186,20 @@ Inspect the item first, then use `update-item-translation`. When replacing the c
194
186
 
195
187
  This replaces that translation key for the target locale. Preserve existing blocks you still want; do not send only the new block unless the user asked to replace the whole content.
196
188
 
197
- ## Creating A Formatted Info Item
189
+ ## Creating formatted information
198
190
 
199
- For a new formatted info item, use one typed `create-item` operation with a compact `richTextBlocks` translation:
191
+ Use an information element in a content item (or an existing layout). Supply the formatted translation on that element's owner ID with role `body`, not the containing item's title. The complete generated create-item/insert-element contract defines the structural payload. For example, its translations entry may be:
200
192
 
201
193
  ```json
202
194
  {
203
- "kind": "create-item",
204
- "target": { "parentItemId": "<root-group-id-or-key>", "index": 0 },
205
- "item": { "id": "info_intro", "key": "intro", "itemType": "infoItem", "config": {} },
206
- "translations": [
207
- {
208
- "locale": "en",
209
- "contentKey": "content",
210
- "richTextBlocks": [
211
- { "type": "heading", "level": 2, "text": "Before you start" },
212
- { "type": "paragraph", "text": "This survey asks about your preferences." }
213
- ]
214
- }
195
+ "ownerId": "intro-information",
196
+ "role": "body",
197
+ "locale": "en",
198
+ "richTextBlocks": [
199
+ { "type": "heading", "level": 2, "text": "Instructions" },
200
+ { "type": "paragraph", "text": "Please answer about the last seven days." }
215
201
  ]
216
202
  }
217
203
  ```
218
204
 
219
- Use the full `content.doc` form from the Block Nodes section only when you need a
220
- structure that the compact forms above do not cover.
221
-
222
- The raw item can still be minimal:
223
-
224
- ```json
225
- { "id": "info_intro", "key": "intro", "itemType": "infoItem", "config": {} }
226
- ```
205
+ Owner-role references remain the same when the element moves. Preserve existing links, templates, assets and content metadata when translating or editing structured content.
@@ -15,7 +15,7 @@ Use this reference when the user asks to implement, recreate, convert, import, o
15
15
  - Implement every distinct question, instruction, answer option, section heading, and respondent input implied by the source unless the user explicitly asks for a summary.
16
16
  - Do not collapse multiple real questions into one text field. A text field is appropriate only when the source asks for open-ended text, an unsupported structured response cannot be represented more precisely, or the user explicitly asks for a free-text capture.
17
17
  - If the questionnaire body asks the respondent to record information, the digital survey must include an input control for it. Do not leave respondent-entered information as static text.
18
- - Empty lines, blanks, underscores, table cells intended for handwriting, parenthetical "specify" prompts, and inline write-in areas in actual questions imply an input field. Model them as form fields or embedded option forms as appropriate.
18
+ - Empty lines, blanks, underscores, table cells intended for handwriting, parenthetical "specify" prompts, and inline write-in areas in actual questions imply an input field. Model them as elements or option-inline follow-ups as appropriate.
19
19
  - Do not create respondent questions for front-cover study identifiers, barcodes, prefilled participant names, prefilled dates of birth, page numbers, institutional logos, or duplicate administrative fields when those values should come from digital participant metadata or are asked later as real survey questions.
20
20
  - Printed examples that demonstrate how to fill in a paper form should be preserved as instructional text when useful, not converted into real inputs.
21
21
  - Preserve question order, numbering intent, and section structure. For long sources, use multiple bounded mutation calls rather than omitting details. Bounded applies to each call, not the whole assistant turn; each successful call automatically extends the same turn draft.
@@ -26,50 +26,45 @@ Use this reference when the user asks to implement, recreate, convert, import, o
26
26
 
27
27
  ## Item Mapping
28
28
 
29
- - Map supported item types directly. Use `choiceItem` for single choice, multiple choice, and scale-like questions until a dedicated scale item exists.
30
- - For scale questions, create an ordered `choiceItem` with stable option IDs/codes and labels that preserve the endpoints and intermediate labels. Include the scale instruction in `subtitle` or `topContent` when it is not part of the actual question.
31
- - Use a simple `formItem` preset for a single text, long-text, number, slider, dropdown, date, or switch response. Use custom form mode for grouped personal data, tables, repeated inputs, contact details, or unsupported compound controls.
32
- - Prefer the supported semantic field type for the respondent value instead of copying the paper
33
- form's box layout. Use one `datepicker` with mode `year-month-day` for an ordinary full calendar
34
- date; use separate day/month/year fields only when the source measures those components
35
- independently or the user requests literal paper-form reproduction.
36
- - Use choice option embedded forms for choices that include an open field, such as "Other, specify", "Yes, explain", or an option-specific quantity/date/text input.
29
+ - Use the installed element registry. Ordinary questions usually become one element in a content item, using a preset where suitable. Use radio/checkbox/dropdown choice presentation as appropriate. For repeated common scales, use a choice matrix; preserve ordered endpoints, codes, scores and non-scoring responses.
30
+ - Use text, number, date or boolean elements for their actual value domains. Multiple related fields can share layouts and semantic sections inside one item. There is no separate form item or simple/custom mode.
31
+ - Use a date element with precision `year-month-day` for a full calendar date. Separate components only when the source measures them independently or the user explicitly requests that reproduction.
32
+ - Use radio/checkbox option-inline follow-ups for option-specific inputs such as “Other, specify”. Dropdown follow-ons use separately conditional elements. Follow-ups cannot own further follow-ups.
37
33
  - Preserve option-level parenthetical instructions, side notes, and footnote markers. If the current choice option UI has no separate option-description surface, fold short option notes into the visible option label, for example `Uitgenodigde persoon zelf (zie hiervoor de naam op de brief en/of geboortedatum op de voorkant van de vragenlijst)`, and keep markers such as `Iemand anders*`.
38
- - For sentence-completion options with an embedded input, put the completion cue on the embedded field label, not twice. Source text like `Iemand anders*, namelijk ____`, `Andere bedrijfstak, namelijk ____`, or `Other, please specify ____` should become option label `Iemand anders*` / `Andere bedrijfstak` / `Other` and embedded field label `Namelijk` / `Please specify`.
39
- - Use info items for non-interactive section introductions, explanations, instruction text, and visible page/section headings. Use a consent item when the participant must explicitly agree or decline, with the full information in `consentBody`. Keep simple paragraphs as plainText; use richText for headings, lists, links, separators, or meaningful emphasis.
40
- - Preserve major chapters/sections as survey structure. If page boundaries matter, use available page-break structure and/or a heading info item so respondents see the section break.
41
- - Include respondent-facing "before you begin", "how to complete this survey", eligibility, safety, and contact/help sections as info items when still relevant digitally. Preserve consent information and any requested decision using the appropriate info or consent item. Rewrite or omit paper-only return/postage instructions unless the user wants a literal reproduction.
34
+ - For sentence-completion options with a follow-up input, put the completion cue on the follow-up element label, not twice. Source text like `Iemand anders*, namelijk ____`, `Andere bedrijfstak, namelijk ____`, or `Other, please specify ____` should become option label `Iemand anders*` / `Andere bedrijfstak` / `Other` and follow-up element label `Namelijk` / `Please specify`.
35
+ - Use information elements in content items for non-interactive section introductions, explanations, instruction text, and visible page/section headings. Use a consent element when the participant must explicitly agree or decline, with the full information in the consent owner's `body` role. Keep simple paragraphs as plainText; use richText for headings, lists, links, separators, or meaningful emphasis.
36
+ - Preserve major chapters/sections as survey structure. If page boundaries matter, use available page-break structure and/or a content item with a heading so respondents see the section break.
37
+ - Include respondent-facing "before you begin", "how to complete this survey", eligibility, safety, and contact/help sections as information elements in content items when still relevant digitally. Preserve consent information and any requested decision using the appropriate information or consent element. Rewrite or omit paper-only return/postage instructions unless the user wants a literal reproduction.
42
38
 
43
39
  ## Layout And Grouping
44
40
 
45
- - Treat source layout as meaningful when it communicates that fields belong together, form a repeated row or table, or have labels and inputs that must stay associated. Preserve that relationship with an appropriate form item, field groups, field order, and responsive group layout. Do not reproduce spacing or columns that are only decorative or optimized for paper.
46
- - For adjacent related fields, choose responsive column counts according to their semantic grouping and the space their labels and controls need. Prefer one column in narrow containers and use two to four columns at wider breakpoints when the fields remain clear and usable.
47
- - Form field-group layouts support one to four columns. Never attempt a larger column count. When a source places more than four fields in one row, use the closest clear supported arrangement; for example, six similarly sized fields can use three columns and flow into two rows. Do not ask a follow-up question only because the exact printed column count is unsupported.
41
+ - Treat source layout as meaningful when it communicates that fields belong together, form a repeated row or table, or have labels and inputs that must stay associated. Preserve that relationship with content items, semantic sections, element order and responsive layouts. Do not reproduce spacing or columns that are only decorative or optimized for paper.
42
+ - Prefer automatic layouts with an intuitive maximum column count; columns align across rows. Minimum widths and full-row elements determine actual packing. Use advanced breakpoints only when the source or user requires them. Avoid reproducing decorative paper columns. Sections are full-width vertical blocks, not cells in a layout.
48
43
  - Follow an explicit user layout request when the supported responsive layout can represent it. When it cannot, apply the closest clear supported arrangement and briefly disclose the adaptation after completing the work.
49
44
 
50
45
  ## Conditions And Follow-Ups
51
46
 
52
47
  - Implement implied conditions, branching, conditional follow-up questions, conditional option visibility, and skip logic when the source text clearly implies them. Do not skip conditions just because they require extra work.
53
- - If newly created items depend on other newly created items, place displayConditions/disabledConditions/validations/prefills directly on the created item objects in the same survey_change call when possible.
48
+ - If newly created items depend on other newly created items, place visibility/disabled conditions on their owners, prefills on elements and cross-input validation rules on content items in the same survey_change call when possible.
54
49
  - Load the expressions reference and use the expression tool for complex expression work or existing/applied items.
55
50
 
56
51
  ## Text Shaping
57
52
 
58
53
  - Rephrase only enough to make the digital survey clear and grammatically coherent. Preserve measurement meaning, recall periods, answer scales, and eligibility wording.
59
- - Split source text into the right visible content keys: concise question in `title`; instructions like "multiple answers possible" or recall-period guidance in `subtitle` or `topContent`; explanations after the control in `bottomContent`; non-question prose in info item `content`.
60
- - For consent, put the document's main heading in `title`, a separate brief introduction or reading instruction in `subtitle` when needed, and the substantive document text in `consentBody`. Consent inherits those question fields by default. Use `consentTitle` only for a distinct consent heading, and `subtitleMode=custom` with `consentSubtitle` for a distinct consent introduction (`none` omits it from the consent). Avoid duplicating the main heading in the body, while retaining meaningful section headings and the supplied terms. Do not replace the document with a summary or an instruction to read content that has not been included; honor an explicit request for verbatim reproduction.
54
+ - Split source text into the right visible content keys: concise question in `title`; instructions like "multiple answers possible" or recall-period guidance in `subtitle` or an information element; explanations after the control in `footer` or a following information element; non-question prose in information element `body`.
55
+ - For consent, put the main heading in the item title or nearest semantic section title, a separate introduction in the item's subtitle or section's description when needed, and the full terms in the consent element's body role. An explicit consent label overrides inherited context; `subtitleMode: "custom"` uses its subtitle role and `none` omits it. Avoid repeating the main heading, but preserve meaningful document headings and the full terms. Honor verbatim reproduction when requested.
61
56
  - Use plainText for ordinary unformatted prose. Use richText, not plainText, only when info item content has headings, subheadings, boxed sections, bullet/list structure, examples, emphasized phrases, separators, footnotes, URLs, email links, or mixed inline formatting. Preserve the hierarchy with heading blocks, paragraph blocks, bullet lists, info boxes, or separators as supported.
62
57
  - Preserve meaningful inline source formatting, not only block layout. A URL or email address that is intended as a destination must be a richText `link` node with a canonical `href`; do not rely on automatic link detection. If source text emphasizes or highlights individual words in a question title, subtitle, option, or info text, author that content key as richText with styled inline runs instead of flattening it to plainText. Use emphasis only where it carries source meaning or scanning value.
63
58
  - For source-import surfaces documented as rendering rich text, prefer the compact `richTextBlocks` shorthand; `survey_change` normalizes it to strict richText. Do not infer formatting support merely because a typed field accepts structured content. Load `rich-text-content` for supported surfaces, compact and canonical nodes, and examples. Invalid or unknown nodes are rejected rather than silently omitted.
64
- - Preserve footnote markers and footnote text when they change interpretation, eligibility, instructions, privacy, or coding. If a question/option has `*`, keep the marker in the visible title/option text and place the note in `subtitle`, `topContent`, `bottomContent`, or a following info item close to the referenced question. Do not silently drop source footnotes.
65
- - Do not put respondent-visible option labels, form field labels, dropdown option labels, validation messages, or embedded-form labels only in config. They need translation entries.
59
+ - Preserve footnote markers and footnote text when they change interpretation, eligibility, instructions, privacy, or coding. If a question/option has `*`, keep the marker in the visible title/option text and place the note in `subtitle`, `footer` or a nearby information element close to the referenced question. Do not silently drop source footnotes.
60
+ - Do not put respondent-visible option labels, form field labels, dropdown option labels, validation messages, or follow-up labels only in config. They need translation entries.
66
61
 
67
62
  ## Workflow
68
63
 
69
- - For complex source implementation, load this source-material reference once, then load item-types
70
- with the specific `itemType` needed for the current chunk and assistant-operations for unfamiliar
71
- operation shapes. Do not load the combined item-types reference merely because a source contains
72
- several types. Load rich-text-content before formatted info items and expressions before complex
64
+ - For complex source implementation, load this source-material reference once, then load element-types
65
+ with the specific `elementType` needed for the current chunk and assistant-operations for unfamiliar
66
+ operation shapes. Do not load the combined element-types reference merely because a source contains
67
+ several types. Load rich-text-content before formatted information elements in content items and expressions before complex
73
68
  branching.
74
69
  - Use survey_inspect for the root group and long-survey insertion points. Use full outline paging or children lookup; do not guess append indexes from truncated context.
75
70
  - Before calling survey_change for a source-derived chunk, do a quick fidelity pass against the source: every question title, option label, option parenthetical, blank/input, meaningful field grouping/layout, section heading, footnote marker, and footnote text in that chunk should either be represented digitally or intentionally omitted or adapted as print-only/admin material.