@pie-players/pie-assessment-toolkit 0.3.74 → 0.3.75

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 (228) hide show
  1. package/README.md +349 -313
  2. package/dist/attempt/TestSession.d.ts +1 -20
  3. package/dist/attempt/TestSession.js +8 -99
  4. package/dist/components/ItemScope.custom-element.d.ts +1 -0
  5. package/dist/components/ItemScope.custom-element.js +1 -0
  6. package/dist/components/ItemToolBar.custom-element.js +1 -1
  7. package/dist/components/PieAssessmentToolkit.custom-element.js +14 -14
  8. package/dist/components/SectionToolBar.custom-element.js +1 -1
  9. package/dist/components/chunks/ItemToolBar-7tt7v2xp.js +4 -0
  10. package/dist/components/chunks/{ItemToolBar-gmrryv2v.js → ItemToolBar-97hx60z4.js} +1 -1
  11. package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +2 -0
  12. package/dist/components/chunks/ItemToolBar-jx38w99s.js +2 -0
  13. package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +40 -0
  14. package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +2 -0
  15. package/dist/components/chunks/sre-engine-jd8cc08x.js +1 -0
  16. package/dist/components/item-scope-element.d.ts +2 -0
  17. package/dist/components/item-scope-element.js +2 -0
  18. package/dist/context/assessment-toolkit-context.d.ts +27 -6
  19. package/dist/index.d.ts +22 -47
  20. package/dist/index.js +12 -36
  21. package/dist/policy/core/PolicySource.d.ts +1 -1
  22. package/dist/policy/core/ToolPolicyEngine.d.ts +77 -32
  23. package/dist/policy/core/ToolPolicyEngine.js +136 -46
  24. package/dist/policy/core/compose-decision.d.ts +28 -7
  25. package/dist/policy/core/compose-decision.js +75 -54
  26. package/dist/policy/core/decision-types.d.ts +65 -34
  27. package/dist/policy/core/feature-decision.d.ts +16 -9
  28. package/dist/policy/core/feature-decision.js +14 -8
  29. package/dist/policy/core/pnp-policy-inputs.d.ts +24 -33
  30. package/dist/policy/core/pnp-policy-inputs.js +28 -56
  31. package/dist/policy/core/provenance.d.ts +9 -4
  32. package/dist/policy/core/provenance.js +1 -1
  33. package/dist/policy/engine.d.ts +7 -23
  34. package/dist/policy/engine.js +5 -20
  35. package/dist/policy/sources/PnpPolicySource.d.ts +44 -61
  36. package/dist/policy/sources/PnpPolicySource.js +117 -118
  37. package/dist/runtime/SectionControllerBinding.d.ts +279 -0
  38. package/dist/runtime/SectionControllerBinding.js +450 -0
  39. package/dist/runtime/SectionRuntimeEngine.d.ts +26 -289
  40. package/dist/runtime/SectionRuntimeEngine.js +30 -372
  41. package/dist/runtime/adapter/SectionEngineAdapter.d.ts +19 -80
  42. package/dist/runtime/adapter/SectionEngineAdapter.js +19 -92
  43. package/dist/runtime/adapter/dom-event-bridge.d.ts +15 -30
  44. package/dist/runtime/adapter/dom-event-bridge.js +17 -44
  45. package/dist/runtime/adapter/subscriber-fanout.d.ts +1 -2
  46. package/dist/runtime/adapter/subscriber-fanout.js +1 -2
  47. package/dist/runtime/catalog-context.d.ts +19 -0
  48. package/dist/runtime/catalog-context.js +28 -0
  49. package/dist/runtime/composition-emit-scheduler.d.ts +9 -15
  50. package/dist/runtime/composition-emit-scheduler.js +9 -15
  51. package/dist/runtime/content-language.d.ts +32 -0
  52. package/dist/runtime/content-language.js +46 -0
  53. package/dist/runtime/content-region.d.ts +17 -0
  54. package/dist/runtime/content-region.js +29 -0
  55. package/dist/runtime/content-registration.d.ts +13 -0
  56. package/dist/runtime/content-registration.js +25 -0
  57. package/dist/runtime/core/SectionEngineCore.d.ts +2 -2
  58. package/dist/runtime/core/SectionEngineCore.js +2 -2
  59. package/dist/runtime/core/cohort.d.ts +1 -1
  60. package/dist/runtime/core/cohort.js +1 -1
  61. package/dist/runtime/core/engine-input.d.ts +18 -30
  62. package/dist/runtime/core/engine-input.js +11 -12
  63. package/dist/runtime/core/engine-output.d.ts +16 -40
  64. package/dist/runtime/core/engine-output.js +9 -21
  65. package/dist/runtime/core/engine-readiness.d.ts +5 -37
  66. package/dist/runtime/core/engine-readiness.js +8 -41
  67. package/dist/runtime/core/engine-resolver.d.ts +46 -74
  68. package/dist/runtime/core/engine-resolver.js +18 -43
  69. package/dist/runtime/core/engine-state.d.ts +28 -36
  70. package/dist/runtime/core/engine-state.js +18 -21
  71. package/dist/runtime/core/engine-transition.d.ts +14 -19
  72. package/dist/runtime/core/engine-transition.js +71 -51
  73. package/dist/runtime/engine.d.ts +16 -19
  74. package/dist/runtime/engine.js +12 -19
  75. package/dist/runtime/page-warnings.d.ts +13 -0
  76. package/dist/runtime/page-warnings.js +22 -0
  77. package/dist/runtime/policy-input-forwarding.d.ts +25 -0
  78. package/dist/runtime/policy-input-forwarding.js +25 -0
  79. package/dist/runtime/registration-events.d.ts +11 -0
  80. package/dist/runtime/runtime-event-claim.d.ts +8 -0
  81. package/dist/runtime/runtime-event-claim.js +15 -0
  82. package/dist/runtime/shell-event-bridge.d.ts +45 -0
  83. package/dist/runtime/shell-event-bridge.js +127 -0
  84. package/dist/runtime/shell-registration.d.ts +73 -0
  85. package/dist/runtime/shell-registration.js +95 -0
  86. package/dist/runtime/shell-scope.d.ts +68 -0
  87. package/dist/runtime/shell-scope.js +188 -0
  88. package/dist/runtime/tool-host-contract.d.ts +8 -10
  89. package/dist/runtime/tool-host-contract.js +11 -11
  90. package/dist/runtime/unclaimed-registration-watch.d.ts +7 -0
  91. package/dist/runtime/unclaimed-registration-watch.js +23 -0
  92. package/dist/services/ElementToolStateStore.d.ts +14 -10
  93. package/dist/services/ElementToolStateStore.js +37 -13
  94. package/dist/services/HighlightCoordinator.d.ts +21 -21
  95. package/dist/services/HighlightCoordinator.js +431 -325
  96. package/dist/services/RangeSerializer.d.ts +10 -1
  97. package/dist/services/RangeSerializer.js +87 -14
  98. package/dist/services/TTSService.d.ts +117 -70
  99. package/dist/services/TTSService.js +668 -578
  100. package/dist/services/ToolCoordinator.d.ts +43 -60
  101. package/dist/services/ToolCoordinator.js +164 -206
  102. package/dist/services/ToolRegistry.d.ts +74 -57
  103. package/dist/services/ToolRegistry.js +104 -114
  104. package/dist/services/ToolkitCoordinator.d.ts +183 -189
  105. package/dist/services/ToolkitCoordinator.js +477 -431
  106. package/dist/services/audio-handoff.d.ts +6 -7
  107. package/dist/services/audio-handoff.js +20 -14
  108. package/dist/services/catalog-owner.d.ts +0 -1
  109. package/dist/services/framework-error-bus.d.ts +3 -6
  110. package/dist/services/framework-error-bus.js +3 -6
  111. package/dist/services/framework-error.d.ts +22 -7
  112. package/dist/services/framework-error.js +9 -7
  113. package/dist/services/interfaces.d.ts +158 -129
  114. package/dist/services/section-session-assignment.d.ts +21 -0
  115. package/dist/services/section-session-assignment.js +82 -0
  116. package/dist/services/spoken-audio-cards.d.ts +0 -2
  117. package/dist/services/spoken-audio-cards.js +0 -2
  118. package/dist/services/tool-config-defaults.d.ts +3 -3
  119. package/dist/services/tool-config-defaults.js +3 -3
  120. package/dist/services/tool-config-validation.d.ts +4 -5
  121. package/dist/services/tool-config-validation.js +36 -61
  122. package/dist/services/tool-context.d.ts +0 -8
  123. package/dist/services/tool-context.js +0 -12
  124. package/dist/services/tool-icons.d.ts +4 -3
  125. package/dist/services/tool-icons.js +4 -3
  126. package/dist/services/tool-instance-id.d.ts +0 -1
  127. package/dist/services/tool-instance-id.js +0 -6
  128. package/dist/services/tool-providers/TTSToolProvider.d.ts +18 -19
  129. package/dist/services/tool-providers/TTSToolProvider.js +37 -34
  130. package/dist/services/tool-providers/ToolProviderApi.d.ts +10 -4
  131. package/dist/services/tool-providers/ToolProviderRegistry.d.ts +30 -26
  132. package/dist/services/tool-providers/ToolProviderRegistry.js +119 -93
  133. package/dist/services/tool-request.d.ts +27 -12
  134. package/dist/services/tool-request.js +24 -14
  135. package/dist/services/toolbar-decided-tools.d.ts +15 -0
  136. package/dist/services/toolbar-decided-tools.js +28 -0
  137. package/dist/services/tools-config-normalizer.d.ts +17 -22
  138. package/dist/services/tools-config-normalizer.js +2 -10
  139. package/dist/services/tts/browser-provider.d.ts +38 -2
  140. package/dist/services/tts/browser-provider.js +276 -140
  141. package/dist/services/tts/flat-tree.d.ts +71 -0
  142. package/dist/services/tts/flat-tree.js +269 -0
  143. package/dist/services/tts/generated-speech/assemble-plan.d.ts +3 -1
  144. package/dist/services/tts/generated-speech/assemble-plan.js +3 -1
  145. package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +2 -0
  146. package/dist/services/tts/generated-speech/dom/build-dom-plan.js +1 -1
  147. package/dist/services/tts/generated-speech/math-speech-cache.d.ts +3 -1
  148. package/dist/services/tts/generated-speech/math-speech-cache.js +5 -1
  149. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +12 -4
  150. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +6 -4
  151. package/dist/services/tts/highlight-pipeline/readable-region.js +3 -2
  152. package/dist/services/tts/highlight-pipeline/types.d.ts +5 -0
  153. package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +12 -0
  154. package/dist/services/tts/highlight-pipeline/visible-map-range.js +73 -7
  155. package/dist/services/tts/math-aware-text-processing.d.ts +5 -1
  156. package/dist/services/tts/math-aware-text-processing.js +32 -18
  157. package/dist/services/tts/math-control-names.d.ts +21 -0
  158. package/dist/services/tts/math-control-names.js +142 -0
  159. package/dist/services/tts/math-speech.d.ts +11 -0
  160. package/dist/services/tts/math-speech.js +51 -18
  161. package/dist/services/tts/provider-options.d.ts +41 -0
  162. package/dist/services/tts/provider-options.js +1 -0
  163. package/dist/services/tts/ssml/spoken-text.d.ts +2 -26
  164. package/dist/services/tts/ssml/spoken-text.js +29 -0
  165. package/dist/services/tts/start-failure.d.ts +11 -0
  166. package/dist/services/tts/start-failure.js +19 -0
  167. package/dist/services/tts/text-processing.d.ts +9 -0
  168. package/dist/services/tts/text-processing.js +46 -33
  169. package/dist/services/tts/text-segmentation.d.ts +7 -0
  170. package/dist/services/tts/text-segmentation.js +47 -0
  171. package/dist/services/tts-runtime-config.d.ts +25 -17
  172. package/dist/services/tts-runtime-config.js +16 -95
  173. package/dist/tools/content-capability-resolution.d.ts +7 -9
  174. package/dist/tools/content-capability-resolution.js +8 -45
  175. package/dist/tools/registration.d.ts +58 -0
  176. package/dist/tools/registration.js +54 -0
  177. package/dist/tools/registrations/toolbar-registration-helpers.js +2 -2
  178. package/dist/tools/tool-surface-host.d.ts +6 -10
  179. package/dist/tools/tool-surface-host.js +44 -42
  180. package/dist/tools/tool-tag-map.d.ts +5 -15
  181. package/dist/tools/tool-tag-map.js +6 -20
  182. package/dist/utils/structural-equality.d.ts +11 -0
  183. package/dist/utils/structural-equality.js +47 -0
  184. package/package.json +13 -29
  185. package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +0 -49
  186. package/dist/attempt/adapters/activity-to-test-attempt-session.js +0 -138
  187. package/dist/components/chunks/ItemToolBar-b9dz5jvd.js +0 -40
  188. package/dist/components/chunks/ItemToolBar-h4xap0t0.js +0 -4
  189. package/dist/components/chunks/ItemToolBar-wr2myaah.js +0 -2
  190. package/dist/components/chunks/sre-engine-wf9s43gg.js +0 -1
  191. package/dist/context/runtime-context-consumer.d.ts +0 -13
  192. package/dist/context/runtime-context-consumer.js +0 -18
  193. package/dist/item-loader.d.ts +0 -44
  194. package/dist/item-loader.js +0 -61
  195. package/dist/policy/core/engine-context.d.ts +0 -29
  196. package/dist/policy/core/engine-context.js +0 -27
  197. package/dist/policy/core/policy-source-tag.d.ts +0 -31
  198. package/dist/policy/core/policy-source-tag.js +0 -28
  199. package/dist/policy/internal.d.ts +0 -25
  200. package/dist/policy/internal.js +0 -25
  201. package/dist/runtime/adapter/coordinator-bridge.d.ts +0 -92
  202. package/dist/runtime/adapter/coordinator-bridge.js +0 -126
  203. package/dist/runtime/adapter/framework-error-bridge.d.ts +0 -36
  204. package/dist/runtime/adapter/framework-error-bridge.js +0 -46
  205. package/dist/runtime/adapter/instrumentation-bridge.d.ts +0 -31
  206. package/dist/runtime/adapter/instrumentation-bridge.js +0 -38
  207. package/dist/runtime/core/engine-stage-derivation.d.ts +0 -18
  208. package/dist/runtime/core/engine-stage-derivation.js +0 -29
  209. package/dist/runtime/engine-context.d.ts +0 -39
  210. package/dist/runtime/engine-context.js +0 -31
  211. package/dist/runtime/internal.d.ts +0 -43
  212. package/dist/runtime/internal.js +0 -45
  213. package/dist/runtime/section-runtime-engine-host-context.d.ts +0 -74
  214. package/dist/runtime/section-runtime-engine-host-context.js +0 -57
  215. package/dist/runtime/stage-emit-gate.d.ts +0 -92
  216. package/dist/runtime/stage-emit-gate.js +0 -82
  217. package/dist/services/I18nService.d.ts +0 -47
  218. package/dist/services/I18nService.js +0 -84
  219. package/dist/services/ThemeProvider.d.ts +0 -95
  220. package/dist/services/ThemeProvider.js +0 -334
  221. package/dist/services/defaultPersonalNeedsProfile.d.ts +0 -21
  222. package/dist/services/defaultPersonalNeedsProfile.js +0 -26
  223. package/dist/services/pnp-standard-features.d.ts +0 -238
  224. package/dist/services/pnp-standard-features.js +0 -338
  225. package/dist/tools/client.d.ts +0 -10
  226. package/dist/tools/client.js +0 -10
  227. package/dist/tools/internal.d.ts +0 -44
  228. package/dist/tools/internal.js +0 -39
@@ -2,28 +2,19 @@
2
2
  * PNP/profile policy input detection. See
3
3
  * `docs/tools-and-accomodations/architecture.md`.
4
4
  *
5
- * Pure helpers that decide whether the inputs the engine has been given
6
- * actually carry PNP/profile policy material. Used by:
7
- *
8
- * - {@link ToolPolicyEngine}'s constructor as the auto-default for
9
- * `pnpEnforcement` when the host did not pass an explicit `"on"` /
10
- * `"off"`.
11
- * - {@link ToolkitCoordinator.resolveEffectivePnpEnforcement} as the
12
- * auto-mode rule. PR 2 used a coarse "any non-null assessment → on"
13
- * placeholder; PR 4 narrows it to "assessment OR currentItemRef
14
- * carries profile policy material."
5
+ * Pure helpers that decide whether policy inputs carry PNP/profile policy
6
+ * material, which is what auto-mode `pnpEnforcement` turns on for. The engine
7
+ * resolves auto-mode per decision: the bound assessment for every decision, and
8
+ * for a decision scoped to an item, that item's settings as well.
15
9
  *
16
10
  * The rule is intentionally narrow. Hosts that bind a bare assessment
17
11
  * record (only `id` / `name`, no PNP and no settings) do not engage
18
12
  * PNP/profile gates. The flip happens the moment the assessment carries any of:
19
13
  *
20
- * - `personalNeedsProfile` (any `supports`, `prohibitedSupports`, or
21
- * `activateAtInit`),
22
- * - `settings.districtPolicy` (any `blockedTools`, `requiredTools`,
23
- * or `policies`),
24
- * - `settings.testAdministration` (any populated key — `mode`,
25
- * `toolOverrides`, etc.),
26
- * - or the bound `currentItemRef.settings` carries
14
+ * - `personalNeedsProfile` (any `supports` or `prohibitedSupports`),
15
+ * - `settings.districtPolicy` (any `blockedTools` or `requiredTools`),
16
+ * - `settings.testAdministration` (any `toolOverrides` entry),
17
+ * - or, for an item-scoped decision, the item's settings carry
27
18
  * `requiredTools` / `restrictedTools` / `toolParameters`.
28
19
  *
29
20
  * Hosts opt out of the auto-on behavior by passing
@@ -34,9 +25,8 @@
34
25
  * Return `true` when the assessment carries any PNP/profile policy
35
26
  * material that the engine's `PnpPolicySource` would consume.
36
27
  *
37
- * The check is structural — the presence of a non-empty PNP, district
38
- * policy, or test administration block is enough; the content does not
39
- * have to validate against any specific rule.
28
+ * The check is structural — a non-empty field the source reads is enough;
29
+ * the content does not have to validate against any specific rule.
40
30
  */
41
31
  export function assessmentHasPnpPolicyInputs(assessment) {
42
32
  if (!assessment)
@@ -49,9 +39,6 @@ export function assessmentHasPnpPolicyInputs(assessment) {
49
39
  pnp.prohibitedSupports.length > 0) {
50
40
  return true;
51
41
  }
52
- if (Array.isArray(pnp.activateAtInit) && pnp.activateAtInit.length > 0) {
53
- return true;
54
- }
55
42
  }
56
43
  const settings = assessment.settings;
57
44
  if (settings) {
@@ -65,42 +52,26 @@ export function assessmentHasPnpPolicyInputs(assessment) {
65
52
  district.requiredTools.length > 0) {
66
53
  return true;
67
54
  }
68
- if (district.policies &&
69
- typeof district.policies === "object" &&
70
- Object.keys(district.policies).length > 0) {
71
- return true;
72
- }
73
55
  }
74
- const admin = settings.testAdministration;
75
- if (admin && typeof admin === "object") {
76
- for (const key of Object.keys(admin)) {
77
- const value = admin[key];
78
- if (value === undefined || value === null)
79
- continue;
80
- if (Array.isArray(value) && value.length === 0)
81
- continue;
82
- if (typeof value === "object" &&
83
- !Array.isArray(value) &&
84
- Object.keys(value).length === 0) {
85
- continue;
86
- }
87
- return true;
88
- }
56
+ const overrides = settings.testAdministration?.toolOverrides;
57
+ if (overrides &&
58
+ typeof overrides === "object" &&
59
+ Object.keys(overrides).length > 0) {
60
+ return true;
89
61
  }
90
62
  }
91
63
  return false;
92
64
  }
93
65
  /**
94
- * Return `true` when the bound item reference carries item-level profile policy
66
+ * Return `true` when an item's settings carry item-level profile policy
95
67
  * material (`requiredTools`, `restrictedTools`, or `toolParameters`).
96
68
  *
97
- * Used in addition to {@link assessmentHasPnpPolicyInputs} so a host that
98
- * navigates to an item with profile-relevant settings — without a parent
99
- * assessment carrying its own PNP/district/test-admin block — still
100
- * gets PNP/profile gates engaged for that item.
69
+ * Used in addition to {@link assessmentHasPnpPolicyInputs} for a decision scoped
70
+ * to the item, so an item with profile-relevant settings engages PNP/profile
71
+ * gates on its own toolbar without a parent assessment carrying a
72
+ * PNP/district/test-admin block.
101
73
  */
102
- export function itemRefHasPnpPolicyInputs(itemRef) {
103
- const settings = itemRef?.settings;
74
+ export function itemSettingsHavePnpPolicyInputs(settings) {
104
75
  if (!settings)
105
76
  return false;
106
77
  if (Array.isArray(settings.requiredTools) &&
@@ -119,18 +90,19 @@ export function itemRefHasPnpPolicyInputs(itemRef) {
119
90
  return false;
120
91
  }
121
92
  /**
122
- * Resolve the default `pnpEnforcement` mode given the bound inputs.
93
+ * Resolve the auto-mode `pnpEnforcement` for one decision.
123
94
  *
124
- * Returns `"on"` when {@link assessmentHasPnpPolicyInputs} or
125
- * {@link itemRefHasPnpPolicyInputs} reports any profile policy material; otherwise
126
- * `"off"`. Hosts override the default by passing an explicit
127
- * `pnpEnforcement` value (engine input) or by calling
95
+ * Returns `"on"` when {@link assessmentHasPnpPolicyInputs} reports profile
96
+ * policy material, or when `itemSettings` (the settings of the item a decision
97
+ * is scoped to) do per {@link itemSettingsHavePnpPolicyInputs}; otherwise
98
+ * `"off"`. Hosts override the default by passing an explicit `pnpEnforcement`
99
+ * value (engine input) or by calling
128
100
  * `ToolkitCoordinator.setPnpEnforcement("on" | "off")`.
129
101
  */
130
102
  export function resolveDefaultPnpEnforcement(args) {
131
103
  if (assessmentHasPnpPolicyInputs(args.assessment))
132
104
  return "on";
133
- if (itemRefHasPnpPolicyInputs(args.currentItemRef))
105
+ if (itemSettingsHavePnpPolicyInputs(args.itemSettings))
134
106
  return "on";
135
107
  return "off";
136
108
  }
@@ -7,17 +7,22 @@
7
7
  * Tracks decisions from every Pass-1 contributor: host placement, host policy,
8
8
  * provider veto, PNP/profile gates, and custom policy sources.
9
9
  */
10
+ /** The PNP/profile precedence rules, highest first. */
11
+ export type PnpPolicySourceRule = "district-block" | "test-admin-override" | "item-restriction" | "pnp-prohibited" | "item-requirement" | "district-requirement" | "pnp-support";
10
12
  /**
11
- * Rule vocabulary for tool policy decisions.
13
+ * Rule vocabulary for tool policy decisions. A decision's `rule` is the one
14
+ * attribution channel: it names the step that enabled, blocked or advised on a
15
+ * tool.
12
16
  */
13
- export type ToolPolicyDecisionRule = "district-block" | "test-admin-override" | "item-restriction" | "item-requirement" | "district-requirement" | "pnp-support" | "pnp-prohibited" | "placement-membership" | "provider-disabled" | "host-allowlist" | "host-blocked" | "required-tool-blocked" | "custom-source" | "system-default";
17
+ export type ToolPolicyDecisionRule = PnpPolicySourceRule | "placement-membership" | "provider-disabled" | "host-allowlist" | "host-blocked" | "required-tool-blocked" | "custom-source" | "system-default";
14
18
  export type ToolPolicySourceType = "organization" | "assessment" | "section" | "item" | "student" | "system" | "host" | "custom";
15
19
  export interface ToolPolicyResolutionDecision {
16
20
  /** Monotonic step index across the entire decision log. */
17
21
  step: number;
18
22
  /**
19
23
  * Precedence level. PNP/profile rules use `1`–`6`; non-profile rules use `0`
20
- * for host-side gates or `7+` for custom sources that run after PNP/profile policy.
24
+ * for host-side gates, and a custom source, which runs after PNP/profile
25
+ * policy, uses its own or `100 + i` for the `i`th registered source.
21
26
  */
22
27
  precedence: number;
23
28
  rule: ToolPolicyDecisionRule;
@@ -120,7 +125,7 @@ export declare class ToolPolicyProvenanceBuilder {
120
125
  * walks every feature trail and rewrites `finalState` from the
121
126
  * final candidate set so callers can rely on
122
127
  * `provenance.features.get(toolId)?.finalState` as the canonical
123
- * "is this tool visible right now?" answer (M8 design § 4 + § 12).
128
+ * "is this tool visible right now?" answer.
124
129
  *
125
130
  * Semantics applied per feature:
126
131
  * - In `survivingIds` → "enabled"
@@ -124,7 +124,7 @@ export class ToolPolicyProvenanceBuilder {
124
124
  * walks every feature trail and rewrites `finalState` from the
125
125
  * final candidate set so callers can rely on
126
126
  * `provenance.features.get(toolId)?.finalState` as the canonical
127
- * "is this tool visible right now?" answer (M8 design § 4 + § 12).
127
+ * "is this tool visible right now?" answer.
128
128
  *
129
129
  * Semantics applied per feature:
130
130
  * - In `survivingIds` → "enabled"
@@ -1,28 +1,12 @@
1
1
  /**
2
- * Tool policy engine — facade entry point (M8 PR 1).
3
- *
4
- * Narrow, stable public surface for hosts that want to instantiate or
5
- * consume a `ToolPolicyEngine`. Re-exports the engine class, its
6
- * decision request/response types, the Svelte context key, and the
7
- * minimal `PolicySource` extension contract.
8
- *
9
- * **Pairing.** This module is the stable counterpart to
10
- * `./policy/internal`, which exposes the wider, evolving surface
11
- * (composition pipeline, provenance builder, PNP policy source). Consumers
12
- * that only need to drive an engine and read its decisions should
13
- * import from here. Consumers that need to reach past the facade
14
- * (e.g. test the composition pipeline directly, build a custom PNP policy
15
- * source variant, instrument provenance generation) should import
16
- * from `./policy/internal` and accept the documented stability
17
- * disclaimer there.
18
- *
19
- * Mirrors the M7 `runtime/engine` / `runtime/internal` split — see
20
- * the same rationale in `src/runtime/engine.ts`.
2
+ * Tool policy engine — the stable entry for a host that instantiates or
3
+ * consumes a `ToolPolicyEngine`: the engine class, its decision request and
4
+ * response types, and the `PolicySource` extension contract. The composition
5
+ * pipeline, the PNP policy source and the provenance builder stay behind the
6
+ * engine, with no entry of their own.
21
7
  */
22
8
  export { ToolPolicyEngine, type PnpEnforcementMode, type ResolvedEngineInputs, type ToolPolicyChangeEvent, type ToolPolicyChangeListener, type ToolPolicyEngineArgs, type ToolPolicyEngineInputs, } from "./core/ToolPolicyEngine.js";
23
- export { TOOL_POLICY_ENGINE_KEY, type ToolPolicyEngineContext, } from "./core/engine-context.js";
24
9
  export { isHostDeniedFeature, type FeaturePolicyDecision, type FeaturePolicyRule, } from "./core/feature-decision.js";
25
- export type { RequiredToolBlockedDetails, ToolPolicyDecision, ToolPolicyDecisionRequest, ToolPolicyDiagnostic, ToolPolicyDiagnosticCode, ToolPolicyEntry, ToolPolicyHostGate, ToolScope, } from "./core/decision-types.js";
10
+ export type { ItemSettingNotAppliedDetails, OverrideBlockedDetails, PlacementMissingDetails, RequiredToolBlockedDetails, ToolPolicyDecision, ToolPolicyDecisionRequest, ToolPolicyDiagnostic, ToolPolicyDiagnosticCode, ToolPolicyEntry, ToolPolicyHostGate, ToolScope, UnknownSupportIdDetails, } from "./core/decision-types.js";
26
11
  export type { PolicySource, PolicySourceDecisionContext, PolicySourceProvenanceEntry, PolicySourceResult, } from "./core/PolicySource.js";
27
- export type { PolicySourceTag, PnpPolicySourceRule, PnpPolicySourceTag, CustomPolicySourceTag, } from "./core/policy-source-tag.js";
28
- export type { ToolPolicyDecisionRule, ToolPolicyFeatureTrail, ToolPolicyProvenance, ToolPolicyResolutionDecision, ToolPolicySourceType, } from "./core/provenance.js";
12
+ export type { PnpPolicySourceRule, ToolPolicyDecisionRule, ToolPolicyFeatureTrail, ToolPolicyProvenance, ToolPolicyResolutionDecision, ToolPolicySourceType, } from "./core/provenance.js";
@@ -1,24 +1,9 @@
1
1
  /**
2
- * Tool policy engine — facade entry point (M8 PR 1).
3
- *
4
- * Narrow, stable public surface for hosts that want to instantiate or
5
- * consume a `ToolPolicyEngine`. Re-exports the engine class, its
6
- * decision request/response types, the Svelte context key, and the
7
- * minimal `PolicySource` extension contract.
8
- *
9
- * **Pairing.** This module is the stable counterpart to
10
- * `./policy/internal`, which exposes the wider, evolving surface
11
- * (composition pipeline, provenance builder, PNP policy source). Consumers
12
- * that only need to drive an engine and read its decisions should
13
- * import from here. Consumers that need to reach past the facade
14
- * (e.g. test the composition pipeline directly, build a custom PNP policy
15
- * source variant, instrument provenance generation) should import
16
- * from `./policy/internal` and accept the documented stability
17
- * disclaimer there.
18
- *
19
- * Mirrors the M7 `runtime/engine` / `runtime/internal` split — see
20
- * the same rationale in `src/runtime/engine.ts`.
2
+ * Tool policy engine — the stable entry for a host that instantiates or
3
+ * consumes a `ToolPolicyEngine`: the engine class, its decision request and
4
+ * response types, and the `PolicySource` extension contract. The composition
5
+ * pipeline, the PNP policy source and the provenance builder stay behind the
6
+ * engine, with no entry of their own.
21
7
  */
22
8
  export { ToolPolicyEngine, } from "./core/ToolPolicyEngine.js";
23
- export { TOOL_POLICY_ENGINE_KEY, } from "./core/engine-context.js";
24
9
  export { isHostDeniedFeature, } from "./core/feature-decision.js";
@@ -1,6 +1,5 @@
1
1
  /**
2
- * PNP Policy Source for the M8 engine
3
- * (see
2
+ * PNP Policy Source: step 5 of `composeDecision` (see
4
3
  * `docs/tools-and-accomodations/architecture.md`).
5
4
  *
6
5
  * This source applies the PNP/profile precedence rules as a `(candidates, pnpPolicyInputs) →
@@ -8,26 +7,37 @@
8
7
  * engine can call once per `decide(...)` request, with all results
9
8
  * routed through the unified `ToolPolicyProvenanceBuilder`.
10
9
  */
11
- import type { AssessmentEntity, AssessmentItemRef } from "@pie-players/pie-players-shared/types";
10
+ import type { AssessmentEntity, ItemSettings } from "@pie-players/pie-players-shared/types";
12
11
  import type { ToolRegistry } from "../../services/ToolRegistry.js";
13
- import type { ToolPolicyResolutionDecision, ToolPolicySourceType } from "../core/provenance.js";
14
- import type { PnpPolicySourceRule } from "../core/policy-source-tag.js";
12
+ import type { PnpPolicySourceRule, ToolPolicyResolutionDecision, ToolPolicySourceType } from "../core/provenance.js";
13
+ import type { OverrideBlockedDetails } from "../core/decision-types.js";
15
14
  /** Per-tool flags PNP/profile policy may attach to a surviving entry. */
16
15
  export interface PnpPolicyToolFlags {
17
16
  /** PNP/profile policy mandates this tool (item or district `requiredTools`). */
18
17
  required: boolean;
19
- /** Student PNP marks this tool as a support (host UI cannot toggle off). */
18
+ /**
19
+ * The student's profile supports this tool, or a test-administration
20
+ * override grants it (host UI cannot toggle off).
21
+ */
20
22
  alwaysAvailable: boolean;
21
23
  /** Tool-specific settings derived from item / assessment settings. */
22
24
  settings?: unknown;
23
25
  /** Which PNP/profile rule contributed the surviving verdict. */
24
26
  rule: PnpPolicySourceRule;
25
- /** Source attribution for `ToolPolicyEntry.sources`. */
26
- sourceType: ToolPolicySourceType;
27
+ }
28
+ /** An item a decision is scoped to, by its canonical id, with its settings. */
29
+ export interface PnpPolicyItem {
30
+ id: string;
31
+ settings: ItemSettings;
27
32
  }
28
33
  export interface PnpPolicyApplyArgs {
29
34
  assessment?: AssessmentEntity | null;
30
- currentItemRef?: AssessmentItemRef;
35
+ /**
36
+ * The item the decision is scoped to. Only a decision for the item's own
37
+ * toolbar or content carries one: an item's settings do not reach a section-
38
+ * or assessment-level decision.
39
+ */
40
+ item?: PnpPolicyItem;
31
41
  }
32
42
  /**
33
43
  * Provenance event the engine should append to its builder. Pre-baked
@@ -35,8 +45,8 @@ export interface PnpPolicyApplyArgs {
35
45
  * keeps a uniform `addDecision(...)` shape.
36
46
  */
37
47
  export interface PnpPolicyDecisionEvent {
38
- precedence: 1 | 2 | 3 | 4 | 5 | 6;
39
- rule: "district-block" | "test-admin-override" | "item-restriction" | "item-requirement" | "district-requirement" | "pnp-support" | "pnp-prohibited";
48
+ precedence: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
49
+ rule: PnpPolicySourceRule;
40
50
  featureId: string;
41
51
  action: ToolPolicyResolutionDecision["action"];
42
52
  sourceType: ToolPolicySourceType;
@@ -66,13 +76,20 @@ export interface PnpPolicyResult {
66
76
  */
67
77
  decisions: PnpPolicyDecisionEvent[];
68
78
  /**
69
- * Support ids named by a profile, district policy or item that no
70
- * registration claims. Nothing resolves them, so they are silently inert —
71
- * the engine turns each into a `tool-policy.unknownSupportId` diagnostic so a
72
- * host sending its own label instead of an AfA/QTI feature id learns of it
73
- * rather than seeing a tool quietly fail to appear.
79
+ * Ids named by a profile, district policy, test administration or item that
80
+ * no tool is registered under, each with the rules whose lists name it, in
81
+ * precedence order. Nothing resolves them; the engine turns each into a
82
+ * `tool-policy.unknownSupportId` diagnostic. Empty when the registry is: an
83
+ * empty registry has nothing to check an id against, and
84
+ * `tool-config-validation` already reports it once.
85
+ */
86
+ unmappedSupportIds: Map<string, PnpPolicySourceRule[]>;
87
+ /**
88
+ * Ids a `true` test-administration override names that an item restriction
89
+ * or a PNP prohibition withdrew instead, each with the rule that did. The
90
+ * engine turns each into a `tool-policy.overrideBlocked` diagnostic.
74
91
  */
75
- unmappedSupportIds: Set<string>;
92
+ blockedOverrides: Map<string, OverrideBlockedDetails["rule"]>;
76
93
  /** Configuration sources the engine should attach to its provenance. */
77
94
  sources: {
78
95
  assessment?: {
@@ -98,20 +115,18 @@ export declare class PnpPolicySource {
98
115
  constructor(toolRegistry: ToolRegistry);
99
116
  apply(args: PnpPolicyApplyArgs): PnpPolicyResult;
100
117
  /**
101
- * Evaluate exactly one PNP support id through the same six-level
118
+ * Evaluate exactly one PNP support id through the same eight-level
102
119
  * precedence `apply(...)` uses.
103
120
  *
104
121
  * This exists for **policy-addressable capabilities that are not toolbar
105
122
  * tools** — a signed alternate rendered as its own region, for example.
106
123
  * `apply(...)` only evaluates support ids that appear somewhere in the
107
- * bound policy inputs, and it keys its result maps by *mapped tool id*, so
108
- * a caller asking about one feature would have to re-derive that mapping
109
- * and could collide with another support id that maps to the same tool.
110
- * Evaluating one id in isolation avoids both problems: the returned result
111
- * carries exactly one decision, and `decisions[0].action` is the verdict.
124
+ * bound policy inputs. Evaluating one id in isolation answers for any
125
+ * feature: the returned result carries exactly one decision, and
126
+ * `decisions[0].action` is the verdict.
112
127
  *
113
128
  * Reusing `resolveSupport(...)` rather than re-walking the precedence rules
114
- * is the point — a second copy of the six levels would drift.
129
+ * is the point — a second copy of the eight levels would drift.
115
130
  */
116
131
  resolveFeature(featureId: string, args: PnpPolicyApplyArgs): PnpPolicyResult;
117
132
  /**
@@ -121,43 +136,11 @@ export declare class PnpPolicySource {
121
136
  private prepare;
122
137
  private resolveSupport;
123
138
  /**
124
- * Map a QTI / PNP support id (e.g. `"calculator-basic"`) to the
125
- * registered tool id that owns it.
126
- *
127
- * Resolution rules:
128
- *
129
- * 1. **Multiple tools register the same support id:** the
130
- * *first-registered* tool wins. `ToolRegistry.getToolsByPNPSupport`
131
- * returns a `Set<string>` whose iteration order matches the
132
- * `register(...)` insertion order, so the result is
133
- * deterministic across runs but order-sensitive at registration
134
- * time. This is an unusual configuration — the typical case is
135
- * one tool per support id — but it is reachable when an
136
- * integrator overrides a default tool with a replacement that
137
- * claims the same `pnpSupportIds`. In that case the integrator
138
- * should `unregister(...)` the default before registering the
139
- * replacement.
140
- *
141
- * 2. **No tool registers the support id:** the support id is
142
- * returned verbatim as the `featureId` for provenance trails
143
- * and `ToolPolicyEntry.toolId`. This lets hosts use raw QTI
144
- * strings for tools the registry does not (yet) carry without
145
- * losing them in policy evaluation.
146
- *
147
- * `tests/policy/PnpPolicySource.test.ts` locks this mapping behavior.
148
- */
149
- private mapSupportToToolId;
150
- /**
151
- * Resolve tool-specific settings, item-level taking precedence over
152
- * assessment-level.
153
- *
154
- * Uses `??` (nullish-coalescing). Tool config values are typed `unknown` and may legitimately
155
- * be `false` / `0` / `""` (e.g. a tool whose canonical "off" config
156
- * is the literal `false`). `||` would treat those as missing and
157
- * silently fall through to the assessment-level config, masking the
158
- * authored item-level intent. `??` only falls through on
159
- * `null`/`undefined`, which matches the semantic of "value not
160
- * provided."
139
+ * The named ids no tool is registered under, with the rules naming each in
140
+ * precedence order. A support id is the id of the tool it grants, so an id
141
+ * missing from the registry matches nothing placed.
161
142
  */
143
+ private unmappedIds;
144
+ /** Tool parameters: the item's entry, else the assessment's. */
162
145
  private resolveToolSettings;
163
146
  }