@vue-skuilder/db 0.2.8 → 0.2.9
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/dist/{contentSource-Cplhv3bJ.d.ts → contentSource-C-0t0y0V.d.ts} +7 -0
- package/dist/{contentSource-kI9_jwTu.d.cts → contentSource-jSkcOt2s.d.cts} +7 -0
- package/dist/core/index.d.cts +29 -4
- package/dist/core/index.d.ts +29 -4
- package/dist/core/index.js +132 -39
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +130 -39
- package/dist/core/index.mjs.map +1 -1
- package/dist/{dataLayerProvider-DrBqOUa3.d.ts → dataLayerProvider-BB0oi9T0.d.ts} +1 -1
- package/dist/{dataLayerProvider-CiA2Rr0v.d.cts → dataLayerProvider-BDClIrFC.d.cts} +1 -1
- package/dist/impl/couch/index.d.cts +2 -2
- package/dist/impl/couch/index.d.ts +2 -2
- package/dist/impl/couch/index.js +128 -39
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +128 -39
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.d.cts +2 -2
- package/dist/impl/static/index.d.ts +2 -2
- package/dist/impl/static/index.js +128 -39
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +128 -39
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/index.d.cts +115 -81
- package/dist/index.d.ts +115 -81
- package/dist/index.js +371 -251
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +369 -251
- package/dist/index.mjs.map +1 -1
- package/docs/navigators-architecture.md +29 -13
- package/package.json +3 -3
- package/src/core/interfaces/contentSource.ts +7 -0
- package/src/core/navigators/SrsDebugger.ts +53 -0
- package/src/core/navigators/generators/prescribed.ts +76 -9
- package/src/core/navigators/generators/srs.ts +81 -37
- package/src/core/navigators/index.ts +5 -0
- package/src/study/SessionController.ts +260 -249
- package/src/study/SessionDebugger.ts +15 -25
- package/src/study/SessionOverlay.ts +108 -13
package/dist/core/index.mjs
CHANGED
|
@@ -1617,6 +1617,30 @@ Example:
|
|
|
1617
1617
|
}
|
|
1618
1618
|
});
|
|
1619
1619
|
|
|
1620
|
+
// src/core/navigators/SrsDebugger.ts
|
|
1621
|
+
var SrsDebugger_exports = {};
|
|
1622
|
+
__export(SrsDebugger_exports, {
|
|
1623
|
+
captureSrsBacklog: () => captureSrsBacklog,
|
|
1624
|
+
clearSrsBacklogDebug: () => clearSrsBacklogDebug,
|
|
1625
|
+
getSrsBacklogDebug: () => getSrsBacklogDebug
|
|
1626
|
+
});
|
|
1627
|
+
function captureSrsBacklog(snapshot) {
|
|
1628
|
+
snapshots.set(snapshot.courseId, snapshot);
|
|
1629
|
+
}
|
|
1630
|
+
function getSrsBacklogDebug() {
|
|
1631
|
+
return [...snapshots.values()].sort((a, b) => b.timestamp - a.timestamp);
|
|
1632
|
+
}
|
|
1633
|
+
function clearSrsBacklogDebug() {
|
|
1634
|
+
snapshots.clear();
|
|
1635
|
+
}
|
|
1636
|
+
var snapshots;
|
|
1637
|
+
var init_SrsDebugger = __esm({
|
|
1638
|
+
"src/core/navigators/SrsDebugger.ts"() {
|
|
1639
|
+
"use strict";
|
|
1640
|
+
snapshots = /* @__PURE__ */ new Map();
|
|
1641
|
+
}
|
|
1642
|
+
});
|
|
1643
|
+
|
|
1620
1644
|
// src/core/navigators/generators/CompositeGenerator.ts
|
|
1621
1645
|
var CompositeGenerator_exports = {};
|
|
1622
1646
|
__export(CompositeGenerator_exports, {
|
|
@@ -1984,7 +2008,7 @@ function shuffleInPlace(arr) {
|
|
|
1984
2008
|
function pickTopByScore(cards, limit) {
|
|
1985
2009
|
return [...cards].sort((a, b) => b.score - a.score || a.cardId.localeCompare(b.cardId)).slice(0, limit);
|
|
1986
2010
|
}
|
|
1987
|
-
var DEFAULT_FRESHNESS_WINDOW, DEFAULT_MAX_DIRECT_PER_RUN, DEFAULT_MAX_SUPPORT_PER_RUN, DEFAULT_HIERARCHY_DEPTH, DEFAULT_MIN_COUNT, DEFAULT_PRACTICE_MIN_COUNT, DEFAULT_MAX_PRACTICE_PER_RUN, BASE_TARGET_SCORE, BASE_SUPPORT_SCORE, DISCOVERED_SUPPORT_SCORE, BASE_PRACTICE_SCORE, MAX_TARGET_MULTIPLIER, MAX_SUPPORT_MULTIPLIER, PRESCRIBED_DEBUG_VERSION, PrescribedCardsGenerator;
|
|
2011
|
+
var DEFAULT_FRESHNESS_WINDOW, DEFAULT_MAX_DIRECT_PER_RUN, DEFAULT_MAX_SUPPORT_PER_RUN, DEFAULT_HIERARCHY_DEPTH, DEFAULT_MIN_COUNT, DEFAULT_PRACTICE_MIN_COUNT, DEFAULT_MAX_PRACTICE_PER_RUN, BASE_TARGET_SCORE, BASE_SUPPORT_SCORE, DISCOVERED_SUPPORT_SCORE, BASE_PRACTICE_SCORE, PRACTICE_BASE_MULT, MAX_PRACTICE_MULTIPLIER, PRACTICE_STALENESS_BUMP_PER_DAY, MAX_TARGET_MULTIPLIER, MAX_SUPPORT_MULTIPLIER, PRESCRIBED_DEBUG_VERSION, PrescribedCardsGenerator;
|
|
1988
2012
|
var init_prescribed = __esm({
|
|
1989
2013
|
"src/core/navigators/generators/prescribed.ts"() {
|
|
1990
2014
|
"use strict";
|
|
@@ -2001,6 +2025,9 @@ var init_prescribed = __esm({
|
|
|
2001
2025
|
BASE_SUPPORT_SCORE = 0.8;
|
|
2002
2026
|
DISCOVERED_SUPPORT_SCORE = 12;
|
|
2003
2027
|
BASE_PRACTICE_SCORE = 1;
|
|
2028
|
+
PRACTICE_BASE_MULT = 2;
|
|
2029
|
+
MAX_PRACTICE_MULTIPLIER = 4;
|
|
2030
|
+
PRACTICE_STALENESS_BUMP_PER_DAY = 0.5;
|
|
2004
2031
|
MAX_TARGET_MULTIPLIER = 8;
|
|
2005
2032
|
MAX_SUPPORT_MULTIPLIER = 4;
|
|
2006
2033
|
PRESCRIBED_DEBUG_VERSION = "testversion-prescribed-v3";
|
|
@@ -2060,6 +2087,8 @@ var init_prescribed = __esm({
|
|
|
2060
2087
|
const emitted = [];
|
|
2061
2088
|
const emittedIds = /* @__PURE__ */ new Set();
|
|
2062
2089
|
const groupRuntimes = [];
|
|
2090
|
+
const priorPracticeDebt = progress.practiceDebt ?? {};
|
|
2091
|
+
const nextPracticeDebt = {};
|
|
2063
2092
|
for (const group of this.config.groups) {
|
|
2064
2093
|
const runtime = this.buildGroupRuntimeState({
|
|
2065
2094
|
group,
|
|
@@ -2117,10 +2146,13 @@ var init_prescribed = __esm({
|
|
|
2117
2146
|
userTagElo,
|
|
2118
2147
|
userGlobalElo,
|
|
2119
2148
|
activeIds,
|
|
2120
|
-
seenIds
|
|
2149
|
+
seenIds,
|
|
2150
|
+
priorPracticeDebt,
|
|
2151
|
+
nextPracticeDebt
|
|
2121
2152
|
});
|
|
2122
2153
|
emitted.push(...directCards, ...supportCards, ...discoveredSupportCards, ...practiceCards);
|
|
2123
2154
|
}
|
|
2155
|
+
nextState.practiceDebt = nextPracticeDebt;
|
|
2124
2156
|
const hintSummary = this.buildSupportHintSummary(groupRuntimes);
|
|
2125
2157
|
const hints = Object.keys(hintSummary.boostTags).length > 0 ? {
|
|
2126
2158
|
boostTags: hintSummary.boostTags,
|
|
@@ -2454,9 +2486,16 @@ var init_prescribed = __esm({
|
|
|
2454
2486
|
* `practiceMinCount`), this resolves cards carrying that tag and emits them
|
|
2455
2487
|
* into the candidate pool. It exists because global-ELO retrieval
|
|
2456
2488
|
* systematically fails to fetch the (low-ELO) drill cards for a
|
|
2457
|
-
* freshly-introduced skill — putting them in the pool here
|
|
2458
|
-
*
|
|
2459
|
-
*
|
|
2489
|
+
* freshly-introduced skill — putting them in the pool here guarantees presence.
|
|
2490
|
+
*
|
|
2491
|
+
* Emphasis is a **practice-debt pressure** (parallel to SRS backlog pressure):
|
|
2492
|
+
* cards score `base × multiplier`, where the multiplier starts at
|
|
2493
|
+
* PRACTICE_BASE_MULT (so a few reps land promptly post-intro, competing with
|
|
2494
|
+
* pressured reviews) and escalates by how long the debt has stayed open
|
|
2495
|
+
* (per-tag, time-based via `priorPracticeDebt`/`nextPracticeDebt`), clamped at
|
|
2496
|
+
* MAX_PRACTICE_MULTIPLIER. The debt is durable and self-discharges the instant
|
|
2497
|
+
* the skill reaches `practiceMinCount` — so this no longer relies on the
|
|
2498
|
+
* session-scoped intro boost to actually surface.
|
|
2460
2499
|
*
|
|
2461
2500
|
* Fully data-driven: the unlock relation comes from the hierarchy config and
|
|
2462
2501
|
* practice-status from per-tag ELO. No card-id or tag-namespace hard-coding.
|
|
@@ -2471,7 +2510,9 @@ var init_prescribed = __esm({
|
|
|
2471
2510
|
userTagElo,
|
|
2472
2511
|
userGlobalElo,
|
|
2473
2512
|
activeIds,
|
|
2474
|
-
seenIds
|
|
2513
|
+
seenIds,
|
|
2514
|
+
priorPracticeDebt,
|
|
2515
|
+
nextPracticeDebt
|
|
2475
2516
|
} = args;
|
|
2476
2517
|
const patterns = group.practiceTagPatterns ?? [];
|
|
2477
2518
|
if (patterns.length === 0) return [];
|
|
@@ -2481,6 +2522,20 @@ var init_prescribed = __esm({
|
|
|
2481
2522
|
(tag) => patterns.some((p) => matchesTagPattern(tag, p)) && this.isUnlockedGatedSkill(tag, hierarchyConfigs, userTagElo, userGlobalElo) && (userTagElo[tag]?.count ?? 0) < practiceMinCount
|
|
2482
2523
|
);
|
|
2483
2524
|
if (practiceTags.length === 0) return [];
|
|
2525
|
+
const now = Date.now();
|
|
2526
|
+
const DAY_MS = 24 * 60 * 60 * 1e3;
|
|
2527
|
+
const tagMultiplier = /* @__PURE__ */ new Map();
|
|
2528
|
+
for (const tag of practiceTags) {
|
|
2529
|
+
const firstOwedAt = priorPracticeDebt[tag] ?? isoNow();
|
|
2530
|
+
nextPracticeDebt[tag] = firstOwedAt;
|
|
2531
|
+
const staleDays = Math.max(0, (now - new Date(firstOwedAt).getTime()) / DAY_MS);
|
|
2532
|
+
const mult = clamp(
|
|
2533
|
+
PRACTICE_BASE_MULT + staleDays * PRACTICE_STALENESS_BUMP_PER_DAY,
|
|
2534
|
+
PRACTICE_BASE_MULT,
|
|
2535
|
+
MAX_PRACTICE_MULTIPLIER
|
|
2536
|
+
);
|
|
2537
|
+
tagMultiplier.set(tag, mult);
|
|
2538
|
+
}
|
|
2484
2539
|
const practiceCardIds = this.findDiscoveredSupportCards({
|
|
2485
2540
|
supportTags: practiceTags,
|
|
2486
2541
|
cardsByTag,
|
|
@@ -2496,18 +2551,25 @@ var init_prescribed = __esm({
|
|
|
2496
2551
|
const cards = [];
|
|
2497
2552
|
for (const cardId of practiceCardIds) {
|
|
2498
2553
|
emittedIds.add(cardId);
|
|
2554
|
+
let mult = PRACTICE_BASE_MULT;
|
|
2555
|
+
for (const tag of practiceTags) {
|
|
2556
|
+
if (cardsByTag.get(tag)?.includes(cardId) ?? false) {
|
|
2557
|
+
mult = Math.max(mult, tagMultiplier.get(tag) ?? PRACTICE_BASE_MULT);
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
const score = BASE_PRACTICE_SCORE * mult;
|
|
2499
2561
|
cards.push({
|
|
2500
2562
|
cardId,
|
|
2501
2563
|
courseId,
|
|
2502
|
-
score
|
|
2564
|
+
score,
|
|
2503
2565
|
provenance: [
|
|
2504
2566
|
{
|
|
2505
2567
|
strategy: "prescribed",
|
|
2506
2568
|
strategyName: this.strategyName || this.name,
|
|
2507
2569
|
strategyId: this.strategyId || "NAVIGATION_STRATEGY-prescribed",
|
|
2508
2570
|
action: "generated",
|
|
2509
|
-
score
|
|
2510
|
-
reason: `mode=practice;group=${group.id};underPracticedSkills=${practiceTags.length};practiceTags=${practiceTags.slice(0, 8).join("|")}${practiceTags.length > 8 ? "|\u2026" : ""};testversion=${PRESCRIBED_DEBUG_VERSION}`
|
|
2571
|
+
score,
|
|
2572
|
+
reason: `mode=practice;group=${group.id};debtMult=\xD7${mult.toFixed(2)};underPracticedSkills=${practiceTags.length};practiceTags=${practiceTags.slice(0, 8).join("|")}${practiceTags.length > 8 ? "|\u2026" : ""};testversion=${PRESCRIBED_DEBUG_VERSION}`
|
|
2511
2573
|
}
|
|
2512
2574
|
]
|
|
2513
2575
|
});
|
|
@@ -2681,14 +2743,15 @@ __export(srs_exports, {
|
|
|
2681
2743
|
default: () => SRSNavigator
|
|
2682
2744
|
});
|
|
2683
2745
|
import moment3 from "moment";
|
|
2684
|
-
var DEFAULT_HEALTHY_BACKLOG,
|
|
2746
|
+
var DEFAULT_HEALTHY_BACKLOG, MAX_BACKLOG_MULTIPLIER, SRSNavigator;
|
|
2685
2747
|
var init_srs = __esm({
|
|
2686
2748
|
"src/core/navigators/generators/srs.ts"() {
|
|
2687
2749
|
"use strict";
|
|
2688
2750
|
init_navigators();
|
|
2751
|
+
init_SrsDebugger();
|
|
2689
2752
|
init_logger();
|
|
2690
2753
|
DEFAULT_HEALTHY_BACKLOG = 20;
|
|
2691
|
-
|
|
2754
|
+
MAX_BACKLOG_MULTIPLIER = 2;
|
|
2692
2755
|
SRSNavigator = class extends ContentNavigator {
|
|
2693
2756
|
/** Human-readable name for CardGenerator interface */
|
|
2694
2757
|
name;
|
|
@@ -2755,9 +2818,18 @@ var init_srs = __esm({
|
|
|
2755
2818
|
}
|
|
2756
2819
|
}
|
|
2757
2820
|
}
|
|
2758
|
-
const
|
|
2821
|
+
const backlogMultiplier = this.computeBacklogMultiplier(dueReviews.length);
|
|
2822
|
+
const notDue = reviews.filter((r) => !now.isAfter(moment3.utc(r.reviewTime)));
|
|
2823
|
+
let nextDueIn = null;
|
|
2824
|
+
if (notDue.length > 0) {
|
|
2825
|
+
const next = notDue.reduce(
|
|
2826
|
+
(a, b) => moment3.utc(a.reviewTime).isBefore(moment3.utc(b.reviewTime)) ? a : b
|
|
2827
|
+
);
|
|
2828
|
+
const until = moment3.duration(moment3.utc(next.reviewTime).diff(now));
|
|
2829
|
+
nextDueIn = until.asHours() < 1 ? `${Math.round(until.asMinutes())}m` : until.asHours() < 24 ? `${Math.round(until.asHours())}h` : `${Math.round(until.asDays())}d`;
|
|
2830
|
+
}
|
|
2759
2831
|
if (dueReviews.length > 0) {
|
|
2760
|
-
const pressureNote =
|
|
2832
|
+
const pressureNote = backlogMultiplier > 1 ? ` [backlog pressure: \xD7${backlogMultiplier.toFixed(2)}]` : ` [healthy backlog]`;
|
|
2761
2833
|
logger.info(
|
|
2762
2834
|
`[SRS] Course ${courseId}: ${dueReviews.length} reviews due now (of ${reviews.length} scheduled)${pressureNote}`
|
|
2763
2835
|
);
|
|
@@ -2776,7 +2848,7 @@ var init_srs = __esm({
|
|
|
2776
2848
|
logger.info(`[SRS] Course ${courseId}: No reviews scheduled`);
|
|
2777
2849
|
}
|
|
2778
2850
|
const scored = dueReviews.map((review) => {
|
|
2779
|
-
const { score, reason } = this.computeUrgencyScore(review, now,
|
|
2851
|
+
const { score, reason } = this.computeUrgencyScore(review, now, backlogMultiplier);
|
|
2780
2852
|
return {
|
|
2781
2853
|
cardId: review.cardId,
|
|
2782
2854
|
courseId: review.courseId,
|
|
@@ -2794,30 +2866,42 @@ var init_srs = __esm({
|
|
|
2794
2866
|
]
|
|
2795
2867
|
};
|
|
2796
2868
|
});
|
|
2797
|
-
|
|
2869
|
+
const sorted = scored.sort((a, b) => b.score - a.score);
|
|
2870
|
+
captureSrsBacklog({
|
|
2871
|
+
courseId,
|
|
2872
|
+
scheduledTotal: reviews.length,
|
|
2873
|
+
dueNow: dueReviews.length,
|
|
2874
|
+
healthyBacklog: this.healthyBacklog,
|
|
2875
|
+
backlogMultiplier,
|
|
2876
|
+
maxBacklogMultiplier: MAX_BACKLOG_MULTIPLIER,
|
|
2877
|
+
topReviewScore: sorted.length > 0 ? sorted[0].score : null,
|
|
2878
|
+
nextDueIn,
|
|
2879
|
+
timestamp: Date.now()
|
|
2880
|
+
});
|
|
2881
|
+
return { cards: sorted.slice(0, limit) };
|
|
2798
2882
|
}
|
|
2799
2883
|
/**
|
|
2800
|
-
* Compute backlog pressure based on number of due reviews.
|
|
2884
|
+
* Compute the multiplicative backlog pressure based on number of due reviews.
|
|
2801
2885
|
*
|
|
2802
|
-
*
|
|
2803
|
-
* and
|
|
2886
|
+
* ×1.0 at or below the healthy threshold (no boost), increasing linearly above
|
|
2887
|
+
* it and maxing out at MAX_BACKLOG_MULTIPLIER at 3× the healthy backlog.
|
|
2804
2888
|
*
|
|
2805
|
-
* Examples (with default healthyBacklog=20):
|
|
2806
|
-
* - 10 due reviews →
|
|
2807
|
-
* - 20 due reviews →
|
|
2808
|
-
* - 40 due reviews →
|
|
2809
|
-
* - 60 due reviews →
|
|
2889
|
+
* Examples (with default healthyBacklog=20, MAX_BACKLOG_MULTIPLIER=2.0):
|
|
2890
|
+
* - 10 due reviews → ×1.00 (healthy)
|
|
2891
|
+
* - 20 due reviews → ×1.00 (at threshold)
|
|
2892
|
+
* - 40 due reviews → ×1.50 (2x threshold)
|
|
2893
|
+
* - 60 due reviews → ×2.00 (3x threshold, maxed)
|
|
2810
2894
|
*
|
|
2811
2895
|
* @param dueCount - Number of reviews currently due
|
|
2812
|
-
* @returns
|
|
2896
|
+
* @returns Multiplier applied to review urgency (1.0 to MAX_BACKLOG_MULTIPLIER)
|
|
2813
2897
|
*/
|
|
2814
|
-
|
|
2898
|
+
computeBacklogMultiplier(dueCount) {
|
|
2815
2899
|
if (dueCount <= this.healthyBacklog) {
|
|
2816
|
-
return
|
|
2900
|
+
return 1;
|
|
2817
2901
|
}
|
|
2818
2902
|
const excess = dueCount - this.healthyBacklog;
|
|
2819
|
-
const
|
|
2820
|
-
return Math.min(
|
|
2903
|
+
const multiplier = 1 + excess / this.healthyBacklog * ((MAX_BACKLOG_MULTIPLIER - 1) / 2);
|
|
2904
|
+
return Math.min(MAX_BACKLOG_MULTIPLIER, multiplier);
|
|
2821
2905
|
}
|
|
2822
2906
|
/**
|
|
2823
2907
|
* Compute urgency score for a review card.
|
|
@@ -2832,19 +2916,20 @@ var init_srs = __esm({
|
|
|
2832
2916
|
* - 30 days (720h) → ~0.56
|
|
2833
2917
|
* - 180 days → ~0.30
|
|
2834
2918
|
*
|
|
2835
|
-
* 3. Backlog pressure = global
|
|
2836
|
-
*
|
|
2837
|
-
* - At 2x healthy: +0.25
|
|
2838
|
-
* - At 3x+ healthy: +0.50 (max)
|
|
2919
|
+
* 3. Backlog pressure = global *multiplier* when review backlog exceeds the
|
|
2920
|
+
* healthy threshold (×1.0 healthy → up to MAX_BACKLOG_MULTIPLIER at 3×).
|
|
2839
2921
|
*
|
|
2840
|
-
* Combined: base 0.5 +
|
|
2841
|
-
*
|
|
2922
|
+
* Combined: (base 0.5 + urgency factors * 0.45) × backlog multiplier.
|
|
2923
|
+
* Per-card range before pressure: ~0.57–0.95. NOT clamped to 1.0 — under a
|
|
2924
|
+
* heavy backlog reviews scale onto the open scale to compete with (and exceed)
|
|
2925
|
+
* new cards; what keeps them from running away is the bounded multiplier, not
|
|
2926
|
+
* a hard ceiling.
|
|
2842
2927
|
*
|
|
2843
2928
|
* @param review - The scheduled card to score
|
|
2844
2929
|
* @param now - Current time
|
|
2845
|
-
* @param
|
|
2930
|
+
* @param backlogMultiplier - Pre-computed backlog multiplier (1.0 to MAX_BACKLOG_MULTIPLIER)
|
|
2846
2931
|
*/
|
|
2847
|
-
computeUrgencyScore(review, now,
|
|
2932
|
+
computeUrgencyScore(review, now, backlogMultiplier) {
|
|
2848
2933
|
const scheduledAt = moment3.utc(review.scheduledAt);
|
|
2849
2934
|
const due = moment3.utc(review.reviewTime);
|
|
2850
2935
|
const intervalHours = Math.max(1, due.diff(scheduledAt, "hours"));
|
|
@@ -2854,15 +2939,15 @@ var init_srs = __esm({
|
|
|
2854
2939
|
const overdueContribution = Math.min(1, Math.max(0, relativeOverdue));
|
|
2855
2940
|
const urgency = overdueContribution * 0.5 + recencyFactor * 0.5;
|
|
2856
2941
|
const baseScore = 0.5 + urgency * 0.45;
|
|
2857
|
-
const score =
|
|
2942
|
+
const score = baseScore * backlogMultiplier;
|
|
2858
2943
|
const reasonParts = [
|
|
2859
2944
|
`${Math.round(hoursOverdue)}h overdue`,
|
|
2860
2945
|
`interval: ${Math.round(intervalHours)}h`,
|
|
2861
2946
|
`relative: ${relativeOverdue.toFixed(2)}`,
|
|
2862
2947
|
`recency: ${recencyFactor.toFixed(2)}`
|
|
2863
2948
|
];
|
|
2864
|
-
if (
|
|
2865
|
-
reasonParts.push(`backlog:
|
|
2949
|
+
if (backlogMultiplier > 1) {
|
|
2950
|
+
reasonParts.push(`backlog: \xD7${backlogMultiplier.toFixed(2)}`);
|
|
2866
2951
|
}
|
|
2867
2952
|
reasonParts.push("review");
|
|
2868
2953
|
const reason = reasonParts.join(", ");
|
|
@@ -5160,6 +5245,7 @@ var init_3 = __esm({
|
|
|
5160
5245
|
"./Pipeline.ts": () => Promise.resolve().then(() => (init_Pipeline(), Pipeline_exports)),
|
|
5161
5246
|
"./PipelineAssembler.ts": () => Promise.resolve().then(() => (init_PipelineAssembler(), PipelineAssembler_exports)),
|
|
5162
5247
|
"./PipelineDebugger.ts": () => Promise.resolve().then(() => (init_PipelineDebugger(), PipelineDebugger_exports)),
|
|
5248
|
+
"./SrsDebugger.ts": () => Promise.resolve().then(() => (init_SrsDebugger(), SrsDebugger_exports)),
|
|
5163
5249
|
"./defaults.ts": () => Promise.resolve().then(() => (init_defaults(), defaults_exports)),
|
|
5164
5250
|
"./diversityRerank.ts": () => Promise.resolve().then(() => (init_diversityRerank(), diversityRerank_exports)),
|
|
5165
5251
|
"./filters/WeightedFilter.ts": () => Promise.resolve().then(() => (init_WeightedFilter(), WeightedFilter_exports)),
|
|
@@ -5192,12 +5278,14 @@ __export(navigators_exports, {
|
|
|
5192
5278
|
NavigatorRole: () => NavigatorRole,
|
|
5193
5279
|
NavigatorRoles: () => NavigatorRoles,
|
|
5194
5280
|
Navigators: () => Navigators,
|
|
5281
|
+
clearSrsBacklogDebug: () => clearSrsBacklogDebug,
|
|
5195
5282
|
diversityRerank: () => diversityRerank,
|
|
5196
5283
|
getActivePipeline: () => getActivePipeline,
|
|
5197
5284
|
getCardOrigin: () => getCardOrigin,
|
|
5198
5285
|
getRegisteredNavigator: () => getRegisteredNavigator,
|
|
5199
5286
|
getRegisteredNavigatorNames: () => getRegisteredNavigatorNames,
|
|
5200
5287
|
getRegisteredNavigatorRole: () => getRegisteredNavigatorRole,
|
|
5288
|
+
getSrsBacklogDebug: () => getSrsBacklogDebug,
|
|
5201
5289
|
hasRegisteredNavigator: () => hasRegisteredNavigator,
|
|
5202
5290
|
initializeNavigatorRegistry: () => initializeNavigatorRegistry,
|
|
5203
5291
|
isFilter: () => isFilter,
|
|
@@ -5279,6 +5367,7 @@ var init_navigators = __esm({
|
|
|
5279
5367
|
"use strict";
|
|
5280
5368
|
init_diversityRerank();
|
|
5281
5369
|
init_PipelineDebugger();
|
|
5370
|
+
init_SrsDebugger();
|
|
5282
5371
|
init_logger();
|
|
5283
5372
|
init_();
|
|
5284
5373
|
init_2();
|
|
@@ -8313,6 +8402,7 @@ export {
|
|
|
8313
8402
|
aggregateOutcomesForGradient,
|
|
8314
8403
|
areQuestionRecords,
|
|
8315
8404
|
buildStrategyStateId,
|
|
8405
|
+
clearSrsBacklogDebug,
|
|
8316
8406
|
computeDeviation,
|
|
8317
8407
|
computeEffectiveWeight,
|
|
8318
8408
|
computeOutcomeSignal,
|
|
@@ -8328,6 +8418,7 @@ export {
|
|
|
8328
8418
|
getRegisteredNavigator,
|
|
8329
8419
|
getRegisteredNavigatorNames,
|
|
8330
8420
|
getRegisteredNavigatorRole,
|
|
8421
|
+
getSrsBacklogDebug,
|
|
8331
8422
|
getStudySource,
|
|
8332
8423
|
hasRegisteredNavigator,
|
|
8333
8424
|
importParsedCards,
|