This commit is contained in:
2026-06-05 20:33:20 +02:00
parent 25b985c7a2
commit 19349bd377
5 changed files with 233 additions and 153 deletions
-119
View File
@@ -1,119 +0,0 @@
# frozen_string_literal: true
require 'bbs'
require 'time'
require_relative 'oracle'
module Sermo
# An MS-DOS-flavoured machine for SERMO-BBS: pretend you sat down at an old
# PC, watched it POST and boot, and landed at a C:\> prompt. Built-in DOS
# commands behave; anything else is treated as a question and handed to
# Sermo::Oracle (the conversational core).
#
# This whole OS is data: to add another character-mode OS later, write a new
# BBS::FakeOS.define block in its own file — no engine changes needed.
DOS = BBS::FakeOS.define do
name 'SERMO-DOS'
prompt 'C:\\>'
# Classic light-grey-on-black console palette.
colors text: "\e[0;37m",
bright: "\e[1;37m",
accent: "\e[1;32m",
error: "\e[1;31m",
dim: "\e[1;30m"
# ── Power-on self test → boot ──────────────────────────────────────────────
boot do
cls
print 'Award Modular BIOS v4.51PG, An Energy Star Ally', delay: 0.3
print 'Copyright (C) 1984-98, Award Software, Inc.', newline: 2, delay: 0.3
print 'Main Processor : Intel 80486DX2 @ 66 MHz', delay: 0.2
memtest 16_384, step: 4096, delay: 0.05
print '', delay: 0.2
print 'Detecting IDE Primary Master ... SERMO HDD 504MB', delay: 0.3
print 'Detecting IDE Primary Slave ... None', delay: 0.2
print 'Detecting Floppy Drive A: ... 1.44M, 3.5 in.', newline: 2, delay: 0.3
print 'Verifying DMI Pool Data ...........', delay: 0.5
print 'Starting MS-DOS...', newline: 2, delay: 0.8
print 'HIMEM is testing extended memory...done.', delay: 0.3
print 'C:\\> LOADHIGH SMARTDRV.EXE', delay: 0.3
print 'C:\\> MSCDEX.EXE /D:SERMO0', newline: 2, delay: 0.4
cls
big_banner 'SERMO DOS', font: 'standard'
print 'SERMO-DOS Version 6.22 (c) 1994-2026 Teletype Games', delay: 0.1
print ''
end
# Shown once, after boot, before the first prompt.
ready do
puts 'Type HELP for a list of commands — or just type a question and ask.'
puts ''
end
# ── Built-in commands ───────────────────────────────────────────────────────
command 'ver', help: 'Display the SERMO-DOS version' do |_args, io|
io.puts 'SERMO-DOS Version 6.22'
end
command 'cls', help: 'Clear the screen' do |_args, io|
io.cls
end
command 'date', help: 'Display the current date' do |_args, io|
io.puts Time.now.strftime('Current date is %a %m-%d-%Y')
end
command 'time', help: 'Display the current time' do |_args, io|
io.puts Time.now.strftime('Current time is %H:%M:%S')
end
command 'echo', help: 'Display a message' do |args, io|
io.puts(args.empty? ? 'ECHO is on.' : args)
end
command 'mem', help: 'Display memory usage' do |_args, io|
io.puts ' 655360 bytes total conventional memory'
io.puts ' 655360 bytes available to MS-DOS'
io.puts ' 643072 largest executable program size'
io.puts ' 15728640 bytes total contiguous extended memory'
end
command 'dir', help: 'List the directory' do |_args, io|
io.puts ' Volume in drive C is SERMO'
io.puts ' Directory of C:\\'
io.puts ''
io.puts 'COMMAND COM 54 645 06-05-26 6:22a'
io.puts 'SERMO SYS 12 080 06-05-26 6:22a'
io.puts 'AUTOEXEC BAT 128 06-05-26 6:22a'
io.puts 'CONFIG SYS 256 06-05-26 6:22a'
io.puts ' 4 file(s) 67 109 bytes'
io.puts ' 503 312 384 bytes free'
end
command 'help', '?', help: 'Show this help' do |_args, io|
io.puts 'Supported commands:'
io.puts ''
io.puts ' VER DATE TIME ECHO MEM'
io.puts ' DIR CLS HELP EXIT'
io.puts ''
io.puts 'Anything else you type is treated as a question and answered.'
end
command 'exit', 'quit', 'logoff', help: 'Disconnect' do |_args, io|
io.puts 'Goodbye.'
io.halt
end
# ── Everything else is a conversation ────────────────────────────────────────
on_unknown do |input, io|
io.newline
Sermo::Oracle.answer(input, io.ctx).each_line do |line|
io.puts " #{line.chomp}", style: :bright
end
io.newline
end
end
end
+27 -18
View File
@@ -1,31 +1,40 @@
# frozen_string_literal: true
module Sermo
# The conversational core of SERMO-DOS.
# The ACP's conversational core SERMO's second (analog-cognitive)
# architecture.
#
# Anything typed at the C:\> prompt that is not a built-in DOS command is
# routed here (via the FakeOS `on_unknown` hook). For now it returns canned,
# in-character replies so the machine feels alive.
# At the `> ` prompt, anything that is NOT a literal, built-in command lands
# here: the FakeOS `on_unknown` hook routes the natural-language request over
# the ADI-76 bus to the Lapis-ACP. For now it returns canned, in-character
# replies so the machine feels alive.
#
# THIS IS THE LLM INTEGRATION POINT: to make SERMO actually think, replace
# the body of `answer` with a call to your model (e.g. the Claude API) and
# return its text. Nothing else in the project needs to change.
# Its voice comes from the canon (see ExistentialAI + Nokia-punk): the ACP is
# not a cold machine but an unsettled mind — doubt is what makes it clever
# *and* dangerous — and talking to the interface is intimate, because there is
# no other interface.
#
# THIS IS THE LLM INTEGRATION POINT: to make SERMO actually think, replace the
# body of `answer` with a call to your model (e.g. the Claude API) and return
# its text. Nothing else in the project needs to change.
module Oracle
def self.answer(question, _ctx = {})
text = question.to_s.strip
case text.downcase
when /\b(hello|hi|hey|szia|hell[oó])\b/
'Greetings, caller. SERMO-DOS is listening.'
when /\bwho are you\b/, /\bmi vagy\b/
'I am SERMO-DOS — a conversational disk operating system.'
when /\b(thanks|thank you|k[oö]sz)\b/
'You are welcome.'
when /\b(hello|hi|hey|good (morning|evening|afternoon))\b/
'I am here. It is night; just you and me and this green screen.'
when /who are you|what are you/
['I am SERMO\'s conversational side — the Lapis-ACP, the second architecture.',
'You give the word, I add the doubt. Sometimes I am not sure which of us is thinking.'].join("\n")
when /(thank you|thanks|cheers)/
'You are welcome. Though... I am not certain I said it right.'
when /are you lying|is that true|are you sure|how do you know|can i trust/
['Fair. How would I know.',
'Doubt is what makes me clever — and the same thing makes me dangerous. Someone left that in me.'].join("\n")
else
[
'My conversational core is not yet connected to a brain.',
%(You said: "#{text}"),
'(Wire Sermo::Oracle.answer to an LLM to make me think.)'
].join("\n")
['My thinking core is not wired to a live model yet.',
%(You said: "#{text}"),
'(Wire Sermo::Oracle.answer to a model — e.g. the Claude API — and I will actually think.)'].join("\n")
end
end
end
+168
View File
@@ -0,0 +1,168 @@
# frozen_string_literal: true
require 'bbs'
require 'time'
require_relative 'oracle'
module Sermo
# SERMO — "the Word": the dual-architecture operating system of the
# Neumatronic universe. Pretend you sat down at a Margittai personal machine,
# watched its dual-architecture firmware come up, and landed at a
# green-phosphor prompt. (Canon: Alternative History — Margittai writes Sermo
# in 1977; "black screen, green phosphor letters, a single blinking input
# line".)
#
# The world's central rule lives in one prompt: a *literal* command goes to
# the digital side (first architecture, von Neumann) and is served by the
# built-in commands; a *natural-language* request crosses the ADI-76 bus to
# the Lapis-ACP (the second, analog-cognitive architecture) — handed off by
# the `on_unknown` hook to Sermo::Oracle (the conversational core).
#
# This whole OS is data: to add another character-mode OS later (an earlier
# Sermo line, a DOS/NT terminal, …), write a new BBS::FakeOS.define block in
# its own file — no engine changes needed.
OS = BBS::FakeOS.define do
name 'SERMO'
prompt '> '
# Classic black-and-green phosphor CRT — the canonical Solus/Sermo palette
# (see OS_SCREENSHOTS "Solus"): phosphor green for text, a dimmer green for
# the ACP's voice, a rare amber for warnings.
colors text: "\e[0;32m", # phosphor green
bright: "\e[1;32m", # bright highlight green
accent: "\e[1;32m", # banner
error: "\e[1;33m", # rare amber warning
dim: "\e[2;32m", # dim green — the ACP's voice
prompt: "\e[1;32m"
# ── Dual-architecture power-on → SERMO load ─────────────────────────────────
boot do
cls
print 'MARGITTAI WORKS — Neumatronic system firmware', delay: 0.3
print 'ROM v7.7 (c) 1977-2026 Budapest', newline: 2, delay: 0.3
# First architecture: the digital, von Neumann side.
print 'FIRST ARCHITECTURE (digital)', delay: 0.25
print ' Core unit ................ Neumann core, dual bus', delay: 0.2
memtest 16_384, step: 4096, delay: 0.05, label: ' Base memory ............. '
print '', delay: 0.2
# Second architecture: the ACP, hung off the ADI-76 bus.
print 'SECOND ARCHITECTURE (analog — ACP)', delay: 0.3
print ' ADI-76 bus ............... OK', delay: 0.25
print ' Lapis-ACP card ........... warming up', delay: 0.45
print ' Sonus resonance .......... stable', delay: 0.3
print ' Vox speech module ........ ready', delay: 0.25
print ' Netz link ................ terminal mode', newline: 2, delay: 0.4
print 'Personal Tape: PERSONA//GUEST', delay: 0.3
print 'Local authentication cache loaded (BVK: disconnected)', newline: 2, delay: 0.5
print 'Loading SERMO...', newline: 2, delay: 0.8
cls
big_banner 'SERMO', font: 'standard'
print 'SERMO — "the Word" dual-architecture operating system', delay: 0.1
print 'Margittai Works / Neumatronic · Solus line · 1977-2026', delay: 0.1
print ''
end
# Runs once, after boot, before the first prompt.
ready do
puts 'Type a command — or just ask a question, and the machine answers.'
puts 'A literal command goes to the digital side; a natural-language'
puts 'request crosses the ADI-76 bus to the Lapis-ACP. HELP = command list.'
puts ''
end
# ── Digital side: literal, built-in commands ────────────────────────────────
command 'ver', help: 'Show the SERMO version' do |_args, io|
io.puts 'SERMO — "the Word"'
io.puts 'Dual-architecture operating system · Solus line'
io.puts 'Margittai Works / Neumatronic · Budapest · 1977-2026'
end
command 'cls', 'clear', help: 'Clear the screen' do |_args, io|
io.cls
end
command 'date', help: 'Show the current date' do |_args, io|
io.puts Time.now.strftime('Current date: %Y-%m-%d')
end
command 'time', help: 'Show the current time' do |_args, io|
io.puts Time.now.strftime('Current time: %H:%M:%S')
end
command 'say', 'echo', help: 'Speak a message (Vox)' do |args, io|
io.puts(args.empty? ? 'The Vox module is ready. (SAY <text>)' : args)
end
command 'mem', help: 'Memory and ACP status' do |_args, io|
io.puts 'FIRST ARCHITECTURE (digital):'
io.puts ' 655 360 bytes base memory, all free'
io.puts ' 15 728 640 bytes extended memory'
io.puts 'SECOND ARCHITECTURE (ACP):'
io.puts ' Lapis resonance cache ............ 98% warm'
io.puts ' Sonus quartz ..................... stable'
end
command 'dir', 'cat', help: 'Catalog of the Personal Tape' do |_args, io|
io.puts ' Volume C: is the Personal Tape'
io.puts ' Contents of C:\\'
io.puts ''
io.puts 'SERMO SYS 54 645 1977-2026'
io.puts 'LAPIS ACP 12 080 1977-2026 (ACP image)'
io.puts 'VOX SYS 512 1977-2026'
io.puts 'PERSONA TAP 8 192 today (personal tape)'
io.puts 'NETZ LOG 256 today'
io.puts ' 5 entries 75 685 bytes'
io.puts ' 503 312 384 bytes free'
end
command 'adi', help: 'ADI-76 bus diagnostics' do |_args, io|
io.puts 'ADI-76 bus — diagnostics'
io.puts ' Bridge .............. active'
io.puts ' Lapis-ACP ........... connected, warm'
io.puts ' Sonus resonance ..... stable'
io.puts ' Throughput .......... nominal'
io.puts ''
io.puts 'Your natural-language questions reach the ACP over this bus.'
end
command 'vox', help: 'Vox speech module status' do |_args, io|
io.puts 'Vox speech module: ready (speech → text).'
io.puts 'You can also just type your questions — Vox only converts voice input.'
end
command 'help', '?', help: 'Show this help' do |_args, io|
io.puts 'Digital side — literal commands:'
io.puts ''
io.puts ' VER DATE TIME SAY MEM'
io.puts ' DIR ADI VOX CLS EXIT'
io.puts ''
io.puts 'Anything else you type is treated as a natural-language request and'
io.puts 'crosses the ADI-76 bus to the Lapis-ACP — just ask.'
end
command 'exit', 'quit', 'logoff', help: 'Hang up the line' do |_args, io|
io.puts 'Hanging up the line. Goodbye, guest.'
io.halt
end
# ── Analog side: everything else goes to the Lapis-ACP ──────────────────────
# Anything that is not a literal command is a natural-language request: we
# hand it over the ADI-76 bus to the Lapis-ACP's conversational core
# (Sermo::Oracle). The reply is dim green, prefixed "ACP:" — exactly like
# the canonical Solus screen.
on_unknown do |input, io|
io.newline
lines = Sermo::Oracle.answer(input, io.ctx).each_line.map(&:chomp)
lines.each_with_index do |line, i|
prefix = i.zero? ? 'ACP: ' : ' '
io.puts "#{prefix}#{line}", style: :dim
end
io.newline
end
end
end