Legacy: SkillPilot Lerncoach mit Startcode und Session-Token
Status: historische Architektur vom 19. Mai 2026; für keine Sprache aktueller Laufzeitvertrag.
Dieses Dokument bleibt als technische Rollback-Referenz erhalten. Der aktuelle mehrsprachige V1-Architektur ist die OpenAI-MCP-App mit OAuth- und 24h-Lernsession. Dabei transportiert ChatGPT den OAuth-Zugriff automatisch. Jeder ausdrückliche Start in SkillPilot erzeugt eine davon getrennte, absolut höchstens 24 Stunden gültige Lernsession, setzt sie automatisch in die vorbereitete Startnachricht ein und verlangt sie danach als Argument jedes fachlichen Tools. Die dauerhafte SkillPilot-ID erscheint nicht im Chat. Die Visible-Session-Architektur bleibt ein separater Custom-GPT-Rollbackpfad. Deutsch, Englisch und jede später unterstützte Interaktionssprache verwenden im Normalbetrieb dieselbe Major-versionierte App.
Dieses Dokument beschreibt ausschließlich den früheren Browser-first-Flow für den
Start des SkillPilot Lerncoachs in ChatGPT. Ziel war, dass Lernende auf
skillpilot.com starten, während ChatGPT nur kurzlebige Start- und
Session-Schlüssel sieht. Die dauerhafte SkillPilot-ID blieb im Browser und
serverseitig im SkillPilot-Backend.
Erhaltener Legacy-Implementierungsstand:
- Web-Start und relevante Kampagnenstarts erzeugen Startcodes ueber
/api/ui/learners/{skillpilotId}/chat-start. - Custom-GPT-Actions loesen Startcodes ueber
/api/ai/{lang}/chat-start/redeemein. - Neue GPT-Actions verwenden Session-Routen unter
/api/ai/{lang}/sessions/{chatSessionToken}/.... - Session-Routen geben
skillpilotId: nullzurueck. - Startcodes und Chat-Session-Tokens werden serverseitig nur gehasht gespeichert.
- Legacy-AI-Routen mit SkillPilot-ID bleiben vorerst als Kompatibilitaets- und Debug-Routen bestehen, werden aber nicht mehr im Custom-GPT-Schema beworben.
Zielbild
Der normale Einstieg ist immer:
skillpilot.com -> SkillPilot Backend -> SkillPilot Lerncoach (ChatGPT) -> SkillPilot Backend
Nicht vorgesehen fuer den normalen Launch:
SkillPilot Lerncoach -> neue SkillPilot-ID erzeugen -> User muss ID selbst sichern
Die SkillPilot-ID bleibt das dauerhafte Sicherheits- und Wiedererkennungsmerkmal eines Lernenden. Sie soll aber nicht in ChatGPT-URLs, ChatGPT-Prompts oder ChatGPT-Antworten transportiert werden.
Beteiligte Schluessel
SkillPilot-ID
Die SkillPilot-ID ist der dauerhafte Learner-Schluessel. Sie identifiziert den Lernstand im Backend.
Eigenschaften:
- langlebig
- im Browser lokal gespeichert
- optional lokal passwortverschluesselt als benannter Login gespeichert
- serverseitig in der Learner-Domain genutzt
- nicht fuer ChatGPT-URLs gedacht
- im normalen GPT-Flow nicht an ChatGPT auszugeben
Startcode
Der Startcode ist ein kurzlebiger Einmalcode, der vom Browser erzeugt bzw. beim Backend angefordert wird, um eine GPT-Session zu starten.
Eigenschaften:
- kurz und fuer Menschen lesbar, z. B.
SP-7KQ9-M2PA - einmalig einloesbar
- kurze Gueltigkeit, z. B. 5 Minuten
- serverseitig an eine SkillPilot-ID gebunden
- darf im ChatGPT-Startprompt und optional in der ChatGPT-URL stehen
- nach erfolgreichem Redeem ungueltig
Chat-Session-Token
Das Chat-Session-Token ist der Schluessel, mit dem der SkillPilot Lerncoach nach dem Startcode-Redeem weiterarbeitet.
Eigenschaften:
- zufaellig, lang und nicht sprechend, z. B.
sps_... - serverseitig an eine SkillPilot-ID gebunden
- zeitlich begrenzt, z. B. 24 Stunden oder bis explizit widerrufen
- kann pro GPT-Session separat erzeugt werden
- ersetzt die SkillPilot-ID in AI-Routen
- darf in GPT-internen Tool-Aufrufen verwendet werden
- soll nicht als dauerhafter User-Schluessel kommuniziert werden
Normaler Browser-first-Flow
- Der Lernende oeffnet
skillpilot.com. - Der Browser zeigt einen bekannten Login-Schritt:
- Wenn eine SkillPilot-ID vorhanden ist, wird sie verwendet.
- Wenn keine SkillPilot-ID vorhanden ist, kann der Lernende eine neue ID beim Backend erzeugen lassen.
- Wenn eine SkillPilot-ID lokal passwortverschluesselt gespeichert wurde, kann sie mit Name und Passwort geladen werden.
- Alternativ kann die SkillPilot-ID direkt eingegeben werden.
- Der Browser speichert die aktive SkillPilot-ID nur lokal fuer diese Browser-Session. Optional kann sie lokal passwortverschluesselt als benannter Login gesichert werden.
- Der Lernende waehlt eine Skill-Landschaft bzw. bestaetigt die vorhandene Auswahl. Diese Curriculum-Auswahl wird zur SkillPilot-ID gespeichert.
- Der Browser bereitet intern eine temporaere Browser-Session vor.
- Fuer den Start des SkillPilot Lerncoachs ruft der Browser das Backend auf, um einen eindeutigen Einmal-Startcode zu erzeugen.
- Das Backend erzeugt den Startcode, speichert ihn serverseitig gehasht und gibt ihn an den Browser zurueck.
- Der Browser oeffnet den SkillPilot Lerncoach mit einem Startprompt, der nur den Startcode enthaelt.
- Der SkillPilot Lerncoach ruft die Startcode-Redeem-Action auf.
- Das Backend loest den Startcode ein, erzeugt ein Chat-Session-Token und gibt dieses zusammen mit dem initialen Lernstand zurueck.
- Der SkillPilot Lerncoach verwendet ab dann nur noch das Chat-Session-Token fuer Backend-Actions.
Aus Nutzersicht sind sichtbar:
- Login: neue SkillPilot-ID erstellen, gespeicherten Login laden oder SkillPilot-ID eingeben.
- Curriculum: Skill-Landschaft auswaehlen.
- Start: Cockpit oeffnen oder SkillPilot Lerncoach mit Startcode starten.
Die technische Session-ID bleibt intern. Der Startcode fuer den SkillPilot Lerncoach wird erklaert, weil er sichtbar im ChatGPT-Startprompt landet.
Sequenz
Browser Backend SkillPilot Lerncoach
| | |
| GET skillpilot.com | |
|---------------------->| |
| | |
| localStorage: ID? | |
| | |
| POST /api/ui/learners | |
| falls keine ID | |
|---------------------->| |
|<----------------------| SkillPilot-ID |
| | |
| PUT curriculum | |
|---------------------->| |
| | |
| POST chat-start | |
|---------------------->| |
|<----------------------| Startcode |
| | |
| open ChatGPT prompt | |
|--------------------------------------------------->|
| | |
| | POST redeemStartCode |
| |<---------------------------|
| | prueft Code, erzeugt Token |
| |--------------------------->|
| | Chat-Session-Token + State |
| | |
| | GET/POST session actions |
| |<---------------------------|
| |--------------------------->|
API
UI- und AI-APIs sind getrennt: Der Browser darf mit der echten SkillPilot-ID arbeiten, der GPT nur mit Startcode und Chat-Session-Token.
UI: Startcode erzeugen
POST /api/ui/learners/{skillpilotId}/chat-start
Content-Type: application/json
Request:
{
"language": "de",
"client": "web",
"selectedCurriculum": "a0e13c56-c25f-4742-9272-3a1a603ee52e"
}
Response:
{
"startCode": "SP-7KQ9-M2PA",
"expiresAt": "2026-05-19T09:35:00Z",
"prompt": "Starte SkillPilot mit Startcode: SP-7KQ9-M2PA"
}
Der Browser kann daraus optional eine ChatGPT-URL bauen:
https://chatgpt.com/g/...skillpilot-gpt-deutsch?prompt=<url-encoded prompt>
Der Prompt-Link ist Komfort, nicht Sicherheitsanker. Im normalen Web-Flow wird der Startcode direkt ueber den ChatGPT-Prompt-Parameter uebergeben. Eine manuelle Copy-Ansicht ist nur als Diagnose- oder Fallback-Option noetig, falls ein Browser den Popup-/Prompt-Start blockiert.
AI: Startcode einloesen
POST /api/ai/{lang}/chat-start/redeem
Content-Type: application/json
Request:
{
"startCode": "SP-7KQ9-M2PA"
}
Response:
{
"chatSessionToken": "sps_3J4v...",
"expiresAt": "2026-05-20T09:30:00Z",
"state": {
"...": "initialer Learner-State ohne echte SkillPilot-ID"
}
}
Der Startcode darf danach nicht erneut einloesbar sein.
AI: Session-basierte Actions
Neue GPT-Actions sollen nicht mehr die SkillPilot-ID im Pfad verwenden.
Beispiele:
GET /api/ai/{lang}/sessions/{chatSessionToken}/state
POST /api/ai/{lang}/sessions/{chatSessionToken}/scope
POST /api/ai/{lang}/sessions/{chatSessionToken}/active-goal
POST /api/ai/{lang}/sessions/{chatSessionToken}/mastery
POST /api/ai/{lang}/sessions/{chatSessionToken}/curriculum
POST /api/ai/{lang}/sessions/{chatSessionToken}/personalization
POST /api/ai/{lang}/sessions/{chatSessionToken}/verified-recall/start
POST /api/ai/{lang}/sessions/{chatSessionToken}/verified-recall/answer
POST /api/ai/{lang}/sessions/{chatSessionToken}/verified-recall/result
Das Backend loest bei jeder Session-Action intern auf:
chatSessionToken -> SkillPilot-ID -> bestehende LearnerService-Logik
Sanitizing der AI-Responses
Wenn der SkillPilot Lerncoach session-basiert arbeitet, sollen AI-Responses die echte SkillPilot-ID nicht enthalten.
Aktuelle Response-Typen koennen intern weiterverwendet werden, muessen aber fuer AI-Session-Routen gesanitized werden:
skillpilotIdnicht ausgeben oder alsnullausgeben- keine Links mit
skillpilotIderzeugen - keine Prompttexte mit echter SkillPilot-ID erzeugen
- keine Fehlermeldung, die versehentlich die ID wiederholt
Wenn der GPT einen Schluessel fuer Folgeaufrufe braucht, ist das ausschliesslich das chatSessionToken.
Persistenzmodell
Startcode-Tabelle
Minimal benoetigte Felder:
code_hash
learner_skillpilot_id
issued_at
expires_at
redeemed_at
redeemed_session_id
client
language
Hinweise:
- Startcodes sollten gehasht gespeichert werden, nicht im Klartext.
- Ablauf und Einmaligkeit muessen atomar geprueft werden.
- Veraltete Startcodes koennen regelmaessig geloescht werden.
Chat-Session-Tabelle
Minimal benoetigte Felder:
token_hash
learner_skillpilot_id
started_at
expires_at
revoked_at
last_used_at
source_start_code_hash
language
Hinweise:
- Auch Session-Tokens sollten gehasht gespeichert werden.
- Das Token selbst wird nur einmal beim Erzeugen an den GPT zurueckgegeben.
- Backend-Logs duerfen Tokens nicht im Klartext ausgeben.
Gueltigkeitsregeln
Aktuelle Defaults fuer den Launch:
Startcode TTL: 5 Minuten
Startcode Nutzung: genau einmal
Chat-Session TTL: 24 Stunden
Chat-Session Nutzung: mehrfach bis Ablauf oder Widerruf
Bei jeder AI-Session-Action:
- Token syntaktisch validieren.
- Token-Hash suchen.
- Pruefen, ob nicht abgelaufen.
- Pruefen, ob nicht widerrufen.
last_used_ataktualisieren.- SkillPilot-ID intern fuer die bestehende Learner-Logik verwenden.
Fehlerfaelle
Startcode fehlt
GPT soll sagen:
Bitte starte SkillPilot ueber skillpilot.com. Dort wird dein Lernstand geladen und ein Startcode erzeugt.
Der GPT soll im normalen Flow keine neue SkillPilot-ID erzeugen.
Startcode abgelaufen
Backend:
410 Gone
GPT:
Der Startcode ist abgelaufen. Bitte oeffne skillpilot.com erneut und starte ChatGPT von dort.
Startcode wurde bereits benutzt
Backend:
409 Conflict
GPT:
Dieser Startcode wurde bereits verwendet. Bitte erzeuge auf skillpilot.com einen neuen Startcode.
Chat-Session-Token abgelaufen
Backend:
401 Unauthorized
GPT:
Die SkillPilot-Chat-Sitzung ist abgelaufen. Bitte starte erneut ueber skillpilot.com.
UX-Regeln
Die Web-Startseite soll nicht direkt zu ChatGPT springen, solange keine SkillPilot-ID im Browser vorhanden ist.
Empfohlener Ablauf:
- Login anzeigen.
- Drei Einstiegswege anbieten:
Neue SkillPilot-ID erstellenGespeicherten Login ladenSkillPilot-ID direkt eingeben- Optional:
Diesen Login auf diesem Geraet speichernmit Name und Passwort. Die SkillPilot-ID wird lokal verschluesselt; das Passwort wird nicht gespeichert. - Curriculum bzw. Startscope anzeigen.
- Buttons:
SkillPilot Lerncoach startenCockpit oeffnen- Beim Button
SkillPilot Lerncoach starten: - Startcode erzeugen
- ChatGPT mit Prompt-Parameter oeffnen
- bei Browserblockade eine klare Fehlermeldung anzeigen oder eine Diagnose-/Fallback-Ansicht anbieten
Der User soll die echte SkillPilot-ID im Normalfall nicht sehen muessen. Eine Diagnose- oder Exportansicht darf sie zeigen, muss aber klar als dauerhafter Schluessel gekennzeichnet sein.
Logout:
- beendet die aktive Browser-Session
- entfernt die aktive SkillPilot-ID aus dem normalen lokalen Session-Speicher
- entfernt nicht automatisch passwortverschluesselte gespeicherte Logins
- fuehrt zur Start-/Login-Oberflaeche zurueck
Lerncoach-Verhalten
Der SkillPilot Lerncoach soll:
- Startcodes erkennen
- bei Startcode zuerst
redeemStartCodeaufrufen - das erhaltene
chatSessionTokenfuer alle Folgeaktionen verwenden - nicht nach der echten SkillPilot-ID fragen
- keine SkillPilot-ID anzeigen, wenn sie nicht explizit fuer Diagnose/Support benoetigt wird
- bei fehlendem Startcode auf
skillpilot.comverweisen - nicht in den Voice Mode wechseln, solange Custom GPT Actions dort keine Function Calls ausfuehren
Legacy- und Migrationsstrategie
Bestehende AI-Routen mit SkillPilot-ID im Pfad koennen vorerst bestehen bleiben:
/api/ai/{lang}/learners/{skillpilotId}/...
Sie sollten aber fuer den normalen GPT-Flow nicht mehr beworben werden. Die Custom-GPT-OpenAPI-Spezifikation soll auf die neuen Session-Routen umgestellt werden.
Uebergang:
- Neue Startcode- und Session-Routen bauen.
- Web-Startseite auf Startcode umstellen.
- GPT-OpenAPI auf Session-Routen umstellen.
- GPT-Instruktionen aktualisieren.
- Alte SkillPilot-ID-Routen als Legacy/Debug belassen.
- Spaeter entscheiden, ob Legacy-Routen eingeschraenkt oder entfernt werden.
Designentscheidungen
- Chat-Session-Token lebt per Default 24 Stunden.
- Mehrere aktive Chat-Sessions pro Learner sind erlaubt.
chatSessionTokenwird in Custom-GPT-Routen als Pfadparameter verwendet, weil ChatGPT Actions damit stabil umgehen. Serverlogs duerfen Tokens nicht im Klartext speichern oder ausgeben.- AI-Session-Responses enthalten
skillpilotId: null, damit vorhandene DTOs kompatibel bleiben. - Ein Startcode darf optional ein ausgewaehltes Curriculum setzen, muss es aber nicht.
Noch offen fuer spaetere Haertung:
- Chat-Sessions im Cockpit sichtbar und widerrufbar machen.
- Regelmaessigen Cleanup fuer abgelaufene Startcodes und Sessions einbauen.
- Optional pruefen, ob Session-Tokens langfristig besser ueber Header statt Pfad laufen koennen.
Implementierungsstand
Umgesetzt:
- Datenmodell und Liquibase-Migration fuer Startcodes und Chat-Sessions.
- Service fuer Code-/Token-Erzeugung, Hashing, Ablauf, Redeem und Token-Aufloesung.
- UI-Endpunkt
chat-startfuer bestehende Learner. - AI-Endpunkt
redeem. - Session-basierte AI-Routen als Wrapper um bestehende LearnerService-Methoden.
- Sanitizing der AI-Session-Responses.
- Frontend-Startflow auf Startcode umstellen.
- Custom-GPT-OpenAPI und System-Instructions aktualisieren.
Lokale End-to-End-Tests:
- neue ID erzeugen
- Startcode erzeugen
- Startcode einloesen
- Folgeaktion mit Session-Token
- Startcode nicht zweimal nutzbar
- abgelaufener Startcode wird abgelehnt
- echte SkillPilot-ID erscheint nicht in GPT-Responses