feat: add three-profile STEM container workflow
This commit is contained in:
@@ -0,0 +1,488 @@
|
||||
# Plan architektury STEM Launcher i środowisk wykonawczych
|
||||
|
||||
Status: wdrożony fundament P0/P1; `fast-dm`, BSP FreeRTOS symulatora i pełne
|
||||
bramki sprzętowe pozostają kolejnymi etapami
|
||||
Data: 2026-07-14
|
||||
|
||||
Role w procesie:
|
||||
|
||||
- Codex — architekt i wykonawca planu;
|
||||
- Claude — senior reviewer;
|
||||
- użytkownik — właściciel produktu i programu nauczania.
|
||||
|
||||
## 1. Decyzja architektoniczna
|
||||
|
||||
System składa się z jednego launchera uruchamianego na hoście, jednego wspólnego
|
||||
stage'a bazowego Dockerfile oraz dokładnie trzech kontenerów roboczych:
|
||||
|
||||
| Profil launchera | Target Dockerfile | Rola |
|
||||
| --- | --- | --- |
|
||||
| `native-amd64` | `native-amd64-final` | szybkie testy algorytmów C/C++ na AMD64 |
|
||||
| `hazard3-sim` | `hazard3-sim-final` | RV32 bare metal i FreeRTOS na rzeczywistym RTL Hazard3 w Verilatorze |
|
||||
| `rp2350` | `rp2350-final` | fizyczny Pico 2/Pico 2 W: RISC-V Hazard3 i ARM Cortex-M33 |
|
||||
|
||||
Stage `dev-ui-base` jest wspólną warstwą budowania, a nie czwartym stale
|
||||
uruchomionym kontenerem. Hoverboard nie otrzymuje teraz osobnego kontenera.
|
||||
Dodamy go dopiero po ustaleniu mikrokontrolera, BSP i interfejsu probe.
|
||||
|
||||
Nie tworzymy osobnych kontenerów dla:
|
||||
|
||||
- bare metal i FreeRTOS;
|
||||
- RP2350 RISC-V i RP2350 ARM;
|
||||
- C i C++/STL;
|
||||
- Termdebug, nvim-dap, tmuxa ani MCP.
|
||||
|
||||
Są to targety, tryby albo narzędzia wewnątrz jednego z trzech profili.
|
||||
|
||||
## 2. Granice odpowiedzialności
|
||||
|
||||
### Host i `stem-launcher`
|
||||
|
||||
Launcher działa jako zwykły użytkownik hosta i odpowiada za:
|
||||
|
||||
1. synchronizację publicznego manifestu serii;
|
||||
2. listowanie serii, kart i zadań;
|
||||
3. pobieranie kodu karty z Git do workspace na hoście;
|
||||
4. przygotowanie repo odpowiedzi, brancha ucznia i remotes;
|
||||
5. wybór profilu oraz targetu;
|
||||
6. lokalny build właściwego targetu ze źródłowego Dockerfile albo użycie jego
|
||||
lokalnego cache;
|
||||
7. utworzenie, wznowienie, zatrzymanie i usunięcie kontenera;
|
||||
8. wywołanie `build`, `test`, `run`, `debug` i `deploy`;
|
||||
9. rejestrację artefaktów, logów, wyników i socketów MCP;
|
||||
10. wykrywanie probe i przekazanie wyłącznie potrzebnego urządzenia do profilu
|
||||
`rp2350`.
|
||||
|
||||
Klucze SSH, tokeny Gitea i konfiguracja Git pozostają na hoście. Prywatnego
|
||||
klucza SSH nie montujemy do kontenera. Kontenery nie otrzymują socketu Podmana
|
||||
ani Dockera i nie zarządzają innymi kontenerami.
|
||||
|
||||
### Kontener roboczy
|
||||
|
||||
Kontener odpowiada wyłącznie za powtarzalne środowisko kompilacji,
|
||||
uruchamiania i debugowania. Otrzymuje:
|
||||
|
||||
- repo karty pod `/workspace` jako bind mount;
|
||||
- katalog stanu instancji pod `/workspace/.stem/instances/<instance>`;
|
||||
- deklarację targetu i akcji;
|
||||
- opcjonalnie konkretne urządzenie USB dla RP2350;
|
||||
- katalog wymiany socketów MCP widoczny również na hoście.
|
||||
|
||||
Kod źródłowy i artefakty pozostają na hoście. Usunięcie kontenera nie usuwa
|
||||
pracy ucznia.
|
||||
|
||||
## 3. Przepływ ucznia
|
||||
|
||||
Docelowy przepływ jest jeden dla domu, pracowni i zdalnego komputera:
|
||||
|
||||
```bash
|
||||
stemctl workspace sync
|
||||
stemctl series list
|
||||
stemctl series cards fetch inf bss
|
||||
|
||||
stemctl env ensure native-amd64
|
||||
stemctl test native-amd64
|
||||
stemctl run native-amd64
|
||||
|
||||
stemctl env ensure hazard3-sim
|
||||
stemctl test hazard3-sim
|
||||
stemctl debug hazard3-sim
|
||||
|
||||
stemctl env ensure rp2350
|
||||
stemctl probe list
|
||||
stemctl deploy rp2350 inf bss 1 --target rp2350-rv --device /dev/bus/usb/001/006
|
||||
stemctl debug rp2350 inf bss 1 --target rp2350-rv --device /dev/bus/usb/001/006
|
||||
```
|
||||
|
||||
Pełne selektory pozostają dostępne, na przykład:
|
||||
|
||||
```bash
|
||||
stemctl test hazard3-sim inf bss 1
|
||||
stemctl deploy rp2350 inf bss 1 --target rp2350-arm
|
||||
```
|
||||
|
||||
Launcher wykonuje następujący pipeline:
|
||||
|
||||
```text
|
||||
workspace-info
|
||||
│
|
||||
▼
|
||||
wybór serii/karty/zadania
|
||||
│
|
||||
▼
|
||||
clone/fetch Git na hoście ──► branch/remotes odpowiedzi
|
||||
│
|
||||
▼
|
||||
wybór profilu i targetu
|
||||
│
|
||||
▼
|
||||
rootless Podman + bind mount repo
|
||||
│
|
||||
├──► build ─► test ─► run/debug
|
||||
│
|
||||
└──► artefakt ─► deploy, tylko gdy target to obsługuje
|
||||
```
|
||||
|
||||
### Znaczenie akcji
|
||||
|
||||
| Akcja | `native-amd64` | `hazard3-sim` | `rp2350` |
|
||||
| --- | --- | --- | --- |
|
||||
| `build` | binarka ELF hosta | ELF/BIN RV32 | ELF/UF2 dla RV albo ARM |
|
||||
| `test` | golden tests, ASan/UBSan | te same wektory, RV32/RTL | testy na płytce, gdy karta je deklaruje |
|
||||
| `run` | proces natywny | program w Verilatorze | uruchomienie wcześniej wgranego programu i serial/RTT |
|
||||
| `debug` | GDB/LLDB | obecnie `fast-rsp`, docelowo `fast-dm`, kontrolnie JTAG | GDB przez OpenOCD/probe |
|
||||
| `deploy` | nieobsługiwane | nieobsługiwane; artefakt ładuje `run`/`debug` | flash przez probe |
|
||||
|
||||
Komenda nie może udawać sukcesu dla niewspieranej możliwości. Launcher czyta
|
||||
capabilities profilu i zwraca czytelny komunikat, na przykład
|
||||
`deploy is not supported by native-amd64`.
|
||||
|
||||
`run rp2350` nie wykonuje ukrytego flashowania. Wymaga rekordu, że wybrany
|
||||
artefakt został wcześniej wdrożony na wybraną płytkę; w przeciwnym razie
|
||||
odmawia startu albo wymaga jawnego `--allow-existing-firmware`. Artefakt
|
||||
powinien zawierać build ID możliwy do potwierdzenia przez UART/RTT lub metadata
|
||||
RP2350, aby nie testować przypadkiem starego firmware.
|
||||
|
||||
## 4. Kontrakt karty pracy
|
||||
|
||||
Karta nie może zależeć od zaszytych w launcherze nazw plików. Jej wersjonowany
|
||||
manifest powinien deklarować co najmniej:
|
||||
|
||||
```yaml
|
||||
schema: 1
|
||||
card: inf/bss
|
||||
default_task: task1
|
||||
profiles:
|
||||
native-amd64:
|
||||
default_target: native
|
||||
hazard3-sim:
|
||||
default_target: hazard3-baremetal
|
||||
rp2350:
|
||||
default_target: rp2350-rv
|
||||
targets:
|
||||
native:
|
||||
profile: native-amd64
|
||||
actions: [build, test, run, debug]
|
||||
hazard3-baremetal:
|
||||
profile: hazard3-sim
|
||||
runtime: baremetal
|
||||
actions: [build, test, run, debug]
|
||||
hazard3-freertos:
|
||||
profile: hazard3-sim
|
||||
runtime: freertos
|
||||
tick_hz: 1000
|
||||
actions: [build, test, run, debug]
|
||||
rp2350-rv:
|
||||
profile: rp2350
|
||||
arch: riscv
|
||||
actions: [build, test, run, debug, deploy]
|
||||
requires:
|
||||
debug: [probe]
|
||||
deploy: [probe]
|
||||
rp2350-arm:
|
||||
profile: rp2350
|
||||
arch: arm
|
||||
actions: [build, test, run, debug, deploy]
|
||||
requires:
|
||||
debug: [probe]
|
||||
deploy: [probe]
|
||||
actions:
|
||||
build: ./tools/card build
|
||||
test: ./tools/card test
|
||||
run: ./tools/card run
|
||||
debug: ./tools/card debug
|
||||
deploy: ./tools/card deploy
|
||||
artifacts:
|
||||
directory: .stem/artifacts
|
||||
```
|
||||
|
||||
Nazwa pliku manifestu i dokładny schemat zostaną zatwierdzone w implementacji.
|
||||
Ważny jest podział: `workspace-info` mówi, skąd pobrać kartę, manifest karty
|
||||
mówi, jak ją wykonać, a profil środowiska dostarcza narzędzia.
|
||||
|
||||
Każda akcja zapisuje maszynowo czytelny wynik do:
|
||||
|
||||
```text
|
||||
.stem/results/<profile>/<target>/<task>/<run-id>/result.json
|
||||
```
|
||||
|
||||
Wynik zawiera co najmniej commit karty, lokalny identyfikator wyniku builda,
|
||||
wersję toolchainu,
|
||||
polecenie, kod wyjścia, czas, testy i skróty artefaktów. Dzięki temu porównanie
|
||||
AMD64 → Hazard3 → RP2350 nie opiera się na ręcznym oglądaniu terminala.
|
||||
|
||||
## 5. Trzy kontenery
|
||||
|
||||
### 5.1 `native-amd64`
|
||||
|
||||
Cel: najszybsza pętla dla algorytmów z podręcznika, matury i ZPE.
|
||||
|
||||
Narzędzia specyficzne:
|
||||
|
||||
- GCC i Clang;
|
||||
- GDB i opcjonalnie LLDB;
|
||||
- ASan, UBSan, coverage i Valgrind;
|
||||
- CMake, Ninja i Make;
|
||||
- testy jednostkowe C/C++.
|
||||
|
||||
Profil nie zawiera SDK RP2350 ani Verilatora. Testuje algorytm i kontrakt API,
|
||||
nie emuluje zachowania 32-bitowego MCU. Testy przenośności muszą dodatkowo
|
||||
przejść w `hazard3-sim`.
|
||||
|
||||
### 5.2 `hazard3-sim`
|
||||
|
||||
Cel: praca domowa bez płytki i dydaktyczny wgląd w procesor.
|
||||
|
||||
Narzędzia specyficzne:
|
||||
|
||||
- przypięty toolchain `riscv64-unknown-elf`;
|
||||
- przypięty Verilator;
|
||||
- Hazard3 RTL oraz testbench;
|
||||
- runtime bare-metal i osobny BSP symulatora dla FreeRTOS;
|
||||
- szybki RSP oraz planowany transport `fast-dm` do wbudowanego DM Hazard3;
|
||||
- OpenOCD/remote-bitbang wyłącznie jako okresowy gate zgodności;
|
||||
- opcjonalne VCD i narzędzia do zajęć z Veriloga.
|
||||
|
||||
Dla FreeRTOS 1 kHz timer symulatora zwiększa `mtime` dokładnie raz na cykl.
|
||||
Przy deklarowanym zegarze 150 MHz tick przypada co 150 000 cykli RTL. Jest to
|
||||
1 kHz czasu gościa, nie obietnica czasu rzeczywistego hosta. Kod aplikacyjny i
|
||||
wektory testowe są wspólne z RP2350, natomiast BSP, startup i linker są osobne.
|
||||
|
||||
Bieżący port FreeRTOS RP2350 ustawia `SIO MTIME` w tryb `FULLSPEED`, dlatego
|
||||
przy zegarze systemowym 150 MHz również używa 150 000 zliczeń na tick. Nie
|
||||
traktujemy jednak tej stałej jako wspólnego API BSP: profil sam wylicza ją z
|
||||
rzeczywistego zegara i trybu timera.
|
||||
|
||||
Testy czasowe mają dwa poziomy. Smoke test PR wykonuje co najmniej 100 ticków z
|
||||
produkcyjnym dzielnikiem 150 000. Długi test schedulera wykonuje 10 000 ticków
|
||||
na jawnie przyspieszonym zegarze testowym i nie jest dowodem częstotliwości.
|
||||
Nightly/release może wykonać dłuższy test produkcyjnego dzielnika w ustalonym
|
||||
budżecie czasu.
|
||||
|
||||
### 5.3 `rp2350`
|
||||
|
||||
Cel: pracownia z fizycznym Pico 2/Pico 2 W.
|
||||
|
||||
Narzędzia specyficzne:
|
||||
|
||||
- przypięty Pico SDK i FreeRTOS Kernel;
|
||||
- toolchain RISC-V dla Hazard3;
|
||||
- toolchain ARM dla Cortex-M33;
|
||||
- CMake/Ninja;
|
||||
- OpenOCD zgodny z RP2350, picotool i obsługa wybranego probe;
|
||||
- serial/RTT oraz reguły diagnostyczne USB.
|
||||
|
||||
Target `rp2350-rv` i `rp2350-arm` wybiera konfigurację CMake, startup, linker,
|
||||
GDB i backend OpenOCD. Nie wymaga kolejnego Dockerfile. Bare metal i FreeRTOS są wariantami
|
||||
manifestu projektu, nie oddzielnymi kontenerami.
|
||||
|
||||
Kontener działa rootless, bez `--privileged`. Launcher przekazuje tylko jawnie
|
||||
wybrane urządzenia. Host otrzymuje regułę udev lub ACL, która pozwala grupie
|
||||
laboratoryjnej korzystać z probe bez `sudo`.
|
||||
|
||||
Debug probe i natywne USB płytki to dwie różne capabilities. Domyślny
|
||||
debug/deploy przez zewnętrzny probe używa stabilnego urządzenia probe; reset
|
||||
targetu nie powinien go odłączać. Opcjonalny BOOTSEL/picotool powoduje
|
||||
re-enumerację targetu i zmianę adresu USB. Taki deploy jest osobną, krótkotrwałą
|
||||
akcją z tego samego profilu `rp2350`: launcher ponownie wykrywa urządzenie po
|
||||
każdej fazie i uruchamia akcję z aktualnym węzłem. Nie przekazujemy całego
|
||||
`/dev`; jeżeli backend wymaga dostępu na poziomie portu/busa USB, zakres jest
|
||||
jawnie raportowany i zatwierdzany dla tej instancji.
|
||||
|
||||
## 6. Wspólny kontrakt UI
|
||||
|
||||
Każdy profil dziedziczy z `dev-ui-base`:
|
||||
|
||||
- tmux z prefiksem `Ctrl-s`;
|
||||
- Neovim i identyczny zestaw skrótów;
|
||||
- Termdebug, nvim-dap i dashboard GDB;
|
||||
- serwery/bridge MCP dla tmuxa i Neovima;
|
||||
- `ripgrep`, `fd`, Git, Python i podstawowe narzędzia diagnostyczne;
|
||||
- użytkownika bez roota i ten sam katalog roboczy `/workspace`.
|
||||
|
||||
Domyślny układ jednego widocznego okna tmuxa:
|
||||
|
||||
```text
|
||||
┌────────────────────────────────────────────────────────────┐
|
||||
│ Neovim — jeden pane tmuxa │
|
||||
│ ┌─ Termdebug + GDB dashboard ─┬─ edytor/nvim-dap ───────┐ │
|
||||
│ └──────────────────────────────┴──────────────────────────┘ │
|
||||
├────────────────────────────────────────────────────────────┤
|
||||
│ bash, cwd=/workspace — drugi pane tmuxa │
|
||||
└────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Termdebug i edytor są oknami jednego Neovima. Hazard3 uruchamia symulator w
|
||||
drugim, domyślnie ukrytym oknie tmuxa `tb`.
|
||||
|
||||
Termdebug i nvim-dap są dwiema nakładkami na ten sam opis targetu GDB. Karta
|
||||
nie przechowuje osobnych adresów i poleceń dla każdego frontendu.
|
||||
|
||||
## 7. Tożsamość instancji i MCP
|
||||
|
||||
Każda sesja ma stabilną tożsamość logiczną, na przykład:
|
||||
|
||||
```text
|
||||
hazard3-sim-inf-bss-t1
|
||||
```
|
||||
|
||||
Kontener otrzymuje label `edu.stem.instance`. Aktualny identyfikator Podmana
|
||||
jest tożsamością procesu. Pełne nazwy pozostają w labels/registry, natomiast
|
||||
ścieżka Unix socketu używa krótkich kluczy, aby zmieścić się w limicie
|
||||
`sun_path` (maksymalnie 107 użytecznych bajtów na Linuksie):
|
||||
|
||||
```text
|
||||
$XDG_RUNTIME_DIR/stem/<thread-key>/<instance-key>/<cid12>/t.sock
|
||||
$XDG_RUNTIME_DIR/stem/<thread-key>/<instance-key>/<cid12>/n.sock
|
||||
$XDG_RUNTIME_DIR/stem/<thread-key>/<instance-key>/current
|
||||
```
|
||||
|
||||
`thread-key` i `instance-key` są 12-znakowymi skrótami kryptograficznymi, a
|
||||
`cid12` to jednoznaczny na danym hoście prefiks bieżącego container ID. Registry
|
||||
mapuje je na pełne wartości i jest weryfikowane przez `podman inspect`. Ta sama
|
||||
krótka ścieżka jest widoczna na hoście i w kontenerze. Test startowy odrzuca
|
||||
konfigurację przekraczającą budżet 100 bajtów.
|
||||
|
||||
Wrapper MCP wybiera najpierw jawną instancję, przez `podman inspect` sprawdza
|
||||
jej aktualny container ID, a dopiero potem otwiera socket. `current` jest
|
||||
wskaźnikiem pomocniczym ograniczonym do wątku agenta, nie globalnym wyborem dla
|
||||
wszystkich kontenerów. Stary socket nie może zostać użyty po odtworzeniu
|
||||
kontenera.
|
||||
|
||||
Agent widzi dokładnie tę samą sesję tmuxa i Neovima co uczeń. MCP nie jest
|
||||
osobnym kontenerem.
|
||||
|
||||
## 8. Rootless Podman i SSH
|
||||
|
||||
Podman jest domyślnym runtime. Docker może pozostać przejściowym backendem dla
|
||||
istniejących komputerów, ale kontrakt nie może wymagać członkostwa ucznia w
|
||||
grupie `docker`.
|
||||
|
||||
Na zdalnym komputerze ucznia nauczyciel lub agent:
|
||||
|
||||
1. łączy się wyłącznie przez SSH z parą kluczy;
|
||||
2. uruchamia `stemctl` na tym zdalnym hoście;
|
||||
3. tamtejszy launcher zarządza lokalnym rootless Podmanem i lokalnym
|
||||
workspace;
|
||||
4. w razie potrzeby sockety MCP/GDB są udostępniane przez tunel SSH, nigdy
|
||||
przez nasłuch na `0.0.0.0`.
|
||||
|
||||
Nie montujemy zdalnego katalogu przez SSHFS jako podstawowego modelu i nie
|
||||
przekazujemy prywatnego klucza do kontenera. Repo i kontener mają znajdować się
|
||||
na tym samym hoście wykonawczym.
|
||||
|
||||
## 9. Budowanie kontenerów ze źródeł i cache
|
||||
|
||||
Repo przechowuje jeden wieloetapowy `Dockerfile` i pliki Compose. Nie
|
||||
przechowuje ani nie publikuje gotowych obrazów. `dev-ui-base` zawiera
|
||||
przypięte binaria i zależności UI, ale nie zawiera często zmienianych
|
||||
`configs/` ani entrypointów. Graf stage'ów:
|
||||
|
||||
```text
|
||||
os-base
|
||||
└─ dev-ui-base (tmux/nvim/MCP i przypięte zależności, bez configs/)
|
||||
├─ ui-node-deps (przypięte zależności serwerów MCP)
|
||||
├─ native-toolchain
|
||||
│ └─ native-amd64-final + COPY configs/ i entrypointów
|
||||
├─ hazard3-toolchain
|
||||
│ └─ hazard3-sim-final + COPY configs/ i entrypointów
|
||||
└─ rp2350-toolchain
|
||||
└─ rp2350-final + COPY configs/ i entrypointów
|
||||
```
|
||||
|
||||
Duże toolchainy, SDK, Verilator, Hazard3 i OpenOCD są instalowane w stage'ach
|
||||
toolchain przed skopiowaniem konfiguracji UI. Zmiana lockfile zależności UI
|
||||
może celowo przebudować potomków; zwykła zmiana mapowania klawisza, dashboardu
|
||||
albo entrypointu nie może tego zrobić.
|
||||
|
||||
Kod karty nigdy nie jest kopiowany do warstw kontenera. Zmiana konfiguracji końcowej nie
|
||||
może ponownie pobierać toolchainów. W CI sprawdzamy drugi build bez zmian i
|
||||
raportujemy wykorzystanie cache.
|
||||
|
||||
Uczeń wykonuje `stemctl env ensure`, które używa lokalnego cache lub buduje
|
||||
profil ze źródłowego Dockerfile. Nic nie jest pobierane z rejestru obrazów.
|
||||
|
||||
## 10. Migracja `rv-launcher` do `stem-launcher`
|
||||
|
||||
Nazwa RV jest zbyt wąska, ponieważ launcher obsługuje serie informatyczne,
|
||||
fizyczne, AMD64, RISC-V i ARM. Docelowe nazwy to:
|
||||
|
||||
- repo: `edu-tools/stem-launcher`;
|
||||
- publiczne CLI: `stemctl`;
|
||||
- workspace: `~/dev/workspace/stem`;
|
||||
- zmienne: `STEM_*`;
|
||||
- stan karty: `.stem/`.
|
||||
|
||||
Migracja musi zachować działające workspace uczniów:
|
||||
|
||||
1. dodać `stemctl` jako nowy entrypoint do obecnej implementacji;
|
||||
2. akceptować `rvctl` jako wrapper kompatybilności z ostrzeżeniem;
|
||||
3. czytać nowe `STEM_*`, a następnie stare `RV_*` jako fallback;
|
||||
4. domyślnie używać `~/dev/workspace/stem`, ale automatycznie wykrywać
|
||||
istniejące `~/dev/workspace/rv`;
|
||||
5. zmigrować `.rv/` do `.stem/` bez usuwania stanu;
|
||||
6. dopiero wtedy zmienić nazwę repo na Gitea i zaktualizować manifest;
|
||||
7. pozostawić alias lub repo informacyjne pod starą nazwą na co najmniej jeden
|
||||
cykl zajęć;
|
||||
8. usunąć kompatybilność dopiero po telemetrycznym/audytowym potwierdzeniu, że
|
||||
materiały nie wywołują starych nazw.
|
||||
|
||||
Szczegóły i kryteria wycofania opisuje `doc/migration-stem-launcher.md`.
|
||||
|
||||
## 11. Kolejność wdrożenia
|
||||
|
||||
### P0 — kontrakt i bezpieczeństwo
|
||||
|
||||
1. Zatwierdzić nazwy profili, capabilities i schemat manifestu karty.
|
||||
2. Dodać `stemctl` oraz zgodność `rvctl`.
|
||||
3. Przenieść runtime z Docker Compose na abstrakcję z rootless Podmanem jako
|
||||
backendem domyślnym.
|
||||
4. Rozdzielić sekrety hosta od kontenerów i usunąć tokeny z URL-i remotes po
|
||||
operacji Git.
|
||||
5. Ustabilizować tożsamość instancji, labels i sockety MCP.
|
||||
|
||||
### P1 — trzy targety jednego Dockerfile
|
||||
|
||||
1. Wyodrębnić `dev-ui-base`.
|
||||
2. Przenieść istniejący profil `host` do `native-amd64`.
|
||||
3. Przenieść istniejący `rv32i` do `hazard3-sim` i dodać simulatorowy BSP
|
||||
FreeRTOS 1 kHz.
|
||||
4. Zbudować `rp2350` z targetami RV i ARM oraz bezpiecznym przekazywaniem probe.
|
||||
5. Ujednolicić layout tmuxa, Termdebug, DAP i MCP.
|
||||
|
||||
### P2 — pełny pipeline karty
|
||||
|
||||
1. Zaimplementować manifest karty i akcje `build/test/run/debug/deploy`.
|
||||
2. Zapisywać wyniki i metadane artefaktów.
|
||||
3. Porównywać golden tests pomiędzy trzema profilami.
|
||||
4. Dodać `fast-dm` oraz okresowy gate JTAG.
|
||||
5. Dodać zdalny smoke test przez SSH bez otwierania portów debuggera.
|
||||
|
||||
## 12. Bramki akceptacyjne
|
||||
|
||||
| Obszar | Kryterium |
|
||||
| --- | --- |
|
||||
| Fetch | czysty host pobiera manifest i kartę wyłącznie przez `stemctl` |
|
||||
| Persistence | usunięcie kontenera nie zmienia ani nie usuwa repo ucznia |
|
||||
| Native | golden tests, ASan i UBSan przechodzą na AMD64 |
|
||||
| Emulator | te same wektory przechodzą jako RV32 bare metal i FreeRTOS |
|
||||
| FreeRTOS | co najmniej 100 ticków z produkcyjnym dzielnikiem 150 000 oraz 10 000 ticków przyspieszonego testu schedulera bez zgubionego cyklu |
|
||||
| RP2350 RV | build, flash, reset, UART i debug przez probe przechodzą bez `sudo` |
|
||||
| RP2350 ARM | ten sam zestaw operacji przechodzi w tym samym obrazie |
|
||||
| USB | probe pozostaje dostępny po resecie; BOOTSEL/picotool przechodzi kontrolowaną re-enumerację bez `--privileged` |
|
||||
| UI | layout tmux/Nvim, skróty i dashboard są identyczne w trzech profilach |
|
||||
| MCP | agent steruje wskazaną instancją i nie łączy się ze starym socketem |
|
||||
| Isolation | brak socketu runtime, prywatnych kluczy i `--privileged` w kontenerze |
|
||||
| Reproducibility | wynik zapisuje commit karty, lokalny ID builda i wersje toolchainów |
|
||||
| SSH | praca zdalna działa przez klucze i tunele na loopback, bez publicznego GDB |
|
||||
| Cache | zmiana entrypointu lub konfiguracji UI nie powoduje ponownego pobrania toolchainów |
|
||||
| Compatibility | stare `rvctl` i workspace `/rv` działają w okresie migracji |
|
||||
|
||||
## 13. Poza zakresem tej iteracji
|
||||
|
||||
- czwarty kontener dla hoverboardu;
|
||||
- orkiestracja klastra albo Kubernetes;
|
||||
- przechowywanie pracy ucznia wewnątrz warstwy kontenera;
|
||||
- udostępnianie GDB, UART lub MCP na publicznym interfejsie;
|
||||
- automatyczne podawanie agentowi prywatnych kluczy i tokenów;
|
||||
- gwarancja działania symulacji RTL w czasie rzeczywistym.
|
||||
Reference in New Issue
Block a user