KidDOS: компьютер, достаточно маленький, чтобы ребёнок мог его изучить целиком
Расскажите о себе и сути проекта?
Пятнадцать с лишним лет я занимаюсь корпоративными системами: модернизировал legacy, писал на .NET, Go и Rust, а последние годы встраиваю LLM и ИИ-агентов в работающие бизнесы. У меня своя компания и блог где я пишу про программирование, найм и всё, что меня раздражает в индустрии.
KidDOS — это ненастоящий компьютер внутри вашего настоящего компьютера.
Одно приложение. Работает на Mac, Windows, Linux. Запускаешь — оно разворачивается на весь экран, прячет всё остальное и показывает терминал, похожий на ЭЛТ-монитор, с мигающим курсором. Всё. Никаких окон, никакой мыши, никакого интернета. Только приглашение командной строки.
Ребёнок печатает hi. Машина здоровается в ответ. А потом говорит: напиши help, если хочешь узнать, что я умею.
kidos:~$ hi
Hi! I'm a computer. I'm small, and you can learn all of me.
Type help if you want to know what I can do.
kidos:~$ help
You're in a folder called /home/kid. Folders hold files.
ls - show what's in this folder
cd - go into a folder
cat - read a file
man - read the manual for any command (try: man ls)
There's a letter for you. Try: cat welcome.txt
А вот как это выглядит на самом деле, прямо из сборки:
https://roganov.me/img/blog/kiddos-hi.webp
Под капотом — настоящий Unix-подобный шелл. ls, cd, cat, mkdir, rm, пайпы, перенаправления, man. Не DOS-команды, хоть я и называю это KidDOS — я хочу, чтобы мышечная память переносилась. Ребёнок, проведший год в KidDOS, должен открыть настоящий терминал и почувствовать себя как дома.
У него свой виртуальный жёсткий диск. Ребёнок может сделать rm -rf всему целиком, и единственным последствием будет урок. Сброс — одна команда в родительском режиме. Семейный ноутбук никогда не под угрозой, потому что KidDOS его не трогает: всё, что видит ребёнок, симулируется, а единственный мостик в настоящую ОС — крошечный белый список: произнести текст вслух, пикнуть, сказать время.
И да, echo "I am a robot" > /dev/speaker заставляет компьютер говорить. Одна эта строчка займёт семилетку на час. Это и есть крючок.
Код открыт и лежит здесь: github.com/nurked/kiddos. Установщиков пока нет, так что нужен Rust на машине, а дальше три строчки:
git clone https://github.com/nurked/kiddos
cd kiddos
cargo run --release -p kiddos
Напишите hi. Всё. Вы внутри.
Как появилась идея? Что вдохновило?
Я начал программировать, потому что мне было скучно.
Не скучно в смысле «хотел изменить мир». Не скучно в смысле «прочитал книгу про Тьюринга». Просто обыкновенная, двенадцатилетняя, нечем-заняться скука перед 486DX4 — 100 МГц, восемь мегабайт памяти, жёсткий диск на 160 мегабайт.
Игры на нём были. Хорошие. Day of the Tentacle. Warcraft II. Dune II. Master of Orion. Z. The Lost Vikings. Dyna Blaster. И один насквозь пиратский диск, купленный кем-то где-то, с надписью «Сотни офигенных игр» шрифтом, который ни разу в жизни не видел дизайнера.
Но, чёрт возьми, я во всё это уже сыграл. Много, много раз. Я знал наизусть каждую миссию в Warcraft II. Я завоевал Арракис за каждый дом. Пиратский диск был выработан до последней еле живой shareware-демки. Интернета не было. Был мигающий курсор.
Тем временем у друзей появлялись всё более новые компьютеры. Мой отец не был большим любителем апгрейдов. Так что пока одноклассники играли в Half-Life и Red Alert 2, я получил апгрейд на 16 мегабайт памяти, который заметно ускорил мою Windows 95. Это был передний край технологий в нашем доме.
И я начал ковыряться в этой штуке.
dir. Ага, файлы. cd. Ага, папки. Что там в autoexec.bat? Почему компьютер пишет всё это при загрузке? Что будет, если это поменять? (Компьютер перестаёт загружаться. И вот ты в двенадцать лет учишься быстро чинить ЕДИНСТВЕННЫЙ компьютер в доме, пока отец не вернулся с работы. Господи. Вот это мотивация. Бэкапы? Не, не слышал.) Что такое debug.exe? Почему прямо тут лежит qbasic.exe и что он делает?
А потом кто-то дал мне книгу. Первая книга по программированию, которая у меня появилась, — Кип Ирвин, Assembly Language for Intel-Based Computers, третье издание. Не Паскаль, не Бейсик, не «Изучи C за 21 день» — ассемблер. Регистры, прерывания, int 21h, MASM. На той машине это выглядело совершенно естественно: между мной и железом почти ничего не было, так почему бы не начать сразу с железа? (Про этот первый язык я уже писал.)
Вот что люди забывают: это было возможно. Сто шестьдесят мегабайт. Один человек мог сесть и прочитать всё, что есть на этом компьютере. У каждого файла была причина существовать. Каждую директорию туда положил человек, и можно было понять зачем. Конфиги были текстом. Исполняемые файлы были достаточно маленькими, чтобы открыть их в hex-редакторе и разглядывать. Вся машина была конечным, познаваемым объектом, и скучающий ребёнок мог её изучить так же, как изучают лес за домом.
Вот так я и стал программистом. Не через курсы. Через скуку, машину, слишком слабую для новых игр, и книгу, которая случайно оказалась про ассемблер.
Сегодня так уже нельзя.
Посадите ребёнка за современный компьютер и скажите ему: изучай.
Windows — это раздутая рекламная платформа, которая иногда запускает программы. Меню «Пуск» пытается вам что-то продать. Файловая система — лабиринт из AppData\Local\Packages\Microsoft.Something_8wekyb3d8bbwe, который не писал ни один человек и который ни один человек не понимает. Откройте любую папку в C:\Windows — там десять тысяч файлов без единого объяснения, и тронуть любой из них — отличный способ переустановить систему.
Linux лучше, но это уже и не тот Linux, который я изучал двадцать пять лет назад. Каждый раз, когда я туда заглядываю, что-то переехало. /etc сбросил половину содержимого в /usr/lib. ifconfig исчез. init превратился в дюжину unit-файлов. У каждого дистрибутива своё мнение о том, где что должно лежать, и это мнение меняется с каждым релизом. Взрослый сисадмин успевает за этим следить. Десятилетний ребёнок — нет.
macOS прячет файловую систему целиком и предпочла бы, чтобы вы вообще не спрашивали.
И у всех троих бесчеловечное количество интерфейсов. У современной ОС больше поверхности для настройки, чем один человек может прочитать за всю жизнь. Больше нет никакого «прочитай всё и пойми». Есть только «загугли текст ошибки и надейся».
Так что делает скучающий ребёнок? Он не изучает компьютер. Там нечего изучать. Он открывает браузер, браузер выдаёт ему бесконечную ленту коротких видео, а эта лента спроектирована очень умными людьми так, чтобы он больше никогда не скучал.
А скука была самой сутью. Именно скука заставила меня открыть autoexec.bat.
Почему бы просто не дать ребёнку Raspberry Pi с Linux?
Потому что я пробовал эквивалент, и это не работает. У настоящей ОС слишком много выходов. Ребёнок находит браузер за десять минут. В файловой системе десять тысяч файлов, которые ничего не значат. Сообщения об ошибках написаны для сисадминов. Внутри машины нет никого, кто сказал бы: «ты создал папку! теперь зайди в неё».
KidDOS маленький намеренно. Каждый файл в нём положен человеком по какой-то причине, и ребёнок может эту причину прочитать. Это компьютер по размеру человека — одного человека, маленького, у которого есть свободное время.
Что вошло в прототип и сколько времени на него было потрачено?
Сначала я написал план: тринадцать разделов, от принципов («словарь Unix, и никаких dir», «ничего не по-настоящему», «машина — это персонаж», «всё есть файл», «родитель — это root») до архитектуры, API консоли, формата картриджей, рисков и открытых вопросов. План разбит на пять фаз. Прототип — это первые три из них, версия 0.3, «конец фазы 2».
Что в нём есть прямо сейчас:
- Шелл
ksh(«kid shell»):;,&&,||, пайпы,>,>>,<,2>, кавычки,$VAR,$?,~, глоббинг, комментарии, скрипты по шебангу#!/bin/ksh. Редактор строки с историей,!!,!nи Tab-дополнением команд и путей. Неизвестная команда получает не код ошибки, а предложение «может, ты имел в видуls?» по Левенштейну. - Виртуальный диск: дерево inode'ов с правами
rwx, пользователиkidиroot. Системные каталоги принадлежат root'у, так чтоrm /etc/motdучит, что такое «Permission denied», а~целиком принадлежит ребёнку. Диск — один SQLite-файл, который пишется атомарно. Заводской образ собирается из папки с контентом на этапе сборки и вшивается в бинарник. /binнастоящий: ядро зеркалит реестр команд в/bin, так чтоls /binработает и отвечает на вопрос «а где вообще живут команды»./dev/null,/dev/ttyи/dev/speakerтоже настоящие.- Мануал: 57 man-страниц в Markdown, с поиском и пейджером.
- Наставник: подписан на события ядра, после каждой строки в шелле смотрит, что ребёнок сделал, и говорит с ним прямо на экране своим цветом. Три промаха — подсказка. Двенадцать уроков в TOML: привет, где я, файлы, строим, мануал, разговор с машиной, пайпы, редактирование, скрипты, переменные, первая программа, сделай игру. Прогресс лежит в
~/.progress, значки — в~/badges/. Ребёнок может отредактировать.progressруками — наставник это переживёт. edit: полноэкранный редактор в духе nano.- Бейсик: встроенный EndBASIC, привязанный к консоли и диску, плюс расширения
SPEAK,BEEP,KEY$,TICK,PUT. - Семь картриджей: пещерный квест, где комнаты — это папки, а рычаги — шелл-скрипты на
&&,||и2>; и шесть игр на Бейсике — угадай число, змейка, виселица, тренажёр печати, тетрис и сокобан. Исходники лежат рядом:cat snake.bas, поменяй скорость, поменяй цвет, сломай, почини. Каждая игра — листинг, из которого можно воровать, как все мы воровали из листингов на последних страницах журналов. - Родительский режим по комбинации клавиш и паролю: выйти из полноэкранного режима, сбросить диск, посмотреть лог, выключить.
- Безоконный режим для тестов: та же машина без окна, скрипты нажатий прогоняются через шелл, и экран 80x25 сравнивается с ожидаемым.
Итого около двенадцати тысяч строк Rust в тринадцати крейтах и сто с лишним файлов контента.
Какой технологический стек вы использовали? Почему?
- Rust, workspace из тринадцати крейтов. Один бинарник, три платформы, никаких рантаймов и зависимостей на машине родителя. И песочница, обеспеченная не дисциплиной, а структурой: шелл, встроенные команды и мануал зависят только от ядра, ядро — только от консоли, диска и строк. Никто из них физически не может назвать модуль, который трогает настоящую ОС. Единственная дверь наружу — один трейт
HostCapsс методами «скажи», «пикни», «который час», «сохрани образ диска». - winit + wgpu, шейдер на WGSL. Процессор растеризует сетку 80x25 в текстуру 640x400 только тогда, когда экран изменился, а шейдер делает выпуклость, скан-линии, свечение и скруглённые углы.
crt offрисует плоско — некоторым детям это будет мешать, важнее эстетики. - SQLite (rusqlite) как формат образа диска. Тупо, надёжно при сбое, можно открыть и посмотреть.
- EndBASIC 0.12.0, жёстко пришпилен. Почему именно эта версия — в следующем разделе.
- Свой парсер подмножества Fluent для строк, ноль зависимостей. Файлы остаются валидными
.ftl, так что настоящий крейтfluentвстанет на его место, когда понадобятся множественные формы. - TOML для уроков и манифестов картриджей, а не YAML, как было в плане: он уже в стеке, а
serde_yamlзаброшен. - cpal для звука, argon2 для родительского пароля, системные TTS для
/dev/speaker.
Общий принцип из плана: ядро, консольное API и формат диска проектируются один раз и версионируются, контент итерируется свободно. Игра — это папка с манифестом. Добавить игру — никогда не значит пересобрать приложение.
Как вы запускались и искали первых пользователей?
Никак. Вот этот текст и есть запуск.
Я написал статью на английском и на русском, выложил репозиторий и собираюсь отнести это на Hacker News и сюда. Критерий выхода из фазы 0 в плане звучит так: «ребёнок может загрузиться, осмотреться, сделать файлы, прочитать мануал, заблудиться и найтись. Отдать пяти семьям как v0.1». Пяти семей у меня пока нет. Есть репозиторий, три команды для запуска и просьба: посадите за это своего ребёнка и расскажите, что случилось.
С какими самыми неожиданными трудностями пришлось столкнуться?
- Лицензии. EndBASIC начиная с версии 0.13 перешёл на AGPL-3.0, что утянуло бы под AGPL всё приложение. Поэтому в проекте пришпилена 0.12 под Apache-2.0, в которой к тому же нет сети. Я не ожидал, что выбор интерпретатора Бейсика для детей упрётся в юристов.
- Шрифт. В репозитории нет растрового DOS-шрифта — ничего не скачивалось. Идёт public-domain набор 8x8 из крейта
font8x8плюс нарисованный руками блок кириллицы, растянутый по вертикали в 8x16. Получился вид Amstrad CPC, а не VGA. VGA-шрифт можно будет подложить позже за командойfont. - Планировщик. План обещал зелёные потоки с кооперативным планировщиком. В прототипе каждый процесс — это поток ОС, а каждый блокирующий вызов раз в 50 мс проверяет флаг «меня убили». Ctrl-C и
killработают без планировщика, пайпы с обратным давлением,yes | headзавершается, паника внутри команды ловится и превращается в «Программа упала». Намерение плана — ничто не может повесить машину — соблюдено, но не тем способом. - Киоск. Честный статус: полноэкранное окно без рамки, скрытый курсор, нет меню macOS (так что Cmd-Q ничего не делает), закрытие окна игнорируется. Спрятать Dock и заблокировать Cmd-Tab — работа четвёртой фазы. В плане отдельно записано: никогда не обещать родителям «нельзя сломать».
- Контент — это продукт, и контент медленный. Это записано в таблице рисков плана, и это правда. Шелл написать быстро. Двенадцать уроков, в которых наставник звучит как живой и не раздражает, — нет.
- И самое главное. Я сразу хочу извиниться: большая часть этого репозитория написана с помощью ИИ. Это первый, очень сырой прототип, доказательство концепции, а не готовая вещь. Сюжетные линии, диалоги, мелкие детали, из-за которых кажется, что внутри машины кто-то есть, — всё это требует ОЧЕНЬ много ручной работы, и я это полностью признаю. Читайте его как набросок идеи, а не как идею, сделанную правильно.
Сколько потратили и заработали? Есть идеи как это можно монетизировать?
Потратил: время и токены. Заработал: ноль. Продукт бесплатный, открытый и пока без единого пользователя, кроме меня.
Монетизация в плане стоит шестым открытым вопросом, который надо было решить «к концу фазы 1», и он до сих пор не решён. Варианты, которые я рассматриваю:
- открытое ядро плюс платные паки картриджей;
- донаты и поддержи меня, если будет инетерс.
- в разделе «позже» — железная коробка: Raspberry Pi плюс монитор с видом ЭЛТ. Существование EndBOX показывает, что рынок для такого есть.
Честно говоря, сначала я хочу узнать, нужно ли это кому-нибудь, кроме меня. Монетизировать то, что никому не нужно, — плохая идея.
Какие планы на будущее?
Самая интересная для меня часть плана — то, что машина растёт вместе с ребёнком.
Семилетка получает шелл и текстовый квест, где комнаты — это папки, а предметы — файлы. Он выучивает cd и cat, не подозревая, что чему-то учится. Это уже есть.
Девятилетка получает Бейсик. PRINT, INPUT, FOR. Игры на машине написаны на нём, и исходники лежат прямо тут. Это тоже уже есть.
Одиннадцатилетка получает cc. Настоящий C, скомпилированный в WebAssembly и запущенный в песочнице на wasmtime с лимитом топлива, так что while(1) не вешает машину, а кривой указатель не роняет ничего, кроме собственной программы ребёнка. Go через TinyGo и Паскаль через Free Pascal — так же, как опциональные паки, которые ставит родитель. Это фаза 3. Критерий выхода: cc hello.c && ./hello работает на всех трёх ОС.
Тринадцатилетка получает что-то похожее на ассемблер. Крошечный ненастоящий процессор с горсткой регистров и просмотрщиком памяти, чтобы «что компьютер вообще делает» перестало быть загадкой. Ну и к тому времени я уже достаточно поработаю с асьмой на ARM чтобы сказать, что и как. Судя по всему процессор будет ARMовый, ибо смысл учить Intel я сейчас особо не вижу.
А если ребёнок настолько умён, настолько любопытен, настолько перерос песочницу — есть дверь. Способ вырваться из KidDOS в настоящую операционную систему. Заслуженный, а не подаренный. Потому что на этом этапе настоящая система — ровно то, что ему и нужно изучать, и он уже будет знать как.
vi в начале даже не установлен. Его открываешь, пройдя игру, которая учит hjkl как заклинаниям перемещения. По-моему, это лучшая идея во всём дизайне, и я хочу увидеть лицо ребёнка, когда появится /bin/vi. Это фаза 4, вместе с настоящим киоском на каждой ОС, образом для Raspberry Pi и установщиками с подписью и нотаризацией. На выходе — v1.0.
Дальше в списке «позже»: SDK и шаблон для картриджей, чтобы люди делали свои; ненастоящий «модем» для BBS по локальной сети — интернета нет, но два KidDOS в одном Wi-Fi — это отличный урок; и железная коробка.
И отдельно для этой аудитории: русский язык. Все строки вынесены в .ftl с первого дня, кириллица в шрифте уже нарисована, так что перевод — это новый файл строк и папка контента, а не код. Но уроки и диалоги наставника нельзя перевести машинно, их надо писать заново, чтобы машина звучала как персонаж, а не как справочник.
Нужны ли какие-то советы или помощь Клуба?
Да, и это главное, зачем я здесь. Чего я не знаю — нужно ли это кому-нибудь, кроме меня.
Поэтому я спрашиваю людей, которым не всё равно, как учить детей программировать, — тех, кто учился так же, как я, на маленькой машине, на которой нечем было заняться:
- Это хорошая идея?
- Вы бы посадили за это своего ребёнка?
- Вы бы склонировали, запустили и рассказали мне, что из этого вышло? Особенно ценны Windows и Linux: у меня под рукой в основном Mac.
- Если ответ «это уже существует и называется X» — скажите, я лучше воспользуюсь готовым, чем буду строить своё.
- Если среди вас есть учителя или родители, которые готовы придраться к урокам и к тому, как машина разговаривает с ребёнком, — это ровно та ручная работа, которой прототипу не хватает больше всего.
- А если ответ «это ностальгия, и сегодняшним детям ничего из этого не нужно» — я хотел бы услышать этот аргумент в нормальном виде, потому что хорошей версии его я пока не слышал.
Какой совет вы бы сами могли дать идущим по вашим стопам?
- Сначала напишите план, а потом код. Тринадцать разделов, принципы, риски, открытые вопросы. Всё, что в прототипе получилось хорошо, было решено в плане один раз, чтобы больше не спорить. Всё, что получилось криво, — это места, где план сказал одно, а код сделал другое, и у меня хотя бы есть документ, где это записано.
- Заморозьте контракт, а не реализацию. Консольное API — единственное, что видят программы. Оно одинаково для встроенных команд, для Бейсика и для будущего WASM. Планировщик под ним можно переписать целиком, и ни одна игра этого не заметит.
- Делайте маленькое намеренно. Самый большой риск в таблице — «расползание в сторону настоящего Linux». Всё, что требует настоящего ядра, автоматически уезжает в раздел «позже».
- ИИ хорошо строит каркас и плохо пишет душу. Шелл, диск, рендерер, парсер — он сделал за день. Голос наставника, тон ошибок, сюжет квеста — это то, что придётся переписывать руками, и этой работы будет больше, чем всей остальной.
- Скука — это ресурс. Не только для детей. Я сел за этот проект ровно потому, что мне нечего было делать и мигал курсор.
