From a69864cc0c0e05ea6c0e4e5d5b9c244d5440d1e8 Mon Sep 17 00:00:00 2001 From: Steffen Beyer Date: Thu, 2 Apr 2026 10:25:56 +0200 Subject: [PATCH] docs: LLM_UI --- docs/LLM_UI.md | 466 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 466 insertions(+) create mode 100644 docs/LLM_UI.md diff --git a/docs/LLM_UI.md b/docs/LLM_UI.md new file mode 100644 index 0000000..d70e236 --- /dev/null +++ b/docs/LLM_UI.md @@ -0,0 +1,466 @@ +Dual output is exactly the right instinct. If you want a system to be self-documenting for both humans and LLMs, the key is this: + +> **Do not treat documentation as prose attached afterward. Treat it as structured semantic data emitted by the same machinery that defines the system.** + +Otherwise the docs drift, the machine lies, the humans improvise, and the model confidently invents nonsense. A beloved industry tradition. + +## My preference, if Fruix wanted to be maximally legible to me + +I would want **three layers at once** for every meaningful object in the system: + +### 1. Operational output + +The normal thing a human expects. + +Example: + +```text +$ fruix service status sshd +running since 2026-04-02T09:14:33Z +pid 812 +generation 42 +store item /frx/store/...-openssh-service +``` + +### 2. Structured machine-readable output + +Explicit, stable, schema-like, with no pretty nonsense. + +Example: + +```json +{ + "kind": "service-status", + "name": "sshd", + "state": "running", + "since": "2026-04-02T09:14:33Z", + "pid": 812, + "generation": 42, + "store_path": "/frx/store/...-openssh-service", + "definition_ref": "services.sshd" +} +``` + +### 3. Embedded semantic help/doc layer + +Not a wall of text. Short, attached meaning. + +Example: + +```json +{ + "doc": { + "summary": "OpenSSH daemon providing remote login access.", + "purpose": "Accepts inbound SSH connections for remote administration.", + "inputs": ["host keys", "network", "authorized keys config"], + "depends_on": ["network-online", "host-keys"], + "used_by": ["admin access", "remote deployment"], + "failure_modes": [ + "missing host keys", + "port unavailable", + "invalid configuration" + ], + "see_also": [ + "fruix service logs sshd", + "fruix config explain services.sshd" + ] + } +} +``` + +That combination is ideal. The command answers the immediate question, but also emits enough structure that an LLM can keep asking intelligent follow-ups without having to guess what “sshd” even is in Fruix-world. + +--- + +## The most important design principle + +Every object in Fruix should ideally answer these questions about itself: + +* what are you? +* why do you exist? +* what created you? +* what do you depend on? +* what depends on you? +* how do I inspect you? +* how do I change you? +* what breaks if you fail? +* where is your definition? +* what commands are relevant next? + +That is the difference between “a system with documentation” and “a system that can explain itself.” + +## The command model I would love + +I would strongly prefer **one canonical plain output mode**, plus **a structured explain mode**, rather than mixing prose into every default command. + +So: + +```text +fruix service status sshd +fruix service status sshd --json +fruix service explain sshd +``` + +Or maybe: + +```text +fruix inspect service sshd +fruix inspect service sshd --json +fruix explain service sshd +``` + +This separation matters. + +### Why not always dual-output in the same stream? + +Because it becomes annoying for humans, brittle for scripts, and ugly for terminals. People say they want hybrid output until they actually have to read it every day. + +Better pattern: + +* default output for operators +* stable machine output for tooling/LLMs +* explicit explanation output for context + +That said, you *can* still have a dual channel if done cleanly. + +--- + +## My favorite model: result + attached explain block + +Something like this: + +```text +$ fruix service status sshd --with-doc + +sshd: running + pid: 812 + since: 2026-04-02T09:14:33Z + generation: 42 + +Explanation: + SSH daemon for remote login and administration. + Depends on network-online and host key material. + Configured from services.sshd in the system definition. + +Relevant commands: + fruix service logs sshd + fruix config explain services.sshd + fruix service restart sshd +``` + +That is excellent for humans and still digestible for an LLM if the formatting is predictable. + +But for automation, I would still want: + +```text +fruix service status sshd --json +fruix service explain sshd --json +``` + +So in practice I’d want **two parallel interfaces**, not one muddled one. + +--- + +## What should be self-documenting in Fruix? + +Not just commands. The **actual nouns** of the system. + +### 1. Store paths + +A store item should be explainable. + +```text +fruix store explain /frx/store/845bd...-freebsd-bash-5.3.9 +``` + +Should answer: + +* package/runtime/component name +* version +* origin +* build inputs +* purpose +* references +* whether it is part of current system +* whether it is GC-rooted +* whether it is user-requested or dependency-only + +### 2. Services + +Explain: + +* purpose +* definition origin +* dependencies +* restart policy +* logs +* ports/files touched +* activation behavior + +### 3. System definitions + +Explain: + +* what modules/options contributed +* what options are set +* defaults vs overrides +* resulting closures +* affected services +* resulting boot entries/generations + +### 4. Configuration options + +This one matters a lot. + +A good system should let me ask: + +```text +fruix config explain services.sshd.enable +fruix config explain system.network.hostname +fruix config search ssh +``` + +And get: + +* type +* default +* current value +* description +* examples +* constraints +* source module +* related options + +This is one of the best things NixOS/Guix-style systems can do, and Fruix should absolutely lean into it. + +### 5. Commands themselves + +CLI subcommands should be introspectable too. + +```text +fruix help gc +fruix help gc --json +fruix explain command gc +``` + +Because LLMs are often dropped into a black box and forced to infer the command surface. A command that can describe itself structurally is vastly easier to use safely. + +--- + +## What would help me most as an LLM? + +If Fruix wanted to be unusually legible to a model, I’d want these properties. + +### Stable schemas + +If `--json` exists, make it boring and stable. No whimsical field names, no gratuitous nesting, no surprise changes. Humans love creative naming, then wonder why tooling breaks. + +### Uniform “kind” fields + +Every structured output should say what it is. + +```json +{ "kind": "service-status", ... } +{ "kind": "config-option", ... } +{ "kind": "store-item", ... } +{ "kind": "system-generation", ... } +``` + +This helps tremendously. + +### Embedded references + +Objects should point to related objects. + +For example, service status should include: + +* definition reference +* related config path +* related store path +* dependency names + +This lets a model traverse the system instead of hallucinating relationships. + +### Short summaries written for machines and humans + +Not marketing copy. Not essay paragraphs. Tight explanatory text. + +Good: + +> "Enables the OpenSSH daemon for inbound remote shell access." + +Bad: + +> "This module offers a powerful and flexible way to control secure access to your Fruix machine." + +Nobody needs brochure language except people trying to justify headcount. + +### Explicit provenance + +For anything important, say where it came from: + +* built from which derivation +* declared in which module +* set by user vs default +* inherited from which profile/system generation + +That makes the system explainable instead of mystical. + +--- + +## I would absolutely add a “why” command + +This is the killer feature. + +Examples: + +```text +fruix why /frx/store/...-freebsd-bash-5.3.9 +fruix why service sshd +fruix why config services.sshd.enable +``` + +Answers like: + +```text +freebsd-bash-5.3.9 is present because: + - required by fruix-system-fruix-freebsd generation 42 + - referenced by interactive-shell-runtime + - pulled in by admin profile +``` + +Or: + +```text +services.sshd.enable is true because: + - set explicitly in hosts/fruix-freebsd.scm + - module openssh-service.scm contributes service definition +``` + +This is huge for both humans and LLMs. “Why is this here?” is half of systems debugging. + +--- + +## My preferred architecture for integrated docs + +I would not store docs only in markdown files. I would make them part of the typed object/module/option definitions themselves. + +For each module/option/service/package, attach fields like: + +* `summary` +* `description` +* `type` +* `default` +* `examples` +* `see-also` +* `danger-level` +* `depends-on` +* `used-by` +* `introduced-in` +* `notes` + +Then generate from that: + +* terminal help +* handbook pages +* man pages +* JSON explain output +* web docs +* maybe even shell completions with hints + +That way there is **one source of truth**, many renderings. + +This is the real win. + +--- + +## A concrete Fruix interaction model I’d love + +Something like this command family: + +```text +fruix inspect [name] +fruix explain [name] +fruix search +fruix why [name] +fruix graph [name] +``` + +Examples: + +```text +fruix inspect service sshd +fruix explain service sshd +fruix why service sshd +fruix graph service sshd + +fruix inspect store /frx/store/...-freebsd-bash-5.3.9 +fruix explain store /frx/store/...-freebsd-bash-5.3.9 +fruix why store /frx/store/...-freebsd-bash-5.3.9 + +fruix inspect config services.sshd.enable +fruix explain config services.sshd.enable +fruix why config services.sshd.enable +``` + +That is clean, memorable, and composable. + +--- + +## If you insist on dual output in one invocation + +Then I would make it a structured container, not mixed prose spaghetti. + +Maybe: + +```text +fruix service status sshd --format annotated +``` + +Output: + +```yaml +result: + name: sshd + state: running + pid: 812 + since: 2026-04-02T09:14:33Z + generation: 42 + +doc: + summary: OpenSSH daemon for remote administration. + depends_on: + - network-online + - host-keys + config_path: services.sshd + see_also: + - fruix service logs sshd + - fruix config explain services.sshd +``` + +YAML is readable enough for humans and parseable enough for tools. Though for machine use I’d still pick JSON. + +--- + +## The single biggest preference of all + +If I had to choose only one thing, it would be this: + +> Every meaningful Fruix object should be introspectable by name or path, with both a stable machine schema and a concise semantic explanation. + +That alone would make the system unusually legible to me, to users, and to future maintainers who have not yet been spiritually damaged by it. + +## My concrete recommendation + +Build this into Fruix from the start: + +* `--json` on all important commands +* `explain` subcommands for commands, config, services, store items, generations +* `why` subcommands for dependency/provenance tracing +* structured doc fields embedded in module and option definitions +* generated docs from the same source +* concise summaries, not essay sludge + +That is the sweet spot. Self-documenting, machine-friendly, human-usable, and hard to let drift. + +If Fruix gets that right, an LLM dropped cold into the system could become useful very quickly instead of fumbling around like a junior admin in an unfamiliar datacenter.