Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

All notable changes to UnoSim. Versions follow [Semantic Versioning](https://semver.org/).

## Unreleased

### Fixed

- **Tutor keeps answering while GitHub is unavailable.** When the Course
Content source cannot be refreshed (outage, rate limit or load limit), Tutor
questions and dialogs fall back to the free Tutor without a Course Content
session instead of failing with `INVALID_REQUEST` (Course Content SSOT §11,
case G).

## v1.0.0 – 2026-10-09

First versioned release of UnoSim. It covers everything merged since the last
Expand All @@ -25,7 +35,7 @@ stays at `1.4.0`.
- **Capacity:** the application default admits 25 running plus waiting
simulations, at most 5 per subject. The Ubuntu/VBox installer writes the
value measured on its reference VM, `SIMULATION_ADMISSION_MAX=40`. Read
[CAPACITY_VALIDATION_PLAN.md](docs/CAPACITY_VALIDATION_PLAN.md) before
[CAPACITY_MODEL.md](docs/CAPACITY_MODEL.md) before
raising it on other hosts.
- **New lifetime limits:** a sandbox ends after `SANDBOX_MAX_LIFETIME_SECONDS`
(default 7200 s) and a run after `SIMULATION_MAX_PAUSED_SECONDS` of total
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ then share an UnoSim identity and its limits. This
IP-identified mode grants access to every client that can reach the proxy and
is not user authentication. See [the deployment security contract](docs/SECURITY.md)
and the [Docker installation guide](docs/INSTALL_SERVER.md). For a tested
Ubuntu Desktop setup, see [README_UbuntuServer.md](README_UbuntuServer.md).
Ubuntu Desktop setup, see [docs/INSTALL_UBUNTU_VBOX.md](docs/INSTALL_UBUNTU_VBOX.md).
Sandbox execution remains dynamic and uses the Docker socket at runtime.

If you need SonarQube, run it separately in its own stack or service; the UnoSim compose file does not include SonarQube or MCP.
Expand Down Expand Up @@ -211,12 +211,12 @@ On macOS, make sure your project directory is allowed under Docker Desktop file
| `RUN_HEAVY_TESTS=1 ./run-tests.sh` | Full pipeline inklusive langsamem Parallel-Instanz-Stresstest |

For host-specific Capacity sizing, use `npm run capacity:calibrate` and follow
the review workflow in [`docs/CAPACITY_VALIDATION_PLAN.md`](docs/CAPACITY_VALIDATION_PLAN.md).
the review workflow in [`docs/CAPACITY_MODEL.md`](docs/CAPACITY_MODEL.md).

### Architecture Overview

- **Sandbox Runner Pool** — Manages runner leases for sketch execution. In the documented production path, each simulation runs in a short-lived isolated Docker sandbox with stdout/stderr capture for serial output and pin state reporting.
- **Compilation Worker Pool** — In production mode, the configured Node.js Worker Thread pool handles compilations in parallel via `CompilerWithFallback`. The Compose reference uses 8 workers (the pool runs at most 8); a full pool answers `503 SYSTEM_BUSY`. Current capacity guidance is in [`docs/CAPACITY_VALIDATION_PLAN.md`](docs/CAPACITY_VALIDATION_PLAN.md); [`docs/SCALABILITY.md`](docs/SCALABILITY.md) keeps the historical measurement.
- **Compilation Worker Pool** — In production mode, the configured Node.js Worker Thread pool handles compilations in parallel via `CompilerWithFallback`. The Compose reference uses 8 workers (the pool runs at most 8); a full pool answers `503 SYSTEM_BUSY`. Current capacity guidance is in [`docs/CAPACITY_MODEL.md`](docs/CAPACITY_MODEL.md); [`docs/CAPACITY_HISTORICAL_PHASE_3_4.md`](docs/CAPACITY_HISTORICAL_PHASE_3_4.md) keeps the historical measurement.
- **WebSocket Layer** — Real-time communication between client and server for serial output, pin state batches, and simulation control (start/stop/pause/resume).
- **SonarQube Integration** — Optional SonarQube scans are wired into the pre-push hook and `./run-tests.sh` when `SONAR_TOKEN` and a reachable SonarQube service are available. Release blocking is controlled by `REQUIRE_RELEASE_GATE=1`.

Expand All @@ -234,7 +234,7 @@ The repository contains a **robust, fast test pipeline**:
3. Heavy stress tests are opt-in. Use `RUN_HEAVY_TESTS=1 ./run-tests.sh` when
validating Docker sandbox isolation and cleanup. Load-test commands are
listed in [`docs/RELEASE_RUNBOOK.md`](docs/RELEASE_RUNBOOK.md) and capacity
conclusions belong in [`docs/CAPACITY_VALIDATION_PLAN.md`](docs/CAPACITY_VALIDATION_PLAN.md).
conclusions belong in [`docs/CAPACITY_MODEL.md`](docs/CAPACITY_MODEL.md).

Local quick‑check example:

Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ services:
# Logical simulation capacity grows on-demand; idle logical runners shrink after IDLE_TIMEOUT_MS.
# Admission caps running plus waiting simulations. Without a host-specific value it
# stays at the application default 25; the Ubuntu/VBox installer writes the value
# measured on its reference VM. See docs/CAPACITY_VALIDATION_PLAN.md before raising.
# measured on its reference VM. See docs/CAPACITY_MODEL.md before raising.
- SIMULATION_ADMISSION_MAX=${SIMULATION_ADMISSION_MAX:-25}
- SIMULATION_MAX_CONCURRENT=200
# Total paused time of one run; a paused run still holds its capacity.
Expand Down
2 changes: 1 addition & 1 deletion docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,5 +393,5 @@ Diese Metriken sind über `/api/status` und WebSocket-Events verfügbar. `/api/h
- [`adr/0006-unified-course-content-and-tutor-strategy.md`](adr/0006-unified-course-content-and-tutor-strategy.md) – aktueller einheitlicher Course-Content-/Tutor-Vertrag
- [`../ssot/ssot_function_definition_CourseContent.md`](../ssot/ssot_function_definition_CourseContent.md) – Normativer Course-Content-Vertrag
- [`../ssot/ssot_function_definition_ExternalExamples.md`](../ssot/ssot_function_definition_ExternalExamples.md) – Fachlicher Examples-Vertrag
- [`SCALABILITY.md`](SCALABILITY.md) – historische Kapazitätsmessung; aktuelle Werte in [`CAPACITY_VALIDATION_PLAN.md`](CAPACITY_VALIDATION_PLAN.md)
- [`CAPACITY_HISTORICAL_PHASE_3_4.md`](CAPACITY_HISTORICAL_PHASE_3_4.md) – historische Kapazitätsmessung; aktuelle Werte in [`CAPACITY_MODEL.md`](CAPACITY_MODEL.md)
- [`TESTING_STANDARDS.md`](TESTING_STANDARDS.md) – Teststrategie und -konventionen
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Dieses Dokument bewahrt die Messung aus Phase 3.4 vor dem aktuellen
Kapazitätsmodell. Es ist keine normative Aussage über die heutigen
Produktionsgrenzen. Das aktuelle Modell, die aktuellen Defaults und die Dell-
Referenzmessungen stehen in
[CAPACITY_VALIDATION_PLAN.md](CAPACITY_VALIDATION_PLAN.md).
[CAPACITY_MODEL.md](CAPACITY_MODEL.md).

## Gemessene Grenzen

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Capacity validation plan and operating model
# Capacity model and validation

This is the authoritative description of UnoSim's simulation capacity model,
its timeout boundaries, and the validation evidence. Validation profiles are
Expand Down
4 changes: 2 additions & 2 deletions docs/CAPACITY_TEST_RESULTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This document summarizes the measured reference results. The operating model,
timeout boundaries, production defaults, and acceptance procedure are
authoritative in CAPACITY_VALIDATION_PLAN.md.
authoritative in CAPACITY_MODEL.md.

## Historical harness baseline

Expand Down Expand Up @@ -35,7 +35,7 @@ That run used 80 sandbox-start slots. On current `main` with 8 start slots
and the 30 s start-slot timeout, a synchronous 80-burst started only 64; the
rest timed out waiting for a start slot. A 43 s timeout or 16 start slots
brought it back to 80/80. See the 2026-10-09 delta check in
CAPACITY_VALIDATION_PLAN.md.
CAPACITY_MODEL.md.

## Dell classroom validation

Expand Down
6 changes: 3 additions & 3 deletions docs/INSTALL_SERVER.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Gateway-Identität und Docker-Simulation automatisch. Der Server prüft
Docker-Daemon, Sandbox-Image und Runner-Pool vor der Readiness-Freigabe.

Die vollständige Kapazitäts- und Timeout-Semantik steht in
[`CAPACITY_VALIDATION_PLAN.md`](CAPACITY_VALIDATION_PLAN.md). Die dortigen
[`CAPACITY_MODEL.md`](CAPACITY_MODEL.md). Die dortigen
Validierungsprofile sind Testprofile und keine automatischen
Produktionsvorgaben.

Expand Down Expand Up @@ -166,7 +166,7 @@ zusammen mit `SIMULATION_ADMISSION_MAX`: Ohne diesen Wert lässt die Admission
höchstens 25 laufende und wartende Simulationen zu. Der Ubuntu/VBox-Installer
schreibt `SIMULATION_ADMISSION_MAX=40` in die `.env`; dieser Wert ist auf der
Referenz-VBox (8 vCPU, 11 GiB, kein Swap) für Klassen von etwa 30 Studierenden
gemessen (siehe `CAPACITY_VALIDATION_PLAN.md`). Auf anderer Hardware vor einer
gemessen (siehe `CAPACITY_MODEL.md`). Auf anderer Hardware vor einer
Übernahme erneut messen.

Ist der Compile-Worker-Pool ausgelastet (500 wartende Compiles oder 30 s
Expand All @@ -185,7 +185,7 @@ ist nur ein Review-Vorschlag; fehlende Werte müssen geprüft und ausdrücklich
aufgelöst werden. Die Kalibrierung ändert keine Produktionskonfiguration
automatisch. Die technische Referenz mit Messphasen, Timeout-Grenzen und
Akzeptanzkriterien steht in
[`CAPACITY_VALIDATION_PLAN.md`](CAPACITY_VALIDATION_PLAN.md).
[`CAPACITY_MODEL.md`](CAPACITY_MODEL.md).

Frühere Topologie- und Kompatibilitätsschalter werden beim Start abgelehnt:
`UNOSIM_SIMULATION_MODE`, `UNOSIM_TRUST_MODE`, `FORCE_DOCKER` und
Expand Down
6 changes: 3 additions & 3 deletions README_UbuntuServer.md → docs/INSTALL_UBUNTU_VBOX.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,6 @@ https://127.0.0.1
https://127.0.0.1:8443
```

Weitere Details stehen in [docs/INSTALL_SERVER.md](docs/INSTALL_SERVER.md),
[docs/SECURITY.md](docs/SECURITY.md) und
[ADR 0008](docs/adr/0008-optional-gateway-authentication.md).
Weitere Details stehen in [INSTALL_SERVER.md](INSTALL_SERVER.md),
[SECURITY.md](SECURITY.md) und
[ADR 0008](adr/0008-optional-gateway-authentication.md).
36 changes: 36 additions & 0 deletions docs/OPEN_POINTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# UnoSim – Offene Punkte (OPL)

> **Nicht normativ.** Enthält nur offene Punkte. Jeder Punkt wurde am
> 2026-10-11 gegen `main` @ `4dcc1ae9` geprüft. Erledigte Punkte werden aus
> dieser Liste entfernt; die abgeschlossene Refactoring-Serie mit Verlauf steht
> in [archive/refactoring/REFACTORING_OPL.md](archive/refactoring/REFACTORING_OPL.md).
> Normative Verträge bleiben ADRs und SSOTs.

Kein offener Punkt ist mit Risiko „hoch“ bewertet.

Statuswerte: `BLOCKED_DECISION` (wartet auf eine Entscheidung) · `DEFERRED`
(bewusst zurückgestellt) · `OPEN` (entschieden, noch nicht umgesetzt)

## Sicherheit und Verträge

| ID | Befund | Risiko | Beleg | Status | Nötige Entscheidung |
|---|---|---|---|---|---|
| R10-PROXY | ADR 0001 §51 verlangt, dass das Backend nur von `UNOSIM_TRUSTED_PROXY` erreichbar ist. Der Code validiert die Einstellung nur und setzt damit `trust proxy`; die Quell-IP eingehender Verbindungen prüft er nicht. | mittel | [access-control.ts:135-142](../server/security/access-control.ts#L135-L142), [index.ts:53](../server/index.ts#L53) | BLOCKED_DECISION | Quell-IP-Prüfung im Code (Rollout-Risiko bei falsch gesetztem Wert) oder ADR als Betreiberpflicht formulieren |
| S1-ASM | Die GAS-Direktive `.include` im Inline-Assembler gibt die ersten Zeichen jeder Zeile einer lesbaren Datei als Fehlermeldung aus. Ein Textfilter lässt sich per String-Konkatenation umgehen. Als Restrisiko in [SECURITY.md](SECURITY.md) dokumentiert. | mittel | Marker-Präfix in der Assemblermeldung reproduziert | BLOCKED_DECISION | REST-Compile ohne Zugriff auf Backend-Dateien (Sandbox/Namespace) – Architekturentscheidung |
| R10-HANDSHAKE | [EXTERNAL_API.md](EXTERNAL_API.md) beschreibt einen initialen `handshake` mit `protocolVersion`. Der Server sendet ihn nur, wenn der Client eine `testRunId` mitschickt. | gering | [simulation.ws.ts:889-895](../server/routes/simulation.ws.ts#L889-L895) | BLOCKED_DECISION | Handshake immer senden (Schemaänderung, `testRunId` optional) oder Vertragstext anpassen |

## Produktentscheidungen

| ID | Befund | Risiko | Beleg | Status | Nötige Entscheidung |
|---|---|---|---|---|---|
| T3 | Vom Client gesendete `answerRating`-Werte zählen als Mastery-Evidenz, solange für die Frage keine gespeicherte Evidenz existiert. Wirkt nur auf den eigenen Lernstand, widerspricht aber der deterministischen Mastery aus ADR 0007. | gering | [curriculum-tutor-adapter.ts:493-515](../server/services/tutor/curriculum-tutor-adapter.ts#L493-L515), [learning-planner.ts:193-200](../server/services/tutor/curriculum/learning-planner.ts#L193-L200) | BLOCKED_DECISION | Dürfen Client-Ratings Mastery beeinflussen? |
| D1 | LEARN nach schwacher oder mittlerer Antwort, wenn das aktuelle Concept keine frische Frage mehr hat, das Topic aber noch andere Fragen bietet. Die SSOT regelt nur den Fall, dass das ganze Topic nicht mehr abfragbar ist (`content-exhausted`). | gering | [LearningQuestions §Zustandsübergänge](../ssot/ssot_function_definition_LearningQuestions.md) | BLOCKED_DECISION | Gewünschtes Tutor-Verhalten festlegen, dann SSOT ergänzen |
| D4 | Tutor-Sessions laufen nach einer absoluten TTL ab (Default 1 h, per `TUTOR_SESSION_TTL_MS` einstellbar), auch bei laufender Nutzung. | gering | [config.ts:412](../server/config.ts#L412), [course-content-session.ts:107](../server/services/course-content/course-content-session.ts#L107) | BLOCKED_DECISION | Absolute oder gleitende TTL? |
| D5 | Ein laufender Sketch hält seinen Simulationsslot bis zum Lauf-Timeout (Default 60 s, Client-Maximum 300 s). Pausierte Läufe enden nach `SIMULATION_MAX_PAUSED_SECONDS` (600 s), jeder Container nach `SANDBOX_MAX_LIFETIME_SECONDS` (2 h). Einen Inaktivitäts-Timeout für laufende Simulationen gibt es nicht. | gering | [input-limits.ts:40-42](../shared/input-limits.ts#L40-L42), [config.ts:246-247](../server/config.ts#L246-L247) | BLOCKED_DECISION | Reichen die vorhandenen Grenzen, oder soll eine Simulation ohne Nutzerinteraktion früher enden? |

## Wartung

| ID | Befund | Risiko | Beleg | Status | Nötige Entscheidung |
|---|---|---|---|---|---|
| A2-DEAD | Die Cache-Lock-API (`acquireCacheLock`) und `drain()` im Gatekeeper werden im Produktionscode nicht genutzt; 48 Testreferenzen hängen daran. | gering | [unified-gatekeeper.ts:259](../server/services/unified-gatekeeper.ts#L259), [unified-gatekeeper.ts:502](../server/services/unified-gatekeeper.ts#L502) | DEFERRED | Entfernen samt Tests (Teständerung braucht Freigabe) |
| R10-SSOTREF | Die SSOT TutorQualityEvaluation verweist auf `ssot_function_tutor_model_registration.md`, die nicht im Repository liegt. | gering | [TutorQualityEvaluation:23](../ssot/ssot_function_definition_TutorQualityEvaluation.md) | DEFERRED | Datei versionieren oder Verweis entfernen (Owner) |
43 changes: 35 additions & 8 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ und Messläufe, keinen Vertrag.
Kompilierung und Simulation.
- [INSTALL_SERVER.md](INSTALL_SERVER.md) – Docker-Deployment mit erforderlichem
Gateway, optionaler Benutzeranmeldung und Docker-Sandboxen.
- [../README_UbuntuServer.md](../README_UbuntuServer.md) – Ubuntu-Desktop-Setup
- [INSTALL_UBUNTU_VBOX.md](INSTALL_UBUNTU_VBOX.md) – Ubuntu-Desktop-Setup in VirtualBox
mit Docker, Nginx, TLS und optionaler Benutzeranmeldung.
- [SECURITY.md](SECURITY.md) – Sicherheits- und Isolationsvertrag.
- [RELEASE_RUNBOOK.md](RELEASE_RUNBOOK.md) – Release-Gates und Betriebskontrollen.
Expand All @@ -22,8 +22,19 @@ und Messläufe, keinen Vertrag.
Runtime-Profile.
- [EXTERNAL_API.md](EXTERNAL_API.md) – versionierter iframe-/postMessage-Vertrag.
- [TESTING_STANDARDS.md](TESTING_STANDARDS.md) – Testklassen und Qualitätsgates.
- [SCALABILITY.md](SCALABILITY.md) – historische Kapazitätsmessung; aktuelle
Werte und Kalibrierung in [CAPACITY_VALIDATION_PLAN.md](CAPACITY_VALIDATION_PLAN.md).

## Kapazität

- [CAPACITY_MODEL.md](CAPACITY_MODEL.md) – maßgebliches
Kapazitätsmodell, Timeout-Grenzen und Kalibrierung.
- [CAPACITY_VALIDATION_QUICKSTART.md](CAPACITY_VALIDATION_QUICKSTART.md) –
Ablauf der Validierung auf dem Staging-Host.
- [CAPACITY_MIXED_LOAD_TESTING.md](CAPACITY_MIXED_LOAD_TESTING.md) – gemischte
Messung aus REST-Compiles, Simulationsstarts und laufenden Simulationen.
- [CAPACITY_TEST_RESULTS.md](CAPACITY_TEST_RESULTS.md) – gemessene
Referenzergebnisse.
- [CAPACITY_HISTORICAL_PHASE_3_4.md](CAPACITY_HISTORICAL_PHASE_3_4.md) –
historische Kapazitätsmessung aus Phase 3.4 (nicht normativ).

## Entscheidungen und Fachverträge

Expand All @@ -32,9 +43,25 @@ und Messläufe, keinen Vertrag.

Bei Änderungen zuerst die zuständige normative Quelle aktualisieren.

## Analysen und Arbeitsstand (nicht normativ)
## Offene Punkte (nicht normativ)

- [OPEN_POINTS.md](OPEN_POINTS.md) – geprüfte offene Entscheidungen und
zurückgestellte Punkte.

## Archiv

- [archive/refactoring/](archive/refactoring/) – Architektur- und
Gesundheitsbericht (Stand `54cc2950`) und die daraus abgeleitete,
abgeschlossene Refactoring-Serie.
- [archive/tutor-quality/](archive/tutor-quality/) – abgeschlossene Pläne und
Messberichte zur Tutor-Qualität. Normativ bleibt
[../ssot/ssot_function_definition_TutorQualityEvaluation.md](../ssot/ssot_function_definition_TutorQualityEvaluation.md).

Erledigte Implementierungspläne werden gelöscht, nicht archiviert; sie bleiben
in der Git-Historie.

## Namenskonvention

- [UNOSIM_TECHNICAL_ARCHITECTURE_HEALTH_REVIEW.md](UNOSIM_TECHNICAL_ARCHITECTURE_HEALTH_REVIEW.md)
– Architektur- und Gesundheitsbericht (Stand `54cc2950`).
- [UNOSIM_REFACTORING_OPL.md](UNOSIM_REFACTORING_OPL.md) – Ergebnis der daraus
abgeleiteten Refactoring-Serie und offene Entscheidungen.
Dateien im Wurzelverzeichnis heißen `THEMA_INHALT.md` in Großbuchstaben. Das
Präfix gruppiert zusammengehörige Dokumente (`INSTALL_`, `CAPACITY_`). ADRs
liegen unter `adr/` als `NNNN-titel.md`.
2 changes: 1 addition & 1 deletion docs/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Remaining risk: inline-assembler directives such as `.include` can still make
the assembler report the first characters of each line of a readable file, and
string concatenation defeats a textual filter. Do not place secrets as files in
the backend container. A sandboxed REST compile is an open decision
([refactoring OPL](UNOSIM_REFACTORING_OPL.md), S1-ASM). The process environment
([open points](OPEN_POINTS.md), S1-ASM). The process environment
is not reachable this way: `/proc/*/environ` reads as empty for both compilers
in use.

Expand Down
4 changes: 2 additions & 2 deletions docs/adr/0003-scalability-and-ha-model.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ADR 0003: Scalability and HA model

- Status: Accepted for the historical Phase 3.4 envelope; current capacity
validation is documented in ../CAPACITY_VALIDATION_PLAN.md
validation is documented in ../CAPACITY_MODEL.md
- Date: 2026-09-06
- Owners: UnoSim maintainers and platform operators
- Records: accepted scalability / HA decision based on the Phase 3.4 measurements
Expand All @@ -11,7 +11,7 @@
Phase 3.4 measured UnoSim capacity with real Docker compile and simulation load.
This ADR records that pre-refactor envelope. It must be read together with the
current model and Dell reference measurements in
../CAPACITY_VALIDATION_PLAN.md; the historical runner values below are not
../CAPACITY_MODEL.md; the historical runner values below are not
current operator settings.
The measurement profile intentionally kept the existing production-like runner
and resource configuration unchanged:
Expand Down
Loading
Loading