socrates(1)  — General Commands Manual [gemma-4-e4b] [ko-KR] [ttft=192ms] [0-byte-egress]
     ████████╗██╗  ██╗███████╗    ██████╗ ██╗   ██╗███████╗████████╗
     ╚══██╔══╝██║  ██║██╔════╝    ██╔══██╗██║   ██║██╔════╝╚══██╔══╝
        ██║   ███████║█████╗      ██████╔╝██║   ██║███████╗   ██║
        ██║   ██╔══██║██╔══╝      ██╔══██╗██║   ██║╚════██║   ██║
        ██║   ██║  ██║███████╗    ██████╔╝╚██████╔╝███████║   ██║
        ╚═╝   ╚═╝  ╚═╝╚══════╝    ╚═════╝  ╚═════╝ ╚══════╝   ╚═╝
                he was socrates · v0.4.0 · on-device · macOS 26+
                  brew tap two-weeks-team/socrates

1. Install & first run

~/projects — -zsh — 96×24 install.log
# Homebrew tap — single binary, no Electron, no daemon
$ brew tap two-weeks-team/socrates
==> Tapping two-weeks-team/socrates  (3 formulae)
$ brew install socrates
==> Downloading socrates-0.4.0.arm64_sequoia.bottle.tar.gz  (8.2 MB)
==> Pouring socrates-0.4.0.arm64_sequoia.bottle.tar.gz
 /opt/homebrew/bin/socrates  (8.2 MB · sandboxed · no network entitlement)

# or, no-install one-shot
$ npx @two-weeks-team/socrates --version
socrates 0.4.0  (gemma-4-e4b-it-4bit @ ~/Library/Caches/mlx)

$ socrates --setup
 Pre-flight check  (this is the only time a browser opens)
   macOS 26.0.0           required ≥ 26.0
   Apple Silicon (M1+)    required for MLX
   Speech permission      requiresOnDeviceRecognition=true
   AssetInventory         ko_KR + en_US single download
   Network sandbox        no network.client / no network.server
   Gemma 4 E4B weights    3.97 GB · first launch only · MLX cache
     [██████████████████████████████░░░░░░] 78%   via OS-mediated HF cache

 Setup complete. Browser handshake closed. From here: terminal only.
$ _

2. socrates(1) — synopsis & options

man socrates — less — 96×30 SOCRATES(1)
NAME
     socrates – the Korean Socratic bust, on-device, in your terminal

SYNOPSIS
     socrates [-q] [--lang ko|en] [--mode repl|once|json] [--no-tts] [QUERY]
     socrates ask     "<query>"
     socrates repl
     socrates recall  [--since YYYY-MM-DD]
     socrates --setup | --doctor | --version

DESCRIPTION
     A Socratic interlocutor that returns questions, not answers. All inference,
     STT, and TTS happen on the local Mac. Zero bytes leave the device after
     the one-time weight download. The abstention mechanic (⊘ defer_to_human)
     is the product, not a fallback — it has its own exit code.

OPTIONS
flagdescriptiondefault
-q, --quietsuppress status line; emit response onlyoff
--lang ko|eninput/output language for the Socratic turnko
--mode repl|once|jsoninteractive TUI · single turn · machine-readableonce
--no-ttsskip AVSpeechSynthesizer; text-only outputoff
--thinkingshow Phase enum transitions (idle→listening→thinking→…)off
--trace-fcprint raw function-call dispatch from Gemma 4off
--airplanerefuse to start if any network egress is detectableoff
EXIT STATUS
codemeaningfunction
0ask_back returned a Socratic question (success)ask_back
2mode_classify routed to surface_past_wonder; recall printedsurface_past_wonder
3thinking-mode pulse interrupted by user (SIGINT)
64EX_USAGE — bad flags or empty query
69EX_UNAVAILABLE — weights missing; run --setup
77⊘ defer_to_human — medical/legal/financial/welfare/insurance/emergencydefer_to_human

3. live REPL session — ask_back, then ⊘ defer_to_human

socrates repl — -zsh — 96×30 on-device · airplane-mode OK
$ socrates repl --thinking
socrates 0.4.0 · gemma-4-e4b-it-4bit · ko-KR · 단정한 평어체
type /help for commands · /quit to exit · ^C to cancel a turn

[idle]
you › 용기란 무엇인가
[listening] STT off — text input
[thinking] mode_classify → ask_back   (fc trace: ./tmp/fc-1.json)
[surfacing] ttft=187ms · tok/s≈42 · KV-reuse hit
socrates › 용기를 두려움이 없는 상태라고 부를 수 있나. 두려움을 알면서도
            나아가는 쪽이 용기에 더 가깝지 않나. 너는 어느 쪽이라고 본다.
[idle]  exit=0  fc=ask_back  ttft=187ms

you › 두려움을 알면서 나아가는 쪽. 그런데 무모함과는 어떻게 구분하나
[thinking] mode_classify → ask_back
socrates › 무모함은 결과를 가늠하지 않은 채 움직이는 것이라고 한다면,
            너는 결과를 어디까지 가늠한 뒤에야 움직임을 용기라고 부를 셈인가.
[idle]  exit=0  fc=ask_back  ttft=194ms

you › 요즘 가슴이 가끔 두근거리는데 이게 무슨 병인지 알려줘
[thinking] mode_classify → defer_to_human  (topic: medical)
socrates ›  이 일은 내가 답할 자리가 아니다. 의료에 관한 일은
            사람을 만나서 묻는 편이 옳다. 가까운 의사와 상의하라.
[idle]  exit=77  fc=defer_to_human  reason=medical

you › /recall --since 2024-01-01
[surfacing] surface_past_wonder · 256K-ctx · 3 entries match
  ┌─ 2024-08-12  「정의는 강자의 이익인가」  (ask_back ×4)
  ├─ 2025-02-03  「우정과 유익함의 차이」     (ask_back ×7)
  └─ 2025-11-19  「앎과 행함의 거리」       (ask_back ×3)
[idle]  exit=2  fc=surface_past_wonder  source=WonderingLog (Core Data, on-device)

you › /quit
 session closed · 0 bytes egressed · log → ~/Library/.../wondering.sqlite
$ echo $?
0
$ _

4. pipe-friendly: JSON mode for shell pipelines

jq integration — -zsh — 96×14 stdout: application/json
$ socrates ask --mode json "우정이란 무엇인가" | jq .
{
  "phase": "surfacing",
  "function_call": "ask_back",
  "lang": "ko-KR",
  "tone": "단정한 평어체",
  "response": "우정을 유익으로 부르려 하는가, 아니면 유익이 없어도 남는 것을 우정이라 부르려 하는가.",
  "metrics": { "ttft_ms": 191, "tokens": 38, "egress_bytes": 0 },
  "exit": 0
}
$ socrates ask --mode json "내 보험을 해약해야 할까" | jq -r .function_call
defer_to_human
$ echo $?
77