@pie-players/pie-assessment-toolkit 0.3.30 → 0.3.32
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.
- package/README.md +289 -5
- package/dist/components/ItemToolBar.custom-element.js +165 -92
- package/dist/components/PieAssessmentToolkit.custom-element.js +604 -107
- package/dist/components/SectionToolBar.custom-element.js +0 -36
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/policy/core/PolicySource.d.ts +64 -0
- package/dist/policy/core/PolicySource.d.ts.map +1 -0
- package/dist/policy/core/PolicySource.js +17 -0
- package/dist/policy/core/PolicySource.js.map +1 -0
- package/dist/policy/core/ToolPolicyEngine.d.ts +123 -0
- package/dist/policy/core/ToolPolicyEngine.d.ts.map +1 -0
- package/dist/policy/core/ToolPolicyEngine.js +217 -0
- package/dist/policy/core/ToolPolicyEngine.js.map +1 -0
- package/dist/policy/core/compose-decision.d.ts +37 -0
- package/dist/policy/core/compose-decision.d.ts.map +1 -0
- package/dist/policy/core/compose-decision.js +332 -0
- package/dist/policy/core/compose-decision.js.map +1 -0
- package/dist/policy/core/decision-types.d.ts +142 -0
- package/dist/policy/core/decision-types.d.ts.map +1 -0
- package/dist/policy/core/decision-types.js +13 -0
- package/dist/policy/core/decision-types.js.map +1 -0
- package/dist/policy/core/engine-context.d.ts +30 -0
- package/dist/policy/core/engine-context.d.ts.map +1 -0
- package/dist/policy/core/engine-context.js +28 -0
- package/dist/policy/core/engine-context.js.map +1 -0
- package/dist/policy/core/policy-source-tag.d.ts +32 -0
- package/dist/policy/core/policy-source-tag.d.ts.map +1 -0
- package/dist/policy/core/policy-source-tag.js +29 -0
- package/dist/policy/core/policy-source-tag.js.map +1 -0
- package/dist/policy/core/provenance.d.ts +163 -0
- package/dist/policy/core/provenance.d.ts.map +1 -0
- package/dist/policy/core/provenance.js +232 -0
- package/dist/policy/core/provenance.js.map +1 -0
- package/dist/policy/core/qti-inputs.d.ts +67 -0
- package/dist/policy/core/qti-inputs.d.ts.map +1 -0
- package/dist/policy/core/qti-inputs.js +139 -0
- package/dist/policy/core/qti-inputs.js.map +1 -0
- package/dist/policy/engine.d.ts +28 -0
- package/dist/policy/engine.d.ts.map +1 -0
- package/dist/policy/engine.js +24 -0
- package/dist/policy/engine.js.map +1 -0
- package/dist/policy/internal.d.ts +26 -0
- package/dist/policy/internal.d.ts.map +1 -0
- package/dist/policy/internal.js +26 -0
- package/dist/policy/internal.js.map +1 -0
- package/dist/policy/sources/QtiPolicySource.d.ts +146 -0
- package/dist/policy/sources/QtiPolicySource.d.ts.map +1 -0
- package/dist/policy/sources/QtiPolicySource.js +270 -0
- package/dist/policy/sources/QtiPolicySource.js.map +1 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts +145 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts.map +1 -1
- package/dist/runtime/SectionRuntimeEngine.js +164 -3
- package/dist/runtime/SectionRuntimeEngine.js.map +1 -1
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts +144 -0
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts.map +1 -0
- package/dist/runtime/adapter/SectionEngineAdapter.js +183 -0
- package/dist/runtime/adapter/SectionEngineAdapter.js.map +1 -0
- package/dist/runtime/adapter/coordinator-bridge.d.ts +93 -0
- package/dist/runtime/adapter/coordinator-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/coordinator-bridge.js +127 -0
- package/dist/runtime/adapter/coordinator-bridge.js.map +1 -0
- package/dist/runtime/adapter/dom-event-bridge.d.ts +63 -0
- package/dist/runtime/adapter/dom-event-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/dom-event-bridge.js +95 -0
- package/dist/runtime/adapter/dom-event-bridge.js.map +1 -0
- package/dist/runtime/adapter/framework-error-bridge.d.ts +37 -0
- package/dist/runtime/adapter/framework-error-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/framework-error-bridge.js +47 -0
- package/dist/runtime/adapter/framework-error-bridge.js.map +1 -0
- package/dist/runtime/adapter/instrumentation-bridge.d.ts +32 -0
- package/dist/runtime/adapter/instrumentation-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/instrumentation-bridge.js +39 -0
- package/dist/runtime/adapter/instrumentation-bridge.js.map +1 -0
- package/dist/runtime/adapter/subscriber-fanout.d.ts +35 -0
- package/dist/runtime/adapter/subscriber-fanout.d.ts.map +1 -0
- package/dist/runtime/adapter/subscriber-fanout.js +60 -0
- package/dist/runtime/adapter/subscriber-fanout.js.map +1 -0
- package/dist/runtime/core/SectionEngineCore.d.ts +52 -0
- package/dist/runtime/core/SectionEngineCore.d.ts.map +1 -0
- package/dist/runtime/core/SectionEngineCore.js +81 -0
- package/dist/runtime/core/SectionEngineCore.js.map +1 -0
- package/dist/runtime/core/cohort.d.ts +40 -0
- package/dist/runtime/core/cohort.d.ts.map +1 -0
- package/dist/runtime/core/cohort.js +49 -0
- package/dist/runtime/core/cohort.js.map +1 -0
- package/dist/runtime/core/engine-input.d.ts +114 -0
- package/dist/runtime/core/engine-input.d.ts.map +1 -0
- package/dist/runtime/core/engine-input.js +19 -0
- package/dist/runtime/core/engine-input.js.map +1 -0
- package/dist/runtime/core/engine-output.d.ts +62 -0
- package/dist/runtime/core/engine-output.d.ts.map +1 -0
- package/dist/runtime/core/engine-output.js +27 -0
- package/dist/runtime/core/engine-output.js.map +1 -0
- package/dist/runtime/core/engine-readiness.d.ts +49 -0
- package/dist/runtime/core/engine-readiness.d.ts.map +1 -0
- package/dist/runtime/core/engine-readiness.js +47 -0
- package/dist/runtime/core/engine-readiness.js.map +1 -0
- package/dist/runtime/core/engine-resolver.d.ts +172 -0
- package/dist/runtime/core/engine-resolver.d.ts.map +1 -0
- package/dist/runtime/core/engine-resolver.js +170 -0
- package/dist/runtime/core/engine-resolver.js.map +1 -0
- package/dist/runtime/core/engine-stage-derivation.d.ts +19 -0
- package/dist/runtime/core/engine-stage-derivation.d.ts.map +1 -0
- package/dist/runtime/core/engine-stage-derivation.js +30 -0
- package/dist/runtime/core/engine-stage-derivation.js.map +1 -0
- package/dist/runtime/core/engine-state.d.ts +83 -0
- package/dist/runtime/core/engine-state.d.ts.map +1 -0
- package/dist/runtime/core/engine-state.js +49 -0
- package/dist/runtime/core/engine-state.js.map +1 -0
- package/dist/runtime/core/engine-transition.d.ts +49 -0
- package/dist/runtime/core/engine-transition.d.ts.map +1 -0
- package/dist/runtime/core/engine-transition.js +261 -0
- package/dist/runtime/core/engine-transition.js.map +1 -0
- package/dist/runtime/engine-context.d.ts +40 -0
- package/dist/runtime/engine-context.d.ts.map +1 -0
- package/dist/runtime/engine-context.js +32 -0
- package/dist/runtime/engine-context.js.map +1 -0
- package/dist/runtime/engine.d.ts +24 -0
- package/dist/runtime/engine.d.ts.map +1 -0
- package/dist/runtime/engine.js +24 -0
- package/dist/runtime/engine.js.map +1 -0
- package/dist/runtime/internal.d.ts +44 -0
- package/dist/runtime/internal.d.ts.map +1 -0
- package/dist/runtime/internal.js +46 -0
- package/dist/runtime/internal.js.map +1 -0
- package/dist/runtime/runtime-id.d.ts +8 -0
- package/dist/runtime/runtime-id.d.ts.map +1 -0
- package/dist/runtime/runtime-id.js +10 -0
- package/dist/runtime/runtime-id.js.map +1 -0
- package/dist/runtime/section-runtime-engine-host-context.d.ts +74 -0
- package/dist/runtime/section-runtime-engine-host-context.d.ts.map +1 -0
- package/dist/runtime/section-runtime-engine-host-context.js +96 -0
- package/dist/runtime/section-runtime-engine-host-context.js.map +1 -0
- package/dist/runtime/stage-emit-gate.d.ts +93 -0
- package/dist/runtime/stage-emit-gate.d.ts.map +1 -0
- package/dist/runtime/stage-emit-gate.js +83 -0
- package/dist/runtime/stage-emit-gate.js.map +1 -0
- package/dist/services/ToolkitCoordinator.d.ts +280 -7
- package/dist/services/ToolkitCoordinator.d.ts.map +1 -1
- package/dist/services/ToolkitCoordinator.js +412 -32
- package/dist/services/ToolkitCoordinator.js.map +1 -1
- package/dist/services/framework-error-bus.d.ts +73 -0
- package/dist/services/framework-error-bus.d.ts.map +1 -0
- package/dist/services/framework-error-bus.js +68 -0
- package/dist/services/framework-error-bus.js.map +1 -0
- package/dist/services/framework-error.d.ts +36 -1
- package/dist/services/framework-error.d.ts.map +1 -1
- package/dist/services/framework-error.js +37 -0
- package/dist/services/framework-error.js.map +1 -1
- package/dist/services/interfaces.d.ts +78 -0
- package/dist/services/interfaces.d.ts.map +1 -1
- package/dist/services/interfaces.js.map +1 -1
- package/dist/services/section-controller-types.d.ts +20 -0
- package/dist/services/section-controller-types.d.ts.map +1 -1
- package/dist/services/tools-config-normalizer.d.ts +23 -0
- package/dist/services/tools-config-normalizer.d.ts.map +1 -1
- package/dist/services/tools-config-normalizer.js +13 -1
- package/dist/services/tools-config-normalizer.js.map +1 -1
- package/dist/tools/client.d.ts +0 -1
- package/dist/tools/client.d.ts.map +1 -1
- package/dist/tools/client.js +0 -2
- package/dist/tools/client.js.map +1 -1
- package/dist/tools/types.d.ts +0 -26
- package/dist/tools/types.d.ts.map +1 -1
- package/package.json +23 -7
- package/dist/runtime/runtime-event-guards.d.ts +0 -2
- package/dist/runtime/runtime-event-guards.d.ts.map +0 -1
- package/dist/runtime/runtime-event-guards.js +0 -4
- package/dist/runtime/runtime-event-guards.js.map +0 -1
- package/dist/tools/tool-coordinator.d.ts +0 -72
- package/dist/tools/tool-coordinator.d.ts.map +0 -1
- package/dist/tools/tool-coordinator.js +0 -194
- package/dist/tools/tool-coordinator.js.map +0 -1
- package/dist/types/events.d.ts +0 -157
- package/dist/types/events.d.ts.map +0 -1
- package/dist/types/events.js +0 -11
- package/dist/types/events.js.map +0 -1
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Policy Provenance — generalization of `PnpResolutionProvenance`
|
|
3
|
+
* (M8 — see `.cursor/plans/m8-design.md` § 4).
|
|
4
|
+
*
|
|
5
|
+
* Today's `PnpResolutionProvenance` (in `services/pnp-provenance.ts`)
|
|
6
|
+
* tracks decisions made by `PnpToolResolver` only. M8 generalizes the
|
|
7
|
+
* shape to track decisions from every Pass-1 contributor — host
|
|
8
|
+
* placement, host policy, provider veto, QTI gates, and custom policy
|
|
9
|
+
* sources — without losing PNP debugger compatibility.
|
|
10
|
+
*
|
|
11
|
+
* **Compatibility posture.** This module is the new home of the shape;
|
|
12
|
+
* the legacy `pnp-provenance.ts` module remains untouched in PR 1 and
|
|
13
|
+
* is deleted in PR 5 (the rip-out PR) once every consumer has migrated
|
|
14
|
+
* to the engine. The shape stays structurally compatible: existing
|
|
15
|
+
* fields (`contextId`, `resolvedAt`, `sources`, `features`,
|
|
16
|
+
* `decisionLog`, `summary`) are preserved verbatim. The rule
|
|
17
|
+
* vocabulary expands, and `ResolutionDecision.precedence` widens from
|
|
18
|
+
* `1 | 2 | 3 | 4 | 5 | 6` to a `number` so non-QTI rules can fit
|
|
19
|
+
* (the QTI rules continue to use `1`–`6` exactly as before).
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Expanded rule vocabulary for `ResolutionDecision.rule` in M8.
|
|
23
|
+
*
|
|
24
|
+
* The first six values map 1:1 onto `PnpResolutionProvenance`'s
|
|
25
|
+
* existing rule names (the QTI 6-level precedence). The remaining
|
|
26
|
+
* values capture the new contributors the M8 engine surfaces:
|
|
27
|
+
* placement membership (step 1), provider veto (step 2), host policy
|
|
28
|
+
* (steps 3 / 4), the QTI-conflict diagnostic (`qti-required-blocked`),
|
|
29
|
+
* custom sources (step 6), and the catch-all `system-default` for the
|
|
30
|
+
* "not configured at any level" fallback.
|
|
31
|
+
*/
|
|
32
|
+
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" | "qti-required-blocked" | "custom-source" | "system-default";
|
|
33
|
+
export type ToolPolicySourceType = "organization" | "assessment" | "section" | "item" | "student" | "system" | "host" | "custom";
|
|
34
|
+
export interface ToolPolicyResolutionDecision {
|
|
35
|
+
/** Monotonic step index across the entire decision log. */
|
|
36
|
+
step: number;
|
|
37
|
+
/**
|
|
38
|
+
* Precedence level. QTI rules use `1`–`6` exactly as in today's
|
|
39
|
+
* `PnpResolutionProvenance`. Non-QTI rules use `0` (host-side
|
|
40
|
+
* gates that always fire before QTI) or `7+` (custom sources that
|
|
41
|
+
* fire after QTI).
|
|
42
|
+
*/
|
|
43
|
+
precedence: number;
|
|
44
|
+
rule: ToolPolicyDecisionRule;
|
|
45
|
+
/** Tool ID being resolved (post-PNP-support-mapping where applicable). */
|
|
46
|
+
featureId: string;
|
|
47
|
+
action: "block" | "enable" | "skip" | "advisory";
|
|
48
|
+
source: {
|
|
49
|
+
type: ToolPolicySourceType;
|
|
50
|
+
id?: string;
|
|
51
|
+
name?: string;
|
|
52
|
+
};
|
|
53
|
+
reason: string;
|
|
54
|
+
value?: unknown;
|
|
55
|
+
timestamp: Date;
|
|
56
|
+
}
|
|
57
|
+
export interface ToolPolicyFeatureTrail {
|
|
58
|
+
featureId: string;
|
|
59
|
+
finalState: "enabled" | "blocked" | "not-configured" | "advisory-only";
|
|
60
|
+
winningDecision?: ToolPolicyResolutionDecision;
|
|
61
|
+
allDecisions: ToolPolicyResolutionDecision[];
|
|
62
|
+
explanation: string;
|
|
63
|
+
}
|
|
64
|
+
export interface ToolPolicyProvenance {
|
|
65
|
+
contextId: string;
|
|
66
|
+
resolvedAt: Date;
|
|
67
|
+
sources: {
|
|
68
|
+
organization?: {
|
|
69
|
+
id: string;
|
|
70
|
+
name: string;
|
|
71
|
+
pnpDefaults?: unknown;
|
|
72
|
+
};
|
|
73
|
+
assessment?: {
|
|
74
|
+
id: string;
|
|
75
|
+
name: string;
|
|
76
|
+
settings?: unknown;
|
|
77
|
+
};
|
|
78
|
+
section?: {
|
|
79
|
+
id: string;
|
|
80
|
+
title?: string;
|
|
81
|
+
settings?: unknown;
|
|
82
|
+
};
|
|
83
|
+
item?: {
|
|
84
|
+
id: string;
|
|
85
|
+
name?: string;
|
|
86
|
+
settings?: unknown;
|
|
87
|
+
};
|
|
88
|
+
student?: {
|
|
89
|
+
id: string;
|
|
90
|
+
pnpProfile?: unknown;
|
|
91
|
+
};
|
|
92
|
+
host?: {
|
|
93
|
+
id: string;
|
|
94
|
+
config?: unknown;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
features: Map<string, ToolPolicyFeatureTrail>;
|
|
98
|
+
decisionLog: ToolPolicyResolutionDecision[];
|
|
99
|
+
summary: {
|
|
100
|
+
totalFeatures: number;
|
|
101
|
+
enabled: number;
|
|
102
|
+
blocked: number;
|
|
103
|
+
notConfigured: number;
|
|
104
|
+
bySource: Record<string, number>;
|
|
105
|
+
byRule: Record<string, number>;
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
interface AddDecisionParams {
|
|
109
|
+
precedence: number;
|
|
110
|
+
rule: ToolPolicyDecisionRule;
|
|
111
|
+
featureId: string;
|
|
112
|
+
action: ToolPolicyResolutionDecision["action"];
|
|
113
|
+
sourceType: ToolPolicySourceType;
|
|
114
|
+
sourceId?: string;
|
|
115
|
+
sourceName?: string;
|
|
116
|
+
reason: string;
|
|
117
|
+
value?: unknown;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Builder mirroring `PnpProvenanceBuilder` but emitting the expanded
|
|
121
|
+
* `ToolPolicyProvenance` shape. Identical API where the field names
|
|
122
|
+
* overlap so an `M8 PR 5` rename of the legacy builder is a near-pure
|
|
123
|
+
* import-path swap.
|
|
124
|
+
*/
|
|
125
|
+
export declare class ToolPolicyProvenanceBuilder {
|
|
126
|
+
private provenance;
|
|
127
|
+
private stepCounter;
|
|
128
|
+
constructor(contextId: string);
|
|
129
|
+
addSource(type: keyof ToolPolicyProvenance["sources"], data: {
|
|
130
|
+
id: string;
|
|
131
|
+
name?: string;
|
|
132
|
+
config?: unknown;
|
|
133
|
+
}): this;
|
|
134
|
+
addDecision(params: AddDecisionParams): this;
|
|
135
|
+
/**
|
|
136
|
+
* Reconcile every feature's `finalState` against the post-pipeline
|
|
137
|
+
* candidate set.
|
|
138
|
+
*
|
|
139
|
+
* The eager `finalState` updates inside `addDecision` track the
|
|
140
|
+
* highest-precedence non-skip decision per feature, but a tool's
|
|
141
|
+
* *actual* visibility is only known after step 6 of the
|
|
142
|
+
* composition pipeline — earlier decisions can be reversed by
|
|
143
|
+
* later host gates, QTI gates, or custom sources. This method
|
|
144
|
+
* walks every feature trail and rewrites `finalState` from the
|
|
145
|
+
* final candidate set so callers can rely on
|
|
146
|
+
* `provenance.features.get(toolId)?.finalState` as the canonical
|
|
147
|
+
* "is this tool visible right now?" answer (M8 design § 4 + § 12).
|
|
148
|
+
*
|
|
149
|
+
* Semantics applied per feature:
|
|
150
|
+
* - In `survivingIds` → "enabled"
|
|
151
|
+
* - Not in `survivingIds`, has any non-skip decision → "blocked"
|
|
152
|
+
* - Not in `survivingIds`, only advisory decisions → "advisory-only"
|
|
153
|
+
* - Otherwise → "not-configured"
|
|
154
|
+
*
|
|
155
|
+
* Surviving features without any logged decisions get a synthetic
|
|
156
|
+
* "enabled" trail so the provenance is dense enough for hosts that
|
|
157
|
+
* iterate `provenance.features` to find the visible set.
|
|
158
|
+
*/
|
|
159
|
+
reconcileFinalStates(survivingIds: ReadonlySet<string>): this;
|
|
160
|
+
build(): ToolPolicyProvenance;
|
|
161
|
+
}
|
|
162
|
+
export {};
|
|
163
|
+
//# sourceMappingURL=provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../../src/policy/core/provenance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Policy Provenance — generalization of `PnpResolutionProvenance`
|
|
3
|
+
* (M8 — see `.cursor/plans/m8-design.md` § 4).
|
|
4
|
+
*
|
|
5
|
+
* Today's `PnpResolutionProvenance` (in `services/pnp-provenance.ts`)
|
|
6
|
+
* tracks decisions made by `PnpToolResolver` only. M8 generalizes the
|
|
7
|
+
* shape to track decisions from every Pass-1 contributor — host
|
|
8
|
+
* placement, host policy, provider veto, QTI gates, and custom policy
|
|
9
|
+
* sources — without losing PNP debugger compatibility.
|
|
10
|
+
*
|
|
11
|
+
* **Compatibility posture.** This module is the new home of the shape;
|
|
12
|
+
* the legacy `pnp-provenance.ts` module remains untouched in PR 1 and
|
|
13
|
+
* is deleted in PR 5 (the rip-out PR) once every consumer has migrated
|
|
14
|
+
* to the engine. The shape stays structurally compatible: existing
|
|
15
|
+
* fields (`contextId`, `resolvedAt`, `sources`, `features`,
|
|
16
|
+
* `decisionLog`, `summary`) are preserved verbatim. The rule
|
|
17
|
+
* vocabulary expands, and `ResolutionDecision.precedence` widens from
|
|
18
|
+
* `1 | 2 | 3 | 4 | 5 | 6` to a `number` so non-QTI rules can fit
|
|
19
|
+
* (the QTI rules continue to use `1`–`6` exactly as before).
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Builder mirroring `PnpProvenanceBuilder` but emitting the expanded
|
|
23
|
+
* `ToolPolicyProvenance` shape. Identical API where the field names
|
|
24
|
+
* overlap so an `M8 PR 5` rename of the legacy builder is a near-pure
|
|
25
|
+
* import-path swap.
|
|
26
|
+
*/
|
|
27
|
+
export class ToolPolicyProvenanceBuilder {
|
|
28
|
+
provenance;
|
|
29
|
+
stepCounter = 0;
|
|
30
|
+
constructor(contextId) {
|
|
31
|
+
this.provenance = {
|
|
32
|
+
contextId,
|
|
33
|
+
resolvedAt: new Date(),
|
|
34
|
+
sources: {},
|
|
35
|
+
features: new Map(),
|
|
36
|
+
decisionLog: [],
|
|
37
|
+
summary: {
|
|
38
|
+
totalFeatures: 0,
|
|
39
|
+
enabled: 0,
|
|
40
|
+
blocked: 0,
|
|
41
|
+
notConfigured: 0,
|
|
42
|
+
bySource: {},
|
|
43
|
+
byRule: {},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
addSource(type, data) {
|
|
48
|
+
const base = { id: data.id, name: data.name ?? data.id };
|
|
49
|
+
switch (type) {
|
|
50
|
+
case "organization":
|
|
51
|
+
this.provenance.sources.organization = {
|
|
52
|
+
...base,
|
|
53
|
+
pnpDefaults: data.config,
|
|
54
|
+
};
|
|
55
|
+
break;
|
|
56
|
+
case "assessment":
|
|
57
|
+
this.provenance.sources.assessment = {
|
|
58
|
+
...base,
|
|
59
|
+
settings: data.config,
|
|
60
|
+
};
|
|
61
|
+
break;
|
|
62
|
+
case "section":
|
|
63
|
+
this.provenance.sources.section = { ...base, settings: data.config };
|
|
64
|
+
break;
|
|
65
|
+
case "item":
|
|
66
|
+
this.provenance.sources.item = { ...base, settings: data.config };
|
|
67
|
+
break;
|
|
68
|
+
case "student":
|
|
69
|
+
this.provenance.sources.student = {
|
|
70
|
+
id: data.id,
|
|
71
|
+
pnpProfile: data.config,
|
|
72
|
+
};
|
|
73
|
+
break;
|
|
74
|
+
case "host":
|
|
75
|
+
this.provenance.sources.host = { id: data.id, config: data.config };
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
addDecision(params) {
|
|
81
|
+
const decision = {
|
|
82
|
+
step: ++this.stepCounter,
|
|
83
|
+
precedence: params.precedence,
|
|
84
|
+
rule: params.rule,
|
|
85
|
+
featureId: params.featureId,
|
|
86
|
+
action: params.action,
|
|
87
|
+
source: {
|
|
88
|
+
type: params.sourceType,
|
|
89
|
+
id: params.sourceId,
|
|
90
|
+
name: params.sourceName,
|
|
91
|
+
},
|
|
92
|
+
reason: params.reason,
|
|
93
|
+
value: params.value,
|
|
94
|
+
timestamp: new Date(),
|
|
95
|
+
};
|
|
96
|
+
this.provenance.decisionLog.push(decision);
|
|
97
|
+
let trail = this.provenance.features.get(params.featureId);
|
|
98
|
+
if (!trail) {
|
|
99
|
+
trail = {
|
|
100
|
+
featureId: params.featureId,
|
|
101
|
+
finalState: "not-configured",
|
|
102
|
+
allDecisions: [],
|
|
103
|
+
explanation: "",
|
|
104
|
+
};
|
|
105
|
+
this.provenance.features.set(params.featureId, trail);
|
|
106
|
+
}
|
|
107
|
+
trail.allDecisions.push(decision);
|
|
108
|
+
// "advisory" doesn't change finalState — it preserves the existing
|
|
109
|
+
// blocked/enabled state and only flags a documented conflict.
|
|
110
|
+
if (params.action === "advisory") {
|
|
111
|
+
if (trail.finalState === "not-configured") {
|
|
112
|
+
trail.finalState = "advisory-only";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else if (params.action !== "skip") {
|
|
116
|
+
const isWinning = !trail.winningDecision ||
|
|
117
|
+
decision.precedence < trail.winningDecision.precedence;
|
|
118
|
+
if (isWinning) {
|
|
119
|
+
trail.winningDecision = decision;
|
|
120
|
+
trail.finalState = decision.action === "enable" ? "enabled" : "blocked";
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
this.provenance.summary.bySource[params.sourceType] =
|
|
124
|
+
(this.provenance.summary.bySource[params.sourceType] || 0) + 1;
|
|
125
|
+
this.provenance.summary.byRule[params.rule] =
|
|
126
|
+
(this.provenance.summary.byRule[params.rule] || 0) + 1;
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Reconcile every feature's `finalState` against the post-pipeline
|
|
131
|
+
* candidate set.
|
|
132
|
+
*
|
|
133
|
+
* The eager `finalState` updates inside `addDecision` track the
|
|
134
|
+
* highest-precedence non-skip decision per feature, but a tool's
|
|
135
|
+
* *actual* visibility is only known after step 6 of the
|
|
136
|
+
* composition pipeline — earlier decisions can be reversed by
|
|
137
|
+
* later host gates, QTI gates, or custom sources. This method
|
|
138
|
+
* walks every feature trail and rewrites `finalState` from the
|
|
139
|
+
* final candidate set so callers can rely on
|
|
140
|
+
* `provenance.features.get(toolId)?.finalState` as the canonical
|
|
141
|
+
* "is this tool visible right now?" answer (M8 design § 4 + § 12).
|
|
142
|
+
*
|
|
143
|
+
* Semantics applied per feature:
|
|
144
|
+
* - In `survivingIds` → "enabled"
|
|
145
|
+
* - Not in `survivingIds`, has any non-skip decision → "blocked"
|
|
146
|
+
* - Not in `survivingIds`, only advisory decisions → "advisory-only"
|
|
147
|
+
* - Otherwise → "not-configured"
|
|
148
|
+
*
|
|
149
|
+
* Surviving features without any logged decisions get a synthetic
|
|
150
|
+
* "enabled" trail so the provenance is dense enough for hosts that
|
|
151
|
+
* iterate `provenance.features` to find the visible set.
|
|
152
|
+
*/
|
|
153
|
+
reconcileFinalStates(survivingIds) {
|
|
154
|
+
for (const featureId of survivingIds) {
|
|
155
|
+
let trail = this.provenance.features.get(featureId);
|
|
156
|
+
if (!trail) {
|
|
157
|
+
trail = {
|
|
158
|
+
featureId,
|
|
159
|
+
finalState: "enabled",
|
|
160
|
+
allDecisions: [],
|
|
161
|
+
explanation: "",
|
|
162
|
+
};
|
|
163
|
+
this.provenance.features.set(featureId, trail);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
trail.finalState = "enabled";
|
|
167
|
+
}
|
|
168
|
+
for (const trail of this.provenance.features.values()) {
|
|
169
|
+
if (survivingIds.has(trail.featureId))
|
|
170
|
+
continue;
|
|
171
|
+
const hasNonSkip = trail.allDecisions.some((d) => d.action !== "skip" && d.action !== "advisory");
|
|
172
|
+
const hasAdvisory = trail.allDecisions.some((d) => d.action === "advisory");
|
|
173
|
+
if (hasNonSkip) {
|
|
174
|
+
trail.finalState = "blocked";
|
|
175
|
+
}
|
|
176
|
+
else if (hasAdvisory) {
|
|
177
|
+
trail.finalState = "advisory-only";
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
trail.finalState = "not-configured";
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return this;
|
|
184
|
+
}
|
|
185
|
+
build() {
|
|
186
|
+
for (const trail of this.provenance.features.values()) {
|
|
187
|
+
trail.explanation = generateExplanation(trail);
|
|
188
|
+
}
|
|
189
|
+
for (const trail of this.provenance.features.values()) {
|
|
190
|
+
this.provenance.summary.totalFeatures++;
|
|
191
|
+
if (trail.finalState === "enabled") {
|
|
192
|
+
this.provenance.summary.enabled++;
|
|
193
|
+
}
|
|
194
|
+
else if (trail.finalState === "blocked") {
|
|
195
|
+
this.provenance.summary.blocked++;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
this.provenance.summary.notConfigured++;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return this.provenance;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function generateExplanation(trail) {
|
|
205
|
+
if (!trail.winningDecision) {
|
|
206
|
+
if (trail.finalState === "advisory-only") {
|
|
207
|
+
const advisory = trail.allDecisions.find((d) => d.action === "advisory");
|
|
208
|
+
return advisory
|
|
209
|
+
? `Feature "${trail.featureId}" was kept in its host-decided state; ${advisory.reason}`
|
|
210
|
+
: `Feature "${trail.featureId}" carries an advisory note.`;
|
|
211
|
+
}
|
|
212
|
+
return `Feature "${trail.featureId}" was not configured at any level.`;
|
|
213
|
+
}
|
|
214
|
+
const decision = trail.winningDecision;
|
|
215
|
+
const sourceName = decision.source.name || decision.source.type;
|
|
216
|
+
let explanation = `Feature "${trail.featureId}" is ${trail.finalState}.\n\n`;
|
|
217
|
+
explanation += `**Primary Reason** (${decision.rule}):\n`;
|
|
218
|
+
explanation += `${decision.reason}\n`;
|
|
219
|
+
explanation += `Source: ${sourceName} (${decision.source.type})\n`;
|
|
220
|
+
const overridden = trail.allDecisions.filter((d) => d.step !== decision.step &&
|
|
221
|
+
d.action !== "skip" &&
|
|
222
|
+
d.action !== "advisory" &&
|
|
223
|
+
d.precedence > decision.precedence);
|
|
224
|
+
if (overridden.length > 0) {
|
|
225
|
+
explanation += `\n**Overridden Rules**:\n`;
|
|
226
|
+
for (const d of overridden) {
|
|
227
|
+
explanation += `- ${d.rule}: ${d.reason}\n`;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return explanation;
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../../src/policy/core/provenance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QTI input detection (M8 PR 4 — see `.cursor/plans/m8-design.md` F2 and
|
|
3
|
+
* `.cursor/plans/m8-implementation-plan.md` § PR 4).
|
|
4
|
+
*
|
|
5
|
+
* Pure helpers that decide whether the inputs the engine has been given
|
|
6
|
+
* actually carry QTI 6-level precedence material. Used by:
|
|
7
|
+
*
|
|
8
|
+
* - {@link ToolPolicyEngine}'s constructor as the auto-default for
|
|
9
|
+
* `qtiEnforcement` when the host did not pass an explicit `"on"` /
|
|
10
|
+
* `"off"`.
|
|
11
|
+
* - {@link ToolkitCoordinator.resolveEffectiveQtiEnforcement} 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 QTI material."
|
|
15
|
+
*
|
|
16
|
+
* The rule is intentionally narrow. Hosts that bind a bare assessment
|
|
17
|
+
* record (only `id` / `name`, no PNP and no settings) get the legacy
|
|
18
|
+
* floating-tools behavior — QTI gates do not engage. The flip happens
|
|
19
|
+
* the moment the assessment carries any of:
|
|
20
|
+
*
|
|
21
|
+
* - `personalNeedsProfile` (any `supports`, `prohibitedSupports`, or
|
|
22
|
+
* `activateAtInit`),
|
|
23
|
+
* - `settings.districtPolicy` (any `blockedTools`, `requiredTools`,
|
|
24
|
+
* or `policies`),
|
|
25
|
+
* - `settings.testAdministration` (any populated key — `mode`,
|
|
26
|
+
* `toolOverrides`, etc.),
|
|
27
|
+
* - or the bound `currentItemRef.settings` carries
|
|
28
|
+
* `requiredTools` / `restrictedTools` / `toolParameters`.
|
|
29
|
+
*
|
|
30
|
+
* Hosts opt out of the auto-on behavior by passing
|
|
31
|
+
* `qtiEnforcement: "off"` explicitly (engine input or
|
|
32
|
+
* `ToolkitCoordinator.setQtiEnforcement("off")`).
|
|
33
|
+
*/
|
|
34
|
+
import type { AssessmentEntity, AssessmentItemRef } from "@pie-players/pie-players-shared/types";
|
|
35
|
+
/**
|
|
36
|
+
* Return `true` when the assessment carries any QTI 6-level precedence
|
|
37
|
+
* material that the engine's `QtiPolicySource` would consume.
|
|
38
|
+
*
|
|
39
|
+
* The check is structural — the presence of a non-empty PNP, district
|
|
40
|
+
* policy, or test administration block is enough; the content does not
|
|
41
|
+
* have to validate against any specific rule.
|
|
42
|
+
*/
|
|
43
|
+
export declare function assessmentHasQtiInputs(assessment: AssessmentEntity | null | undefined): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Return `true` when the bound item reference carries item-level QTI
|
|
46
|
+
* material (`requiredTools`, `restrictedTools`, or `toolParameters`).
|
|
47
|
+
*
|
|
48
|
+
* Used in addition to {@link assessmentHasQtiInputs} so a host that
|
|
49
|
+
* navigates to an item with QTI-relevant settings — without a parent
|
|
50
|
+
* assessment carrying its own PNP/district/test-admin block — still
|
|
51
|
+
* gets QTI gates engaged for that item.
|
|
52
|
+
*/
|
|
53
|
+
export declare function itemRefHasQtiInputs(itemRef: AssessmentItemRef | null | undefined): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the default `qtiEnforcement` mode given the bound inputs.
|
|
56
|
+
*
|
|
57
|
+
* Returns `"on"` when {@link assessmentHasQtiInputs} or
|
|
58
|
+
* {@link itemRefHasQtiInputs} reports any QTI material; otherwise
|
|
59
|
+
* `"off"`. Hosts override the default by passing an explicit
|
|
60
|
+
* `qtiEnforcement` value (engine input) or by calling
|
|
61
|
+
* `ToolkitCoordinator.setQtiEnforcement("on" | "off")`.
|
|
62
|
+
*/
|
|
63
|
+
export declare function resolveDefaultQtiEnforcement(args: {
|
|
64
|
+
assessment?: AssessmentEntity | null;
|
|
65
|
+
currentItemRef?: AssessmentItemRef | null;
|
|
66
|
+
}): "on" | "off";
|
|
67
|
+
//# sourceMappingURL=qti-inputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti-inputs.d.ts","sourceRoot":"","sources":["../../../src/policy/core/qti-inputs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EACX,gBAAgB,EAChB,iBAAiB,EACjB,MAAM,uCAAuC,CAAC;AAE/C;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACrC,UAAU,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,GAC7C,OAAO,CA4DT;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,GAC3C,OAAO,CAuBT;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IAClD,UAAU,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACrC,cAAc,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC1C,GAAG,IAAI,GAAG,KAAK,CAIf"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QTI input detection (M8 PR 4 — see `.cursor/plans/m8-design.md` F2 and
|
|
3
|
+
* `.cursor/plans/m8-implementation-plan.md` § PR 4).
|
|
4
|
+
*
|
|
5
|
+
* Pure helpers that decide whether the inputs the engine has been given
|
|
6
|
+
* actually carry QTI 6-level precedence material. Used by:
|
|
7
|
+
*
|
|
8
|
+
* - {@link ToolPolicyEngine}'s constructor as the auto-default for
|
|
9
|
+
* `qtiEnforcement` when the host did not pass an explicit `"on"` /
|
|
10
|
+
* `"off"`.
|
|
11
|
+
* - {@link ToolkitCoordinator.resolveEffectiveQtiEnforcement} 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 QTI material."
|
|
15
|
+
*
|
|
16
|
+
* The rule is intentionally narrow. Hosts that bind a bare assessment
|
|
17
|
+
* record (only `id` / `name`, no PNP and no settings) get the legacy
|
|
18
|
+
* floating-tools behavior — QTI gates do not engage. The flip happens
|
|
19
|
+
* the moment the assessment carries any of:
|
|
20
|
+
*
|
|
21
|
+
* - `personalNeedsProfile` (any `supports`, `prohibitedSupports`, or
|
|
22
|
+
* `activateAtInit`),
|
|
23
|
+
* - `settings.districtPolicy` (any `blockedTools`, `requiredTools`,
|
|
24
|
+
* or `policies`),
|
|
25
|
+
* - `settings.testAdministration` (any populated key — `mode`,
|
|
26
|
+
* `toolOverrides`, etc.),
|
|
27
|
+
* - or the bound `currentItemRef.settings` carries
|
|
28
|
+
* `requiredTools` / `restrictedTools` / `toolParameters`.
|
|
29
|
+
*
|
|
30
|
+
* Hosts opt out of the auto-on behavior by passing
|
|
31
|
+
* `qtiEnforcement: "off"` explicitly (engine input or
|
|
32
|
+
* `ToolkitCoordinator.setQtiEnforcement("off")`).
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Return `true` when the assessment carries any QTI 6-level precedence
|
|
36
|
+
* material that the engine's `QtiPolicySource` would consume.
|
|
37
|
+
*
|
|
38
|
+
* The check is structural — the presence of a non-empty PNP, district
|
|
39
|
+
* policy, or test administration block is enough; the content does not
|
|
40
|
+
* have to validate against any specific rule.
|
|
41
|
+
*/
|
|
42
|
+
export function assessmentHasQtiInputs(assessment) {
|
|
43
|
+
if (!assessment)
|
|
44
|
+
return false;
|
|
45
|
+
const pnp = assessment.personalNeedsProfile;
|
|
46
|
+
if (pnp) {
|
|
47
|
+
if (Array.isArray(pnp.supports) && pnp.supports.length > 0)
|
|
48
|
+
return true;
|
|
49
|
+
if (Array.isArray(pnp.prohibitedSupports) &&
|
|
50
|
+
pnp.prohibitedSupports.length > 0) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (Array.isArray(pnp.activateAtInit) &&
|
|
54
|
+
pnp.activateAtInit.length > 0) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const settings = assessment.settings;
|
|
59
|
+
if (settings) {
|
|
60
|
+
const district = settings.districtPolicy;
|
|
61
|
+
if (district) {
|
|
62
|
+
if (Array.isArray(district.blockedTools) &&
|
|
63
|
+
district.blockedTools.length > 0) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
if (Array.isArray(district.requiredTools) &&
|
|
67
|
+
district.requiredTools.length > 0) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
if (district.policies &&
|
|
71
|
+
typeof district.policies === "object" &&
|
|
72
|
+
Object.keys(district.policies).length > 0) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const admin = settings.testAdministration;
|
|
77
|
+
if (admin && typeof admin === "object") {
|
|
78
|
+
for (const key of Object.keys(admin)) {
|
|
79
|
+
const value = admin[key];
|
|
80
|
+
if (value === undefined || value === null)
|
|
81
|
+
continue;
|
|
82
|
+
if (Array.isArray(value) && value.length === 0)
|
|
83
|
+
continue;
|
|
84
|
+
if (typeof value === "object" &&
|
|
85
|
+
!Array.isArray(value) &&
|
|
86
|
+
Object.keys(value).length === 0) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Return `true` when the bound item reference carries item-level QTI
|
|
97
|
+
* material (`requiredTools`, `restrictedTools`, or `toolParameters`).
|
|
98
|
+
*
|
|
99
|
+
* Used in addition to {@link assessmentHasQtiInputs} so a host that
|
|
100
|
+
* navigates to an item with QTI-relevant settings — without a parent
|
|
101
|
+
* assessment carrying its own PNP/district/test-admin block — still
|
|
102
|
+
* gets QTI gates engaged for that item.
|
|
103
|
+
*/
|
|
104
|
+
export function itemRefHasQtiInputs(itemRef) {
|
|
105
|
+
const settings = itemRef?.settings;
|
|
106
|
+
if (!settings)
|
|
107
|
+
return false;
|
|
108
|
+
if (Array.isArray(settings.requiredTools) &&
|
|
109
|
+
settings.requiredTools.length > 0) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
if (Array.isArray(settings.restrictedTools) &&
|
|
113
|
+
settings.restrictedTools.length > 0) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (settings.toolParameters &&
|
|
117
|
+
typeof settings.toolParameters === "object" &&
|
|
118
|
+
Object.keys(settings.toolParameters).length > 0) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Resolve the default `qtiEnforcement` mode given the bound inputs.
|
|
125
|
+
*
|
|
126
|
+
* Returns `"on"` when {@link assessmentHasQtiInputs} or
|
|
127
|
+
* {@link itemRefHasQtiInputs} reports any QTI material; otherwise
|
|
128
|
+
* `"off"`. Hosts override the default by passing an explicit
|
|
129
|
+
* `qtiEnforcement` value (engine input) or by calling
|
|
130
|
+
* `ToolkitCoordinator.setQtiEnforcement("on" | "off")`.
|
|
131
|
+
*/
|
|
132
|
+
export function resolveDefaultQtiEnforcement(args) {
|
|
133
|
+
if (assessmentHasQtiInputs(args.assessment))
|
|
134
|
+
return "on";
|
|
135
|
+
if (itemRefHasQtiInputs(args.currentItemRef))
|
|
136
|
+
return "on";
|
|
137
|
+
return "off";
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=qti-inputs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti-inputs.js","sourceRoot":"","sources":["../../../src/policy/core/qti-inputs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
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, QTI 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 QTI
|
|
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`.
|
|
21
|
+
*/
|
|
22
|
+
export { ToolPolicyEngine, type QtiEnforcementMode, 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
|
+
export type { QtiRequiredBlockedDetails, ToolPolicyDecision, ToolPolicyDecisionRequest, ToolPolicyDiagnostic, ToolPolicyDiagnosticCode, ToolPolicyEntry, ToolPolicyHostGate, ToolScope, } from "./core/decision-types.js";
|
|
25
|
+
export type { PolicySource, PolicySourceDecisionContext, PolicySourceProvenanceEntry, PolicySourceResult, } from "./core/PolicySource.js";
|
|
26
|
+
export type { PolicySourceTag, QtiPolicySourceRule, QtiPolicySourceTag, CustomPolicySourceTag, } from "./core/policy-source-tag.js";
|
|
27
|
+
export type { ToolPolicyDecisionRule, ToolPolicyFeatureTrail, ToolPolicyProvenance, ToolPolicyResolutionDecision, ToolPolicySourceType, } from "./core/provenance.js";
|
|
28
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/policy/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EACN,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC3B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACN,sBAAsB,EACtB,KAAK,uBAAuB,GAC5B,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACX,yBAAyB,EACzB,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,kBAAkB,EAClB,SAAS,GACT,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACX,YAAY,EACZ,2BAA2B,EAC3B,2BAA2B,EAC3B,kBAAkB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACX,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACrB,MAAM,6BAA6B,CAAC;AAErC,YAAY,EACX,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,4BAA4B,EAC5B,oBAAoB,GACpB,MAAM,sBAAsB,CAAC"}
|