@vue-skuilder/db 0.1.22 → 0.1.24

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 (67) hide show
  1. package/dist/{contentSource-BP9hznNV.d.ts → contentSource-BotbOOfX.d.ts} +227 -3
  2. package/dist/{contentSource-DsJadoBU.d.cts → contentSource-C90LH-OH.d.cts} +227 -3
  3. package/dist/core/index.d.cts +220 -6
  4. package/dist/core/index.d.ts +220 -6
  5. package/dist/core/index.js +2052 -559
  6. package/dist/core/index.js.map +1 -1
  7. package/dist/core/index.mjs +2035 -555
  8. package/dist/core/index.mjs.map +1 -1
  9. package/dist/{dataLayerProvider-CHYrQ5pB.d.cts → dataLayerProvider-DGKp4zFB.d.cts} +1 -1
  10. package/dist/{dataLayerProvider-MDTxXq2l.d.ts → dataLayerProvider-SBpz9jQf.d.ts} +1 -1
  11. package/dist/impl/couch/index.d.cts +11 -3
  12. package/dist/impl/couch/index.d.ts +11 -3
  13. package/dist/impl/couch/index.js +1811 -574
  14. package/dist/impl/couch/index.js.map +1 -1
  15. package/dist/impl/couch/index.mjs +1792 -550
  16. package/dist/impl/couch/index.mjs.map +1 -1
  17. package/dist/impl/static/index.d.cts +4 -4
  18. package/dist/impl/static/index.d.ts +4 -4
  19. package/dist/impl/static/index.js +1797 -560
  20. package/dist/impl/static/index.js.map +1 -1
  21. package/dist/impl/static/index.mjs +1789 -547
  22. package/dist/impl/static/index.mjs.map +1 -1
  23. package/dist/{index-Dj0SEgk3.d.ts → index-BWvO-_rJ.d.ts} +1 -1
  24. package/dist/{index-B_j6u5E4.d.cts → index-Ba7hYbHj.d.cts} +1 -1
  25. package/dist/index.d.cts +150 -12
  26. package/dist/index.d.ts +150 -12
  27. package/dist/index.js +2658 -791
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +2584 -747
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/{types-DQaXnuoc.d.ts → types-CJrLM1Ew.d.ts} +1 -1
  32. package/dist/{types-Bn0itutr.d.cts → types-W8n-B6HG.d.cts} +1 -1
  33. package/dist/{types-legacy-DDY4N-Uq.d.cts → types-legacy-JXDxinpU.d.cts} +5 -1
  34. package/dist/{types-legacy-DDY4N-Uq.d.ts → types-legacy-JXDxinpU.d.ts} +5 -1
  35. package/dist/util/packer/index.d.cts +3 -3
  36. package/dist/util/packer/index.d.ts +3 -3
  37. package/docs/brainstorm-navigation-paradigm.md +40 -34
  38. package/docs/future-orchestration-vision.md +216 -0
  39. package/docs/navigators-architecture.md +188 -5
  40. package/docs/todo-strategy-authoring.md +8 -6
  41. package/package.json +3 -3
  42. package/src/core/index.ts +2 -0
  43. package/src/core/interfaces/contentSource.ts +7 -0
  44. package/src/core/interfaces/userDB.ts +6 -0
  45. package/src/core/navigators/Pipeline.ts +46 -0
  46. package/src/core/navigators/PipelineAssembler.ts +14 -1
  47. package/src/core/navigators/filters/WeightedFilter.ts +141 -0
  48. package/src/core/navigators/filters/types.ts +4 -0
  49. package/src/core/navigators/generators/CompositeGenerator.ts +61 -19
  50. package/src/core/navigators/generators/types.ts +4 -0
  51. package/src/core/navigators/index.ts +194 -13
  52. package/src/core/orchestration/gradient.ts +133 -0
  53. package/src/core/orchestration/index.ts +210 -0
  54. package/src/core/orchestration/learning.ts +250 -0
  55. package/src/core/orchestration/recording.ts +92 -0
  56. package/src/core/orchestration/signal.ts +67 -0
  57. package/src/core/types/contentNavigationStrategy.ts +38 -0
  58. package/src/core/types/learningState.ts +77 -0
  59. package/src/core/types/types-legacy.ts +4 -0
  60. package/src/core/types/userOutcome.ts +51 -0
  61. package/src/courseConfigRegistration.ts +546 -0
  62. package/src/factory.ts +6 -0
  63. package/src/impl/common/BaseUserDB.ts +16 -0
  64. package/src/index.ts +2 -0
  65. package/src/study/SessionController.ts +64 -1
  66. package/tests/core/navigators/Pipeline.test.ts +2 -0
  67. package/docs/todo-evolutionary-orchestration.md +0 -310
@@ -1,8 +1,8 @@
1
- import { W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../contentSource-DsJadoBU.cjs';
2
- export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, O as NavigatorRole, P as NavigatorRoles, N as Navigators, j as ScheduledCard, H as SessionTrackingData, L as StrategyContribution, i as StudentClassroomDBInterface, h as StudyContentSource, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, S as StudySessionItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, M as getCardOrigin, r as getStudySource, R as isFilter, Q as isGenerator, p as isReview } from '../contentSource-DsJadoBU.cjs';
3
- export { D as DataLayerProvider } from '../dataLayerProvider-CHYrQ5pB.cjs';
4
- import { b as DocTypePrefixes, D as DocType, C as CardHistory, c as CardRecord, i as QuestionRecord } from '../types-legacy-DDY4N-Uq.cjs';
5
- export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-DDY4N-Uq.cjs';
1
+ import { a1 as LearnableWeight, L as UserOutcomeRecord, a2 as OrchestrationContext, W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../contentSource-C90LH-OH.cjs';
2
+ export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, N as NavigatorConstructor, Z as NavigatorRole, _ as NavigatorRoles, Y as Navigators, j as ScheduledCard, H as SessionTrackingData, V as StrategyContribution, i as StudentClassroomDBInterface, h as StudyContentSource, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, S as StudySessionItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, a3 as computeDeviation, a5 as computeEffectiveWeight, a4 as computeSpread, a6 as createOrchestrationContext, X as getCardOrigin, O as getRegisteredNavigator, Q as getRegisteredNavigatorNames, r as getStudySource, P as hasRegisteredNavigator, R as initializeNavigatorRegistry, a0 as isFilter, $ as isGenerator, p as isReview, M as registerNavigator } from '../contentSource-C90LH-OH.cjs';
3
+ export { D as DataLayerProvider } from '../dataLayerProvider-DGKp4zFB.cjs';
4
+ import { D as DocType, i as QuestionRecord, b as DocTypePrefixes, C as CardHistory, c as CardRecord } from '../types-legacy-JXDxinpU.cjs';
5
+ export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-JXDxinpU.cjs';
6
6
  import { DataShape, ParsedCard } from '@vue-skuilder/common';
7
7
  import 'moment';
8
8
 
@@ -12,6 +12,216 @@ declare abstract class Loggable {
12
12
  protected error(...args: unknown[]): void;
13
13
  }
14
14
 
15
+ /**
16
+ * Snapshot of the learning state for a strategy.
17
+ *
18
+ * Stored in the CourseDB for observability and debugging.
19
+ * Updated periodically by the gradient learning system.
20
+ */
21
+ interface StrategyLearningState {
22
+ /**
23
+ * Unique ID: "STRATEGY_LEARNING_STATE::{courseId}::{strategyId}"
24
+ */
25
+ _id: string;
26
+ /** Allow CouchDB to manage revisions */
27
+ _rev?: string;
28
+ docType: DocType.STRATEGY_LEARNING_STATE;
29
+ courseId: string;
30
+ strategyId: string;
31
+ /** Current learned weight (mirrors the strategy doc, for convenience) */
32
+ currentWeight: LearnableWeight;
33
+ /** Most recent regression statistics */
34
+ regression: {
35
+ /** Slope of the linear regression (deviation vs outcome) */
36
+ gradient: number;
37
+ /** Y-intercept of the regression line */
38
+ intercept: number;
39
+ /** R-squared value (0-1), measure of fit quality */
40
+ rSquared: number;
41
+ /** Number of observations used in this regression */
42
+ sampleSize: number;
43
+ /** ISO timestamp of when this regression was computed */
44
+ computedAt: string;
45
+ };
46
+ /** Historical weight snapshots for visualization */
47
+ history: Array<{
48
+ timestamp: string;
49
+ weight: number;
50
+ confidence: number;
51
+ gradient: number;
52
+ }>;
53
+ /** ISO timestamp of last update */
54
+ updatedAt: string;
55
+ }
56
+ /**
57
+ * Data point for gradient computation: (deviation, outcome) pair.
58
+ */
59
+ interface GradientObservation {
60
+ /** User's deviation for this strategy [-1, 1] */
61
+ deviation: number;
62
+ /** User's outcome value [0, 1] */
63
+ outcomeValue: number;
64
+ /** Optional: weight for this observation (default 1.0) */
65
+ weight?: number;
66
+ }
67
+ /**
68
+ * Result of linear regression on (deviation, outcome) pairs.
69
+ */
70
+ interface GradientResult {
71
+ /** Slope: positive = higher deviation correlates with better outcomes */
72
+ gradient: number;
73
+ /** Y-intercept */
74
+ intercept: number;
75
+ /** R-squared: 0-1, how well the line fits */
76
+ rSquared: number;
77
+ /** Number of observations */
78
+ sampleSize: number;
79
+ }
80
+
81
+ /**
82
+ * Extract (deviation, outcome) observations for a specific strategy
83
+ * from a collection of UserOutcomeRecords.
84
+ *
85
+ * @param outcomes - Collection of outcome records (from multiple users)
86
+ * @param strategyId - The strategy to extract observations for
87
+ * @returns Array of gradient observations
88
+ */
89
+ declare function aggregateOutcomesForGradient(outcomes: UserOutcomeRecord[], strategyId: string): GradientObservation[];
90
+ /**
91
+ * Compute linear regression on (deviation, outcome) pairs.
92
+ *
93
+ * Uses ordinary least squares to find the best fit line:
94
+ * outcome = gradient * deviation + intercept
95
+ *
96
+ * The gradient tells us:
97
+ * - Positive: users with higher deviation (higher weight) had better outcomes
98
+ * → we should increase the peak weight
99
+ * - Negative: users with higher deviation (higher weight) had worse outcomes
100
+ * → we should decrease the peak weight
101
+ * - Near zero: weight doesn't affect outcomes much
102
+ * → we're near optimal, increase confidence
103
+ *
104
+ * @param observations - Array of (deviation, outcome) pairs
105
+ * @returns Regression result, or null if insufficient data
106
+ */
107
+ declare function computeStrategyGradient(observations: GradientObservation[]): GradientResult | null;
108
+
109
+ /**
110
+ * Compute updated weight based on gradient result.
111
+ *
112
+ * The update logic:
113
+ * - Positive gradient: users with higher weight did better → increase weight
114
+ * - Negative gradient: users with higher weight did worse → decrease weight
115
+ * - Flat gradient: weight doesn't affect outcome → increase confidence
116
+ *
117
+ * @param current - Current learnable weight
118
+ * @param gradient - Computed gradient result
119
+ * @returns Updated learnable weight
120
+ */
121
+ declare function updateStrategyWeight(current: LearnableWeight, gradient: GradientResult): LearnableWeight;
122
+ /**
123
+ * Create or update a StrategyLearningState document.
124
+ *
125
+ * @param courseId - Course ID
126
+ * @param strategyId - Strategy ID
127
+ * @param currentWeight - Current learned weight
128
+ * @param gradient - Gradient result from recent computation
129
+ * @param existing - Existing learning state (if any)
130
+ * @returns Updated learning state document
131
+ */
132
+ declare function updateLearningState(courseId: string, strategyId: string, currentWeight: LearnableWeight, gradient: GradientResult, existing?: StrategyLearningState): StrategyLearningState;
133
+ /**
134
+ * Input data for running a period update on a single strategy.
135
+ */
136
+ interface PeriodUpdateInput {
137
+ courseId: string;
138
+ strategyId: string;
139
+ currentWeight: LearnableWeight;
140
+ gradient: GradientResult;
141
+ existingState?: StrategyLearningState;
142
+ }
143
+ /**
144
+ * Result of a period update for a single strategy.
145
+ */
146
+ interface PeriodUpdateResult {
147
+ strategyId: string;
148
+ previousWeight: LearnableWeight;
149
+ newWeight: LearnableWeight;
150
+ gradient: GradientResult;
151
+ learningState: StrategyLearningState;
152
+ updated: boolean;
153
+ }
154
+ /**
155
+ * Run a period update for a single strategy.
156
+ *
157
+ * This function:
158
+ * 1. Takes the computed gradient
159
+ * 2. Computes the new weight
160
+ * 3. Generates the updated learning state
161
+ *
162
+ * Note: Actual persistence (updating strategy doc, saving learning state)
163
+ * must be done by the caller with appropriate DB access.
164
+ *
165
+ * @param input - Update input data
166
+ * @returns Update result with new weight and learning state
167
+ */
168
+ declare function runPeriodUpdate(input: PeriodUpdateInput): PeriodUpdateResult;
169
+ /**
170
+ * Create a default LearnableWeight for strategies that don't have one.
171
+ */
172
+ declare function getDefaultLearnableWeight(): LearnableWeight;
173
+
174
+ interface SignalConfig {
175
+ /** Target accuracy for "in the zone" learning (default: 0.85) */
176
+ targetAccuracy?: number;
177
+ /** Width of the peak plateau (default: 0.05) */
178
+ tolerance?: number;
179
+ }
180
+ /**
181
+ * Computes a scalar signal (0-1) representing the quality of the learning outcome.
182
+ *
183
+ * Current implementation focuses on "accuracy within Zone of Proximal Development".
184
+ * Future versions should include ELO gain rate.
185
+ *
186
+ * @param records - List of question attempts in the period
187
+ * @param config - Configuration for the signal function
188
+ * @returns Score 0.0-1.0, or null if insufficient data
189
+ */
190
+ declare function computeOutcomeSignal(records: QuestionRecord[], config?: SignalConfig): number | null;
191
+ /**
192
+ * Scores an accuracy value based on how close it is to the target "sweet spot".
193
+ *
194
+ * The function defines a plateau of width (2 * tolerance) around the target
195
+ * where score is 1.0. Outside this plateau, it falls off linearly.
196
+ *
197
+ * @param accuracy - Observed accuracy (0-1)
198
+ * @param target - Target accuracy (e.g. 0.85)
199
+ * @param tolerance - +/- range allowed for max score
200
+ */
201
+ declare function scoreAccuracyInZone(accuracy: number, target: number, tolerance: number): number;
202
+
203
+ /**
204
+ * Records a learning outcome for a specific period of time.
205
+ *
206
+ * This function:
207
+ * 1. Computes a scalar "success" signal from the provided question records
208
+ * 2. Re-computes the deviations that were active for this user/course
209
+ * 3. Persists a UserOutcomeRecord to the user's database
210
+ *
211
+ * This record is later used by the optimization job to correlate
212
+ * deviations with outcomes (Evolutionary Orchestration).
213
+ *
214
+ * @param context - Orchestration context (user, course, etc.)
215
+ * @param periodStart - ISO timestamp of period start
216
+ * @param periodEnd - ISO timestamp of period end (now)
217
+ * @param records - Question records generated during this period
218
+ * @param activeStrategyIds - IDs of strategies active in this course
219
+ * @param eloStart - User's ELO at start of period (optional)
220
+ * @param eloEnd - User's ELO at end of period (optional)
221
+ * @param config - Optional configuration for signal computation
222
+ */
223
+ declare function recordUserOutcome(context: OrchestrationContext, periodStart: string, periodEnd: string, records: QuestionRecord[], activeStrategyIds: string[], eloStart?: number, eloEnd?: number, config?: SignalConfig): Promise<void>;
224
+
15
225
  /**
16
226
  * Shared context available to all filters in a pipeline.
17
227
  *
@@ -25,6 +235,8 @@ interface FilterContext {
25
235
  course: CourseDBInterface;
26
236
  /** User's global ELO score for this course */
27
237
  userElo: number;
238
+ /** Orchestration context for evolutionary weighting */
239
+ orchestration?: OrchestrationContext;
28
240
  }
29
241
  /**
30
242
  * A filter that transforms a list of weighted cards.
@@ -104,6 +316,8 @@ interface GeneratorContext {
104
316
  course: CourseDBInterface;
105
317
  /** User's global ELO score for this course */
106
318
  userElo: number;
319
+ /** Orchestration context for evolutionary weighting */
320
+ orchestration?: OrchestrationContext;
107
321
  }
108
322
  /**
109
323
  * A generator that produces candidate cards with initial scores.
@@ -301,4 +515,4 @@ declare function validateProcessorConfig(config: Partial<BulkCardProcessorConfig
301
515
  errorMessage?: string;
302
516
  };
303
517
 
304
- export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, DocType, DocTypePrefixes, type FilterContext, type GeneratorContext, type ImportResult, Loggable, QuestionRecord, type StrategyStateDoc, type StrategyStateId, UserDBInterface, WeightedCard, areQuestionRecords, buildStrategyStateId, docIsDeleted, getCardHistoryID, importParsedCards, isQuestionRecord, parseCardHistoryID, validateProcessorConfig };
518
+ export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, DocType, DocTypePrefixes, type FilterContext, type GeneratorContext, type GradientObservation, type GradientResult, type ImportResult, LearnableWeight, Loggable, OrchestrationContext, type PeriodUpdateInput, type PeriodUpdateResult, QuestionRecord, type SignalConfig, type StrategyLearningState, type StrategyStateDoc, type StrategyStateId, UserDBInterface, UserOutcomeRecord, WeightedCard, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, parseCardHistoryID, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, validateProcessorConfig };
@@ -1,8 +1,8 @@
1
- import { W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../contentSource-BP9hznNV.js';
2
- export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, O as NavigatorRole, P as NavigatorRoles, N as Navigators, j as ScheduledCard, H as SessionTrackingData, L as StrategyContribution, i as StudentClassroomDBInterface, h as StudyContentSource, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, S as StudySessionItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, M as getCardOrigin, r as getStudySource, R as isFilter, Q as isGenerator, p as isReview } from '../contentSource-BP9hznNV.js';
3
- export { D as DataLayerProvider } from '../dataLayerProvider-MDTxXq2l.js';
4
- import { b as DocTypePrefixes, D as DocType, C as CardHistory, c as CardRecord, i as QuestionRecord } from '../types-legacy-DDY4N-Uq.js';
5
- export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-DDY4N-Uq.js';
1
+ import { a1 as LearnableWeight, L as UserOutcomeRecord, a2 as OrchestrationContext, W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../contentSource-BotbOOfX.js';
2
+ export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, N as NavigatorConstructor, Z as NavigatorRole, _ as NavigatorRoles, Y as Navigators, j as ScheduledCard, H as SessionTrackingData, V as StrategyContribution, i as StudentClassroomDBInterface, h as StudyContentSource, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, S as StudySessionItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, a3 as computeDeviation, a5 as computeEffectiveWeight, a4 as computeSpread, a6 as createOrchestrationContext, X as getCardOrigin, O as getRegisteredNavigator, Q as getRegisteredNavigatorNames, r as getStudySource, P as hasRegisteredNavigator, R as initializeNavigatorRegistry, a0 as isFilter, $ as isGenerator, p as isReview, M as registerNavigator } from '../contentSource-BotbOOfX.js';
3
+ export { D as DataLayerProvider } from '../dataLayerProvider-SBpz9jQf.js';
4
+ import { D as DocType, i as QuestionRecord, b as DocTypePrefixes, C as CardHistory, c as CardRecord } from '../types-legacy-JXDxinpU.js';
5
+ export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-JXDxinpU.js';
6
6
  import { DataShape, ParsedCard } from '@vue-skuilder/common';
7
7
  import 'moment';
8
8
 
@@ -12,6 +12,216 @@ declare abstract class Loggable {
12
12
  protected error(...args: unknown[]): void;
13
13
  }
14
14
 
15
+ /**
16
+ * Snapshot of the learning state for a strategy.
17
+ *
18
+ * Stored in the CourseDB for observability and debugging.
19
+ * Updated periodically by the gradient learning system.
20
+ */
21
+ interface StrategyLearningState {
22
+ /**
23
+ * Unique ID: "STRATEGY_LEARNING_STATE::{courseId}::{strategyId}"
24
+ */
25
+ _id: string;
26
+ /** Allow CouchDB to manage revisions */
27
+ _rev?: string;
28
+ docType: DocType.STRATEGY_LEARNING_STATE;
29
+ courseId: string;
30
+ strategyId: string;
31
+ /** Current learned weight (mirrors the strategy doc, for convenience) */
32
+ currentWeight: LearnableWeight;
33
+ /** Most recent regression statistics */
34
+ regression: {
35
+ /** Slope of the linear regression (deviation vs outcome) */
36
+ gradient: number;
37
+ /** Y-intercept of the regression line */
38
+ intercept: number;
39
+ /** R-squared value (0-1), measure of fit quality */
40
+ rSquared: number;
41
+ /** Number of observations used in this regression */
42
+ sampleSize: number;
43
+ /** ISO timestamp of when this regression was computed */
44
+ computedAt: string;
45
+ };
46
+ /** Historical weight snapshots for visualization */
47
+ history: Array<{
48
+ timestamp: string;
49
+ weight: number;
50
+ confidence: number;
51
+ gradient: number;
52
+ }>;
53
+ /** ISO timestamp of last update */
54
+ updatedAt: string;
55
+ }
56
+ /**
57
+ * Data point for gradient computation: (deviation, outcome) pair.
58
+ */
59
+ interface GradientObservation {
60
+ /** User's deviation for this strategy [-1, 1] */
61
+ deviation: number;
62
+ /** User's outcome value [0, 1] */
63
+ outcomeValue: number;
64
+ /** Optional: weight for this observation (default 1.0) */
65
+ weight?: number;
66
+ }
67
+ /**
68
+ * Result of linear regression on (deviation, outcome) pairs.
69
+ */
70
+ interface GradientResult {
71
+ /** Slope: positive = higher deviation correlates with better outcomes */
72
+ gradient: number;
73
+ /** Y-intercept */
74
+ intercept: number;
75
+ /** R-squared: 0-1, how well the line fits */
76
+ rSquared: number;
77
+ /** Number of observations */
78
+ sampleSize: number;
79
+ }
80
+
81
+ /**
82
+ * Extract (deviation, outcome) observations for a specific strategy
83
+ * from a collection of UserOutcomeRecords.
84
+ *
85
+ * @param outcomes - Collection of outcome records (from multiple users)
86
+ * @param strategyId - The strategy to extract observations for
87
+ * @returns Array of gradient observations
88
+ */
89
+ declare function aggregateOutcomesForGradient(outcomes: UserOutcomeRecord[], strategyId: string): GradientObservation[];
90
+ /**
91
+ * Compute linear regression on (deviation, outcome) pairs.
92
+ *
93
+ * Uses ordinary least squares to find the best fit line:
94
+ * outcome = gradient * deviation + intercept
95
+ *
96
+ * The gradient tells us:
97
+ * - Positive: users with higher deviation (higher weight) had better outcomes
98
+ * → we should increase the peak weight
99
+ * - Negative: users with higher deviation (higher weight) had worse outcomes
100
+ * → we should decrease the peak weight
101
+ * - Near zero: weight doesn't affect outcomes much
102
+ * → we're near optimal, increase confidence
103
+ *
104
+ * @param observations - Array of (deviation, outcome) pairs
105
+ * @returns Regression result, or null if insufficient data
106
+ */
107
+ declare function computeStrategyGradient(observations: GradientObservation[]): GradientResult | null;
108
+
109
+ /**
110
+ * Compute updated weight based on gradient result.
111
+ *
112
+ * The update logic:
113
+ * - Positive gradient: users with higher weight did better → increase weight
114
+ * - Negative gradient: users with higher weight did worse → decrease weight
115
+ * - Flat gradient: weight doesn't affect outcome → increase confidence
116
+ *
117
+ * @param current - Current learnable weight
118
+ * @param gradient - Computed gradient result
119
+ * @returns Updated learnable weight
120
+ */
121
+ declare function updateStrategyWeight(current: LearnableWeight, gradient: GradientResult): LearnableWeight;
122
+ /**
123
+ * Create or update a StrategyLearningState document.
124
+ *
125
+ * @param courseId - Course ID
126
+ * @param strategyId - Strategy ID
127
+ * @param currentWeight - Current learned weight
128
+ * @param gradient - Gradient result from recent computation
129
+ * @param existing - Existing learning state (if any)
130
+ * @returns Updated learning state document
131
+ */
132
+ declare function updateLearningState(courseId: string, strategyId: string, currentWeight: LearnableWeight, gradient: GradientResult, existing?: StrategyLearningState): StrategyLearningState;
133
+ /**
134
+ * Input data for running a period update on a single strategy.
135
+ */
136
+ interface PeriodUpdateInput {
137
+ courseId: string;
138
+ strategyId: string;
139
+ currentWeight: LearnableWeight;
140
+ gradient: GradientResult;
141
+ existingState?: StrategyLearningState;
142
+ }
143
+ /**
144
+ * Result of a period update for a single strategy.
145
+ */
146
+ interface PeriodUpdateResult {
147
+ strategyId: string;
148
+ previousWeight: LearnableWeight;
149
+ newWeight: LearnableWeight;
150
+ gradient: GradientResult;
151
+ learningState: StrategyLearningState;
152
+ updated: boolean;
153
+ }
154
+ /**
155
+ * Run a period update for a single strategy.
156
+ *
157
+ * This function:
158
+ * 1. Takes the computed gradient
159
+ * 2. Computes the new weight
160
+ * 3. Generates the updated learning state
161
+ *
162
+ * Note: Actual persistence (updating strategy doc, saving learning state)
163
+ * must be done by the caller with appropriate DB access.
164
+ *
165
+ * @param input - Update input data
166
+ * @returns Update result with new weight and learning state
167
+ */
168
+ declare function runPeriodUpdate(input: PeriodUpdateInput): PeriodUpdateResult;
169
+ /**
170
+ * Create a default LearnableWeight for strategies that don't have one.
171
+ */
172
+ declare function getDefaultLearnableWeight(): LearnableWeight;
173
+
174
+ interface SignalConfig {
175
+ /** Target accuracy for "in the zone" learning (default: 0.85) */
176
+ targetAccuracy?: number;
177
+ /** Width of the peak plateau (default: 0.05) */
178
+ tolerance?: number;
179
+ }
180
+ /**
181
+ * Computes a scalar signal (0-1) representing the quality of the learning outcome.
182
+ *
183
+ * Current implementation focuses on "accuracy within Zone of Proximal Development".
184
+ * Future versions should include ELO gain rate.
185
+ *
186
+ * @param records - List of question attempts in the period
187
+ * @param config - Configuration for the signal function
188
+ * @returns Score 0.0-1.0, or null if insufficient data
189
+ */
190
+ declare function computeOutcomeSignal(records: QuestionRecord[], config?: SignalConfig): number | null;
191
+ /**
192
+ * Scores an accuracy value based on how close it is to the target "sweet spot".
193
+ *
194
+ * The function defines a plateau of width (2 * tolerance) around the target
195
+ * where score is 1.0. Outside this plateau, it falls off linearly.
196
+ *
197
+ * @param accuracy - Observed accuracy (0-1)
198
+ * @param target - Target accuracy (e.g. 0.85)
199
+ * @param tolerance - +/- range allowed for max score
200
+ */
201
+ declare function scoreAccuracyInZone(accuracy: number, target: number, tolerance: number): number;
202
+
203
+ /**
204
+ * Records a learning outcome for a specific period of time.
205
+ *
206
+ * This function:
207
+ * 1. Computes a scalar "success" signal from the provided question records
208
+ * 2. Re-computes the deviations that were active for this user/course
209
+ * 3. Persists a UserOutcomeRecord to the user's database
210
+ *
211
+ * This record is later used by the optimization job to correlate
212
+ * deviations with outcomes (Evolutionary Orchestration).
213
+ *
214
+ * @param context - Orchestration context (user, course, etc.)
215
+ * @param periodStart - ISO timestamp of period start
216
+ * @param periodEnd - ISO timestamp of period end (now)
217
+ * @param records - Question records generated during this period
218
+ * @param activeStrategyIds - IDs of strategies active in this course
219
+ * @param eloStart - User's ELO at start of period (optional)
220
+ * @param eloEnd - User's ELO at end of period (optional)
221
+ * @param config - Optional configuration for signal computation
222
+ */
223
+ declare function recordUserOutcome(context: OrchestrationContext, periodStart: string, periodEnd: string, records: QuestionRecord[], activeStrategyIds: string[], eloStart?: number, eloEnd?: number, config?: SignalConfig): Promise<void>;
224
+
15
225
  /**
16
226
  * Shared context available to all filters in a pipeline.
17
227
  *
@@ -25,6 +235,8 @@ interface FilterContext {
25
235
  course: CourseDBInterface;
26
236
  /** User's global ELO score for this course */
27
237
  userElo: number;
238
+ /** Orchestration context for evolutionary weighting */
239
+ orchestration?: OrchestrationContext;
28
240
  }
29
241
  /**
30
242
  * A filter that transforms a list of weighted cards.
@@ -104,6 +316,8 @@ interface GeneratorContext {
104
316
  course: CourseDBInterface;
105
317
  /** User's global ELO score for this course */
106
318
  userElo: number;
319
+ /** Orchestration context for evolutionary weighting */
320
+ orchestration?: OrchestrationContext;
107
321
  }
108
322
  /**
109
323
  * A generator that produces candidate cards with initial scores.
@@ -301,4 +515,4 @@ declare function validateProcessorConfig(config: Partial<BulkCardProcessorConfig
301
515
  errorMessage?: string;
302
516
  };
303
517
 
304
- export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, DocType, DocTypePrefixes, type FilterContext, type GeneratorContext, type ImportResult, Loggable, QuestionRecord, type StrategyStateDoc, type StrategyStateId, UserDBInterface, WeightedCard, areQuestionRecords, buildStrategyStateId, docIsDeleted, getCardHistoryID, importParsedCards, isQuestionRecord, parseCardHistoryID, validateProcessorConfig };
518
+ export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, DocType, DocTypePrefixes, type FilterContext, type GeneratorContext, type GradientObservation, type GradientResult, type ImportResult, LearnableWeight, Loggable, OrchestrationContext, type PeriodUpdateInput, type PeriodUpdateResult, QuestionRecord, type SignalConfig, type StrategyLearningState, type StrategyStateDoc, type StrategyStateId, UserDBInterface, UserOutcomeRecord, WeightedCard, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, parseCardHistoryID, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, validateProcessorConfig };