@cachly-dev/mcp-server 0.10.123 → 0.10.125

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 (85) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +7 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/src/aussetzer.d.ts +67 -0
  5. package/dist/src/aussetzer.js +82 -0
  6. package/dist/src/aussetzer.js.map +1 -0
  7. package/dist/src/autor-abzeichen.d.ts +41 -0
  8. package/dist/src/autor-abzeichen.js +56 -0
  9. package/dist/src/autor-abzeichen.js.map +1 -0
  10. package/dist/src/autor.d.ts +101 -0
  11. package/dist/src/autor.js +136 -0
  12. package/dist/src/autor.js.map +1 -0
  13. package/dist/src/bauabdruck-daten.generiert.json +5 -0
  14. package/dist/src/bauabdruck.d.ts +38 -0
  15. package/dist/src/bauabdruck.js +93 -0
  16. package/dist/src/bauabdruck.js.map +1 -0
  17. package/dist/src/bedeutung.d.ts +175 -0
  18. package/dist/src/bedeutung.js +254 -0
  19. package/dist/src/bedeutung.js.map +1 -0
  20. package/dist/src/brain-export.d.ts +24 -0
  21. package/dist/src/brain-export.js +31 -1
  22. package/dist/src/brain-export.js.map +1 -1
  23. package/dist/src/deutsch.d.ts +98 -0
  24. package/dist/src/deutsch.js +223 -0
  25. package/dist/src/deutsch.js.map +1 -0
  26. package/dist/src/eingaenge-nachruesten.d.ts +41 -0
  27. package/dist/src/eingaenge-nachruesten.js +290 -0
  28. package/dist/src/eingaenge-nachruesten.js.map +1 -0
  29. package/dist/src/eingaenge.d.ts +135 -0
  30. package/dist/src/eingaenge.js +228 -0
  31. package/dist/src/eingaenge.js.map +1 -0
  32. package/dist/src/geliefert.d.ts +63 -0
  33. package/dist/src/geliefert.js +114 -0
  34. package/dist/src/geliefert.js.map +1 -0
  35. package/dist/src/handlers/advanced.js +7 -3
  36. package/dist/src/handlers/advanced.js.map +1 -1
  37. package/dist/src/handlers/brain.d.ts +19 -0
  38. package/dist/src/handlers/brain.js +492 -48
  39. package/dist/src/handlers/brain.js.map +1 -1
  40. package/dist/src/handlers/instances.d.ts +24 -0
  41. package/dist/src/handlers/instances.js +49 -1
  42. package/dist/src/handlers/instances.js.map +1 -1
  43. package/dist/src/handlers/team.js +105 -0
  44. package/dist/src/handlers/team.js.map +1 -1
  45. package/dist/src/index.d.ts +20 -0
  46. package/dist/src/index.js +282 -36
  47. package/dist/src/index.js.map +1 -1
  48. package/dist/src/lesson-preview.d.ts +81 -0
  49. package/dist/src/lesson-preview.js +133 -0
  50. package/dist/src/lesson-preview.js.map +1 -0
  51. package/dist/src/rangfolge.d.ts +169 -0
  52. package/dist/src/rangfolge.js +214 -0
  53. package/dist/src/rangfolge.js.map +1 -0
  54. package/dist/src/raumkorrektur.d.ts +100 -0
  55. package/dist/src/raumkorrektur.js +197 -0
  56. package/dist/src/raumkorrektur.js.map +1 -0
  57. package/dist/src/recall-tiefe.d.ts +48 -0
  58. package/dist/src/recall-tiefe.js +42 -0
  59. package/dist/src/recall-tiefe.js.map +1 -0
  60. package/dist/src/rerank.d.ts +0 -14
  61. package/dist/src/rerank.js +39 -2
  62. package/dist/src/rerank.js.map +1 -1
  63. package/dist/src/search.d.ts +56 -17
  64. package/dist/src/search.js +335 -73
  65. package/dist/src/search.js.map +1 -1
  66. package/dist/src/seltenheitsbestand.d.ts +53 -0
  67. package/dist/src/seltenheitsbestand.js +92 -0
  68. package/dist/src/seltenheitsbestand.js.map +1 -0
  69. package/dist/src/spuren.d.ts +97 -0
  70. package/dist/src/spuren.js +150 -0
  71. package/dist/src/spuren.js.map +1 -0
  72. package/dist/src/tools.js +1 -1
  73. package/dist/src/tools.js.map +1 -1
  74. package/dist/src/vorspann.d.ts +73 -0
  75. package/dist/src/vorspann.js +146 -0
  76. package/dist/src/vorspann.js.map +1 -0
  77. package/dist/src/werkzeug-nutzung.d.ts +62 -0
  78. package/dist/src/werkzeug-nutzung.js +72 -0
  79. package/dist/src/werkzeug-nutzung.js.map +1 -0
  80. package/dist/src/wertbeitrag.d.ts +57 -0
  81. package/dist/src/wertbeitrag.js +73 -0
  82. package/dist/src/wertbeitrag.js.map +1 -0
  83. package/glama.json +1 -1
  84. package/package.json +12 -4
  85. package/server.json +2 -2
@@ -0,0 +1,81 @@
1
+ /**
2
+ * lesson-preview — one place that decides how a lesson is shown in a briefing.
3
+ *
4
+ * WHY THIS EXISTS (measured 2026-08-16, real incident):
5
+ * A session briefing showed this lesson line:
6
+ *
7
+ * ✅🔴 `node4:einrichtung-contabo-und-fallen` — node-4 (Contabo, 169.58.175.157,
8
+ * Lauterbourg FR, 12 Kerne / 48 GB / 400 GB, 25,29 EUR/Monat) eingeri
9
+ *
10
+ * The reader needed one thing from that lesson: the WireGuard address of the
11
+ * machine. It sits at character 323 of `what_worked`. The preview cut at 100.
12
+ * Worse, the lesson's `what_failed` field held the literal sentence "always read
13
+ * `wg show wg0 allowed-ips`" — and no briefing surface renders `what_failed` for
14
+ * a lesson whose outcome is "success". The lesson was displayed, at the right
15
+ * moment, and the exact mistake it warns about happened anyway.
16
+ *
17
+ * The fix is not "show more prose". The two most actionable fields of that
18
+ * lesson were already short and structured:
19
+ *
20
+ * commands: ["wg show wg0 allowed-ips", "ssh -i ~/.ssh/... -p 2222 root@..."]
21
+ * file_paths: ["/etc/wireguard/wg0.conf", ...]
22
+ *
23
+ * ~15 tokens that answer the question, thrown away in favour of 100 characters
24
+ * of preamble. So a preview renders three things now: trimmed prose, a facts
25
+ * tail drawn from the structured fields, and — for critical lessons — the
26
+ * warning, regardless of outcome.
27
+ *
28
+ * This helps the EXISTING corpus. A writing rule ("put the fact first") only
29
+ * improves lessons written after it; reading structured fields improves every
30
+ * lesson ever stored.
31
+ */
32
+ export interface PreviewLesson {
33
+ topic: string;
34
+ outcome?: string;
35
+ severity?: string;
36
+ what_worked?: string;
37
+ what_failed?: string;
38
+ commands?: string[];
39
+ file_paths?: string[];
40
+ }
41
+ export interface PreviewOptions {
42
+ /** Prose budget for what_worked. Default 100 — the historical briefing value. */
43
+ maxChars?: number;
44
+ /** Render the commands/paths tail. Default true. */
45
+ facts?: boolean;
46
+ /** Render the warning line for critical lessons. Default true. */
47
+ warning?: boolean;
48
+ /** How many commands + paths to show. Default 2 each. */
49
+ maxFacts?: number;
50
+ /** Per-fact character cap. Default 64. */
51
+ factChars?: number;
52
+ /** Character cap for the warning line. Default 110. */
53
+ warningChars?: number;
54
+ /** Indent for continuation lines. Default 5 spaces (matches briefing lists). */
55
+ indent?: string;
56
+ }
57
+ /**
58
+ * Cut to `max` characters, preferring a word boundary, and mark the cut.
59
+ * The marker matters: without it a truncated line reads like a complete one,
60
+ * and the reader never learns there is more to fetch.
61
+ */
62
+ export declare function trimTo(text: string, max: number): string;
63
+ /**
64
+ * Facts worth showing even when the prose is cut: commands first (they are
65
+ * directly runnable), then file paths. Deduplicated, order preserved.
66
+ */
67
+ export declare function factsOf(l: PreviewLesson, maxFacts: number, factChars: number): string[];
68
+ /**
69
+ * The warning is the single most fear-inducing, mistake-preventing part of a
70
+ * lesson — and it was invisible whenever `outcome` was "success". Show it for
71
+ * critical lessons no matter how the lesson ended.
72
+ */
73
+ export declare function warningOf(l: PreviewLesson, max: number): string | null;
74
+ /**
75
+ * Render the body of one briefing entry: prose, then facts, then warning.
76
+ * Returns lines WITHOUT the caller's bullet/emoji prefix — the caller owns the
77
+ * first line's prefix, this owns everything after the em dash.
78
+ */
79
+ export declare function lessonPreviewLines(l: PreviewLesson, opts?: PreviewOptions): string[];
80
+ /** Convenience: the same content as a single newline-joined string. */
81
+ export declare function lessonPreview(l: PreviewLesson, opts?: PreviewOptions): string;
@@ -0,0 +1,133 @@
1
+ /**
2
+ * lesson-preview — one place that decides how a lesson is shown in a briefing.
3
+ *
4
+ * WHY THIS EXISTS (measured 2026-08-16, real incident):
5
+ * A session briefing showed this lesson line:
6
+ *
7
+ * ✅🔴 `node4:einrichtung-contabo-und-fallen` — node-4 (Contabo, 169.58.175.157,
8
+ * Lauterbourg FR, 12 Kerne / 48 GB / 400 GB, 25,29 EUR/Monat) eingeri
9
+ *
10
+ * The reader needed one thing from that lesson: the WireGuard address of the
11
+ * machine. It sits at character 323 of `what_worked`. The preview cut at 100.
12
+ * Worse, the lesson's `what_failed` field held the literal sentence "always read
13
+ * `wg show wg0 allowed-ips`" — and no briefing surface renders `what_failed` for
14
+ * a lesson whose outcome is "success". The lesson was displayed, at the right
15
+ * moment, and the exact mistake it warns about happened anyway.
16
+ *
17
+ * The fix is not "show more prose". The two most actionable fields of that
18
+ * lesson were already short and structured:
19
+ *
20
+ * commands: ["wg show wg0 allowed-ips", "ssh -i ~/.ssh/... -p 2222 root@..."]
21
+ * file_paths: ["/etc/wireguard/wg0.conf", ...]
22
+ *
23
+ * ~15 tokens that answer the question, thrown away in favour of 100 characters
24
+ * of preamble. So a preview renders three things now: trimmed prose, a facts
25
+ * tail drawn from the structured fields, and — for critical lessons — the
26
+ * warning, regardless of outcome.
27
+ *
28
+ * This helps the EXISTING corpus. A writing rule ("put the fact first") only
29
+ * improves lessons written after it; reading structured fields improves every
30
+ * lesson ever stored.
31
+ */
32
+ const DEFAULTS = {
33
+ maxChars: 100,
34
+ facts: true,
35
+ warning: true,
36
+ maxFacts: 2,
37
+ factChars: 64,
38
+ warningChars: 110,
39
+ indent: ' ',
40
+ };
41
+ /** Collapse whitespace so a multi-line field cannot break list layout. */
42
+ function flat(s) {
43
+ return String(s ?? '').replace(/\s+/g, ' ').trim();
44
+ }
45
+ /**
46
+ * Cut to `max` characters, preferring a word boundary, and mark the cut.
47
+ * The marker matters: without it a truncated line reads like a complete one,
48
+ * and the reader never learns there is more to fetch.
49
+ */
50
+ export function trimTo(text, max) {
51
+ const s = flat(text);
52
+ if (max <= 0)
53
+ return '';
54
+ if (s.length <= max)
55
+ return s;
56
+ const hard = s.slice(0, max);
57
+ const space = hard.lastIndexOf(' ');
58
+ // Only honour the word boundary if it does not throw away most of the budget.
59
+ const body = space > max * 0.6 ? hard.slice(0, space) : hard;
60
+ return `${body.replace(/[\s,;:.-]+$/, '')}…`;
61
+ }
62
+ /**
63
+ * Facts worth showing even when the prose is cut: commands first (they are
64
+ * directly runnable), then file paths. Deduplicated, order preserved.
65
+ */
66
+ export function factsOf(l, maxFacts, factChars) {
67
+ const out = [];
68
+ const seen = new Set();
69
+ const take = (raw, prefix, limit) => {
70
+ let n = 0;
71
+ for (const item of Array.isArray(raw) ? raw : []) {
72
+ if (n >= limit)
73
+ break;
74
+ const v = flat(item);
75
+ if (!v)
76
+ continue;
77
+ const key = `${prefix}${v}`;
78
+ if (seen.has(key))
79
+ continue;
80
+ seen.add(key);
81
+ out.push(`${prefix}${trimTo(v, factChars)}`);
82
+ n++;
83
+ }
84
+ };
85
+ take(l.commands, '⌘ ', maxFacts);
86
+ take(l.file_paths, '▸ ', maxFacts);
87
+ return out;
88
+ }
89
+ /**
90
+ * The warning is the single most fear-inducing, mistake-preventing part of a
91
+ * lesson — and it was invisible whenever `outcome` was "success". Show it for
92
+ * critical lessons no matter how the lesson ended.
93
+ */
94
+ export function warningOf(l, max) {
95
+ const w = flat(l.what_failed);
96
+ if (!w)
97
+ return null;
98
+ const isCritical = String(l.severity ?? '').toLowerCase() === 'critical';
99
+ const failed = l.outcome === 'failure' || l.outcome === 'partial';
100
+ if (!isCritical && !failed)
101
+ return null;
102
+ return trimTo(w, max);
103
+ }
104
+ /**
105
+ * Render the body of one briefing entry: prose, then facts, then warning.
106
+ * Returns lines WITHOUT the caller's bullet/emoji prefix — the caller owns the
107
+ * first line's prefix, this owns everything after the em dash.
108
+ */
109
+ export function lessonPreviewLines(l, opts = {}) {
110
+ const o = { ...DEFAULTS, ...opts };
111
+ const lines = [];
112
+ const prose = trimTo(l.what_worked ?? '', o.maxChars);
113
+ if (prose)
114
+ lines.push(prose);
115
+ if (o.warning) {
116
+ const w = warningOf(l, o.warningChars);
117
+ if (w)
118
+ lines.push(`${o.indent}⚠️ ${w}`);
119
+ }
120
+ if (o.facts) {
121
+ const f = factsOf(l, o.maxFacts, o.factChars);
122
+ // One line, not one per fact: a briefing lists many lessons, and a
123
+ // four-line block per lesson would push the interesting ones off screen.
124
+ if (f.length)
125
+ lines.push(`${o.indent}${f.join(' ')}`);
126
+ }
127
+ return lines;
128
+ }
129
+ /** Convenience: the same content as a single newline-joined string. */
130
+ export function lessonPreview(l, opts = {}) {
131
+ return lessonPreviewLines(l, opts).join('\n');
132
+ }
133
+ //# sourceMappingURL=lesson-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lesson-preview.js","sourceRoot":"","sources":["../../src/lesson-preview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Der zusammengesetzte Sortierer.
3
+ *
4
+ * ── Was hier drinsteckt, und was NICHT ──────────────────────────────────────
5
+ *
6
+ * Am 19.08.2026 wurden an 499 echten Lektionen mit 100 Fragen ein Dutzend
7
+ * Verfahren durchgemessen. Die meisten haben nichts gebracht. Sie stehen hier,
8
+ * damit sie niemand ein zweites Mal baut:
9
+ *
10
+ * Symptom-Sicht (what_failed als eigener Vektor) 17 % statt 40 % — das Feld
11
+ * beschreibt bei uns nicht das Symptom, sondern was vergeblich versucht wurde
12
+ * Schwerpunkt abziehen 41 % — im Rauschen
13
+ * Hauptrichtungen entfernen (1, 3, 6 Stueck) 37–41 % — im Rauschen
14
+ * Nabenabzug (CSLS-artig) 41 % — im Rauschen
15
+ * Text in Stuecke schneiden nicht gebaut: gemessen deckt
16
+ * das beste Stueck genauso viel ab wie der ganze Text (Verhaeltnis 1,00),
17
+ * und es liegt bei 86 von 96 Fragen ohnehin am Anfang
18
+ *
19
+ * Was BLEIBT, sind vier Bestandteile — kreuzweise geprueft, also auf der einen
20
+ * Haelfte der Fragen eingestellt und auf der anderen gemessen, in beide
21
+ * Richtungen:
22
+ *
23
+ * P@1 MRR
24
+ * nur Bedeutung 40 % 51,3 %
25
+ * zusammengesetzt 51 % 57,0 %
26
+ *
27
+ * ── Die vier Bestandteile ───────────────────────────────────────────────────
28
+ *
29
+ * 1. NAEHE ZUM GANZEN TEXT (Sicht A). Der Grundstock.
30
+ *
31
+ * 2. NAEHE ZUM THEMENNAMEN (Sicht C). Der Name ist kurz wie eine Frage — der
32
+ * Vergleich ist damit symmetrisch, waehrend eine 60-Zeichen-Frage gegen
33
+ * 1376 Zeichen Text es nicht ist. Allein liefert diese Sicht nur 26 %, im
34
+ * Verbund traegt sie verlaesslich (Gewicht 0,6 in beiden Richtungen).
35
+ *
36
+ * 3. RUECKKOPPLUNG. Die ersten drei Treffer sind meistens ungefaehr richtig.
37
+ * Ihre Vektoren werden zu einem Viertel unter die Frage gemischt, dann wird
38
+ * erneut verglichen. Kostet nichts — keine neue Einbettung, nur eine
39
+ * Mittelung vorhandener Zahlen.
40
+ *
41
+ * 4. SELTENHEITS-UEBERLAPPUNG. Welcher Anteil der SELTENEN Fragewoerter kommt
42
+ * im Text vor. Ohne Laengennormierung, ohne unscharfe Treffer, ohne
43
+ * Bigramme.
44
+ *
45
+ * Das ist der unbequeme Befund: dieses eine Verhaeltnis bekam beim Einstellen
46
+ * das Gewicht 1,0 bis 1,6 — unser ausgefeiltes BM25 mit Laengennormierung,
47
+ * Bigramm-Naehe, unscharfen Treffern und Frischebonus bekam NULL. Nicht weil
48
+ * Woerter nichts taugen, sondern weil das ganze Beiwerk beim Sortieren
49
+ * daneben misst.
50
+ *
51
+ * ── Warum innerhalb des Topfes normiert wird ────────────────────────────────
52
+ *
53
+ * Ueber den ganzen Bestand liegen alle Aehnlichkeiten zwischen 0,42 und 0,61 —
54
+ * ein sehr schmales Band, weil alle Vektoren eine gemeinsame Grundrichtung
55
+ * teilen (gemessen: 69,8 Prozent). Unter fuenfzig Kandidaten spreizt eine
56
+ * Normierung auf 0 bis 1 genau die Unterschiede auf, um die es geht. Das ist
57
+ * dasselbe Ziel wie beim Schwerpunkt-Abziehen — nur dort, wo es wirkt.
58
+ */
59
+ /** Wörter eines Textes, umlautfrei, ohne Kurzwörter. */
60
+ export declare function inhaltsWoerter(text: string): Set<string>;
61
+ /**
62
+ * Es gibt hier KEINE Stammbildung — und das ist gemessen, nicht vergessen.
63
+ *
64
+ * Naheliegend wäre, `Abhaengigkeiten` und `Abhaengigkeit` auf einen Nenner zu
65
+ * bringen. Drei Varianten wurden am 19.08.2026 an 499 Lektionen mit 100 Fragen
66
+ * kreuzweise durchgemessen:
67
+ *
68
+ * ohne Stammbildung P@1 50 % MRR 56,4 %
69
+ * erste 6 Zeichen P@1 47 % MRR 54,7 %
70
+ * erste 8 Zeichen P@1 47 % MRR 54,7 %
71
+ *
72
+ * Jede Form von Kürzen kostet drei Punkte. Der Grund liegt daran, was diese
73
+ * Suche trägt: seltene Fachwörter. `fail2ban`, `stampede`, `timestamptz`,
74
+ * `keycloak` entscheiden eine Frage praktisch allein — und jede Verschmelzung
75
+ * verwischt genau sie. `container` und `contains` werden zu demselben Wort,
76
+ * und aus zwei seltenen wird ein häufiges.
77
+ *
78
+ * Beugung einzufangen lohnt sich also nur, wo die häufigen Wörter zählen. Hier
79
+ * zählen die seltenen.
80
+ *
81
+ * (Die Wortform-Behandlung in deutsch.ts bleibt davon unberührt — sie wirkt im
82
+ * Wortabgleich, der die Vorauswahl macht, nicht in dieser Bewertung.)
83
+ */
84
+ export declare function grobStamm(w: string): string;
85
+ /**
86
+ * Die Seltenheit jedes Wortes im Bestand — einmal berechnet, oft benutzt.
87
+ *
88
+ * Trifft eine Frage das Wort "nicht", sagt das nichts. Trifft sie "fail2ban",
89
+ * ist die Sache praktisch entschieden. Ohne diese Gewichtung sind beide gleich
90
+ * viel wert.
91
+ */
92
+ export declare class Seltenheit {
93
+ private df;
94
+ private anzahl;
95
+ /** @param texte je ein Text pro Datensatz */
96
+ constructor(texte: string[]);
97
+ wert(wort: string): number;
98
+ /**
99
+ * Welcher Anteil der seltenen Fragewörter kommt im Text vor.
100
+ *
101
+ * Der Nenner ist die Summe über ALLE Fragewörter — ein fehlendes seltenes
102
+ * Wort zieht damit den Wert herunter. Fehlende Belege zählen also mit, nicht
103
+ * nur vorhandene.
104
+ */
105
+ deckung(frageWoerter: Set<string>, textWoerter: Set<string>): number;
106
+ }
107
+ /** Auf 0 bis 1 spreizen — innerhalb des Topfes, nicht über den Bestand. */
108
+ export declare function spreizeImTopf(werte: number[]): number[];
109
+ /**
110
+ * Die Frage mit ihren besten Treffern anreichern.
111
+ *
112
+ * Die Frage benutzt Alltagsworte, die Lektionen Fachworte. Die ersten Treffer
113
+ * schlagen diese Brücke: ihre Vektoren zeigen dorthin, wo die Antwort liegt.
114
+ *
115
+ * Das Risiko ist bekannt und begrenzt: sind die ersten Treffer falsch, zieht
116
+ * die Anreicherung in die falsche Richtung. Deshalb bleibt die ursprüngliche
117
+ * Frage mit drei Vierteln stehen — gemessen war das besser als jede stärkere
118
+ * Beimischung.
119
+ */
120
+ export declare function reichereAn(frage: number[], besteTreffer: number[][], anteil?: number): number[];
121
+ /**
122
+ * Die Gewichte.
123
+ *
124
+ * Kreuzweise ermittelt: auf der einen Hälfte der Fragen eingestellt, auf der
125
+ * anderen gemessen, in beide Richtungen. Die drei Werte hier waren in BEIDEN
126
+ * Richtungen stabil. Zwei weitere Merkmale — Überlappung mit dem Themennamen
127
+ * und Qualitätsmerkmale — schwankten zwischen den Richtungen und sind deshalb
128
+ * NICHT dabei: was nur in einer Hälfte hilft, ist eine Eigenschaft dieser
129
+ * Hälfte, keine des Verfahrens.
130
+ */
131
+ export declare const GEWICHTE: {
132
+ /** Nähe zum ganzen Text. Der Grundstock, deshalb 1. */
133
+ readonly text: 1;
134
+ /** Nähe zum Themennamen. In beiden Richtungen 0,6. */
135
+ readonly thema: 0.6;
136
+ /** Angereicherte Frage gegen den ganzen Text. In beiden Richtungen 0,3. */
137
+ readonly rueckkopplung: 0.3;
138
+ /** Anteil der seltenen Fragewörter im Text. 1,0 bis 1,6 — Mitte genommen. */
139
+ readonly seltenheit: 1.3;
140
+ };
141
+ export interface Bewertbar {
142
+ /** Kosinus zur Sicht über den ganzen Text, oder -2 wenn kein Vektor da ist. */
143
+ naeheText: number;
144
+ /** Kosinus zur Sicht über den Themennamen. */
145
+ naeheThema: number;
146
+ /** Kosinus der angereicherten Frage zum ganzen Text. */
147
+ naeheRueckkopplung: number;
148
+ /** Anteil der seltenen Fragewörter, die im Text vorkommen. */
149
+ seltenheitsDeckung: number;
150
+ }
151
+ /**
152
+ * Punktzahl je Kandidat. Höher ist besser.
153
+ *
154
+ * Erwartet den GANZEN Topf auf einmal, weil die Normierung ihn braucht — eine
155
+ * Punktzahl für einen einzelnen Kandidaten gibt es nicht und kann es nicht
156
+ * geben.
157
+ */
158
+ export declare function bewerteTopf(topf: Bewertbar[], gewichte?: {
159
+ /** Nähe zum ganzen Text. Der Grundstock, deshalb 1. */
160
+ readonly text: 1;
161
+ /** Nähe zum Themennamen. In beiden Richtungen 0,6. */
162
+ readonly thema: 0.6;
163
+ /** Angereicherte Frage gegen den ganzen Text. In beiden Richtungen 0,3. */
164
+ readonly rueckkopplung: 0.3;
165
+ /** Anteil der seltenen Fragewörter im Text. 1,0 bis 1,6 — Mitte genommen. */
166
+ readonly seltenheit: 1.3;
167
+ }): number[];
168
+ /** Bequemlichkeit: Kosinus mit Lücken-Behandlung. */
169
+ export declare function naeheOderLuecke(frage: number[] | null, vektor: number[] | null | undefined): number;
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Der zusammengesetzte Sortierer.
3
+ *
4
+ * ── Was hier drinsteckt, und was NICHT ──────────────────────────────────────
5
+ *
6
+ * Am 19.08.2026 wurden an 499 echten Lektionen mit 100 Fragen ein Dutzend
7
+ * Verfahren durchgemessen. Die meisten haben nichts gebracht. Sie stehen hier,
8
+ * damit sie niemand ein zweites Mal baut:
9
+ *
10
+ * Symptom-Sicht (what_failed als eigener Vektor) 17 % statt 40 % — das Feld
11
+ * beschreibt bei uns nicht das Symptom, sondern was vergeblich versucht wurde
12
+ * Schwerpunkt abziehen 41 % — im Rauschen
13
+ * Hauptrichtungen entfernen (1, 3, 6 Stueck) 37–41 % — im Rauschen
14
+ * Nabenabzug (CSLS-artig) 41 % — im Rauschen
15
+ * Text in Stuecke schneiden nicht gebaut: gemessen deckt
16
+ * das beste Stueck genauso viel ab wie der ganze Text (Verhaeltnis 1,00),
17
+ * und es liegt bei 86 von 96 Fragen ohnehin am Anfang
18
+ *
19
+ * Was BLEIBT, sind vier Bestandteile — kreuzweise geprueft, also auf der einen
20
+ * Haelfte der Fragen eingestellt und auf der anderen gemessen, in beide
21
+ * Richtungen:
22
+ *
23
+ * P@1 MRR
24
+ * nur Bedeutung 40 % 51,3 %
25
+ * zusammengesetzt 51 % 57,0 %
26
+ *
27
+ * ── Die vier Bestandteile ───────────────────────────────────────────────────
28
+ *
29
+ * 1. NAEHE ZUM GANZEN TEXT (Sicht A). Der Grundstock.
30
+ *
31
+ * 2. NAEHE ZUM THEMENNAMEN (Sicht C). Der Name ist kurz wie eine Frage — der
32
+ * Vergleich ist damit symmetrisch, waehrend eine 60-Zeichen-Frage gegen
33
+ * 1376 Zeichen Text es nicht ist. Allein liefert diese Sicht nur 26 %, im
34
+ * Verbund traegt sie verlaesslich (Gewicht 0,6 in beiden Richtungen).
35
+ *
36
+ * 3. RUECKKOPPLUNG. Die ersten drei Treffer sind meistens ungefaehr richtig.
37
+ * Ihre Vektoren werden zu einem Viertel unter die Frage gemischt, dann wird
38
+ * erneut verglichen. Kostet nichts — keine neue Einbettung, nur eine
39
+ * Mittelung vorhandener Zahlen.
40
+ *
41
+ * 4. SELTENHEITS-UEBERLAPPUNG. Welcher Anteil der SELTENEN Fragewoerter kommt
42
+ * im Text vor. Ohne Laengennormierung, ohne unscharfe Treffer, ohne
43
+ * Bigramme.
44
+ *
45
+ * Das ist der unbequeme Befund: dieses eine Verhaeltnis bekam beim Einstellen
46
+ * das Gewicht 1,0 bis 1,6 — unser ausgefeiltes BM25 mit Laengennormierung,
47
+ * Bigramm-Naehe, unscharfen Treffern und Frischebonus bekam NULL. Nicht weil
48
+ * Woerter nichts taugen, sondern weil das ganze Beiwerk beim Sortieren
49
+ * daneben misst.
50
+ *
51
+ * ── Warum innerhalb des Topfes normiert wird ────────────────────────────────
52
+ *
53
+ * Ueber den ganzen Bestand liegen alle Aehnlichkeiten zwischen 0,42 und 0,61 —
54
+ * ein sehr schmales Band, weil alle Vektoren eine gemeinsame Grundrichtung
55
+ * teilen (gemessen: 69,8 Prozent). Unter fuenfzig Kandidaten spreizt eine
56
+ * Normierung auf 0 bis 1 genau die Unterschiede auf, um die es geht. Das ist
57
+ * dasselbe Ziel wie beim Schwerpunkt-Abziehen — nur dort, wo es wirkt.
58
+ */
59
+ import { kosinus } from './bedeutung.js';
60
+ /** Wörter eines Textes, umlautfrei, ohne Kurzwörter. */
61
+ export function inhaltsWoerter(text) {
62
+ return new Set(text.toLowerCase()
63
+ .replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue').replace(/ß/g, 'ss')
64
+ .split(/[^a-z0-9]+/)
65
+ .filter((w) => w.length > 3));
66
+ }
67
+ /**
68
+ * Es gibt hier KEINE Stammbildung — und das ist gemessen, nicht vergessen.
69
+ *
70
+ * Naheliegend wäre, `Abhaengigkeiten` und `Abhaengigkeit` auf einen Nenner zu
71
+ * bringen. Drei Varianten wurden am 19.08.2026 an 499 Lektionen mit 100 Fragen
72
+ * kreuzweise durchgemessen:
73
+ *
74
+ * ohne Stammbildung P@1 50 % MRR 56,4 %
75
+ * erste 6 Zeichen P@1 47 % MRR 54,7 %
76
+ * erste 8 Zeichen P@1 47 % MRR 54,7 %
77
+ *
78
+ * Jede Form von Kürzen kostet drei Punkte. Der Grund liegt daran, was diese
79
+ * Suche trägt: seltene Fachwörter. `fail2ban`, `stampede`, `timestamptz`,
80
+ * `keycloak` entscheiden eine Frage praktisch allein — und jede Verschmelzung
81
+ * verwischt genau sie. `container` und `contains` werden zu demselben Wort,
82
+ * und aus zwei seltenen wird ein häufiges.
83
+ *
84
+ * Beugung einzufangen lohnt sich also nur, wo die häufigen Wörter zählen. Hier
85
+ * zählen die seltenen.
86
+ *
87
+ * (Die Wortform-Behandlung in deutsch.ts bleibt davon unberührt — sie wirkt im
88
+ * Wortabgleich, der die Vorauswahl macht, nicht in dieser Bewertung.)
89
+ */
90
+ export function grobStamm(w) {
91
+ return w;
92
+ }
93
+ /**
94
+ * Die Seltenheit jedes Wortes im Bestand — einmal berechnet, oft benutzt.
95
+ *
96
+ * Trifft eine Frage das Wort "nicht", sagt das nichts. Trifft sie "fail2ban",
97
+ * ist die Sache praktisch entschieden. Ohne diese Gewichtung sind beide gleich
98
+ * viel wert.
99
+ */
100
+ export class Seltenheit {
101
+ df = new Map();
102
+ anzahl = 0;
103
+ /** @param texte je ein Text pro Datensatz */
104
+ constructor(texte) {
105
+ this.anzahl = texte.length;
106
+ for (const t of texte) {
107
+ for (const w of inhaltsWoerter(t))
108
+ this.df.set(grobStamm(w), (this.df.get(grobStamm(w)) ?? 0) + 1);
109
+ }
110
+ }
111
+ wert(wort) {
112
+ return Math.log((this.anzahl + 1) / ((this.df.get(grobStamm(wort)) ?? 0) + 1));
113
+ }
114
+ /**
115
+ * Welcher Anteil der seltenen Fragewörter kommt im Text vor.
116
+ *
117
+ * Der Nenner ist die Summe über ALLE Fragewörter — ein fehlendes seltenes
118
+ * Wort zieht damit den Wert herunter. Fehlende Belege zählen also mit, nicht
119
+ * nur vorhandene.
120
+ */
121
+ deckung(frageWoerter, textWoerter) {
122
+ let gesamt = 0;
123
+ let getroffen = 0;
124
+ for (const w of frageWoerter) {
125
+ const g = this.wert(w);
126
+ gesamt += g;
127
+ if (textWoerter.has(grobStamm(w)))
128
+ getroffen += g;
129
+ }
130
+ return gesamt > 0 ? getroffen / gesamt : 0;
131
+ }
132
+ }
133
+ /** Auf 0 bis 1 spreizen — innerhalb des Topfes, nicht über den Bestand. */
134
+ export function spreizeImTopf(werte) {
135
+ const gueltig = werte.filter((x) => Number.isFinite(x) && x > -2);
136
+ if (gueltig.length === 0)
137
+ return werte.map(() => 0);
138
+ let min = Infinity;
139
+ let max = -Infinity;
140
+ for (const x of gueltig) {
141
+ if (x < min)
142
+ min = x;
143
+ if (x > max)
144
+ max = x;
145
+ }
146
+ if (max === min)
147
+ return werte.map(() => 0.5);
148
+ return werte.map((x) => (x > -2 ? (x - min) / (max - min) : 0));
149
+ }
150
+ /**
151
+ * Die Frage mit ihren besten Treffern anreichern.
152
+ *
153
+ * Die Frage benutzt Alltagsworte, die Lektionen Fachworte. Die ersten Treffer
154
+ * schlagen diese Brücke: ihre Vektoren zeigen dorthin, wo die Antwort liegt.
155
+ *
156
+ * Das Risiko ist bekannt und begrenzt: sind die ersten Treffer falsch, zieht
157
+ * die Anreicherung in die falsche Richtung. Deshalb bleibt die ursprüngliche
158
+ * Frage mit drei Vierteln stehen — gemessen war das besser als jede stärkere
159
+ * Beimischung.
160
+ */
161
+ export function reichereAn(frage, besteTreffer, anteil = 0.25) {
162
+ if (besteTreffer.length === 0)
163
+ return frage;
164
+ const d = frage.length;
165
+ const m = new Array(d).fill(0);
166
+ for (const v of besteTreffer) {
167
+ if (v.length !== d)
168
+ continue;
169
+ for (let i = 0; i < d; i++)
170
+ m[i] += v[i] / besteTreffer.length;
171
+ }
172
+ return frage.map((x, i) => (1 - anteil) * x + anteil * m[i]);
173
+ }
174
+ /**
175
+ * Die Gewichte.
176
+ *
177
+ * Kreuzweise ermittelt: auf der einen Hälfte der Fragen eingestellt, auf der
178
+ * anderen gemessen, in beide Richtungen. Die drei Werte hier waren in BEIDEN
179
+ * Richtungen stabil. Zwei weitere Merkmale — Überlappung mit dem Themennamen
180
+ * und Qualitätsmerkmale — schwankten zwischen den Richtungen und sind deshalb
181
+ * NICHT dabei: was nur in einer Hälfte hilft, ist eine Eigenschaft dieser
182
+ * Hälfte, keine des Verfahrens.
183
+ */
184
+ export const GEWICHTE = {
185
+ /** Nähe zum ganzen Text. Der Grundstock, deshalb 1. */
186
+ text: 1,
187
+ /** Nähe zum Themennamen. In beiden Richtungen 0,6. */
188
+ thema: 0.6,
189
+ /** Angereicherte Frage gegen den ganzen Text. In beiden Richtungen 0,3. */
190
+ rueckkopplung: 0.3,
191
+ /** Anteil der seltenen Fragewörter im Text. 1,0 bis 1,6 — Mitte genommen. */
192
+ seltenheit: 1.3,
193
+ };
194
+ /**
195
+ * Punktzahl je Kandidat. Höher ist besser.
196
+ *
197
+ * Erwartet den GANZEN Topf auf einmal, weil die Normierung ihn braucht — eine
198
+ * Punktzahl für einen einzelnen Kandidaten gibt es nicht und kann es nicht
199
+ * geben.
200
+ */
201
+ export function bewerteTopf(topf, gewichte = GEWICHTE) {
202
+ const t = spreizeImTopf(topf.map((k) => k.naeheText));
203
+ const th = spreizeImTopf(topf.map((k) => k.naeheThema));
204
+ const r = spreizeImTopf(topf.map((k) => k.naeheRueckkopplung));
205
+ return topf.map((k, i) => gewichte.text * t[i]
206
+ + gewichte.thema * th[i]
207
+ + gewichte.rueckkopplung * r[i]
208
+ + gewichte.seltenheit * k.seltenheitsDeckung);
209
+ }
210
+ /** Bequemlichkeit: Kosinus mit Lücken-Behandlung. */
211
+ export function naeheOderLuecke(frage, vektor) {
212
+ return frage && vektor && vektor.length > 0 ? kosinus(frage, vektor) : -2;
213
+ }
214
+ //# sourceMappingURL=rangfolge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rangfolge.js","sourceRoot":"","sources":["../../src/rangfolge.ts"],"names":[],"mappings":"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"}