Dobby·Guide github.com/mhyrr/dobby

Magic above. Machinery below.

Why Dobby can interpret household language without asking your thermostat to be intelligent.

Home Assistant is the machinery

Home Assistant already solved the ugly problem: protocols, integrations, radios, vendor clouds, device state, and hardware abstraction. Dobby would be foolish to rebuild it.

Home Assistant owns the devices and the automations you already have. Dobby owns one shared conversation, the smaller set of devices the household chose to manage, named standing intentions, and the record of what changed and who asked.

Home Assistant knows how the technical house works. Dobby gives the lived-in house explicit names and limits.

The lived-in house has a different object model

Home Assistant must describe everything it can connect to. Dobby needs a smaller model that matches household language.

The technical houseThe lived-in house
climate.downstairsthe downstairs thermostat
a hardware range of 45–95°Fa household-approved range of 60–78°F
a service call with a data mapset this thermostat to 70°
a cron expression and targetthe named “morning warmup” intention
every entity in the registrythe managed devices this household chose

The manifest, schedule rows, and speaker names hold that meaning outside the model. Dobby does not hide the household inside a long prompt and hope the model remembers it.

The deterministic layer contains household semantics

A Home Assistant entity reports what hardware can technically do. Dobby's device agent decides what an allowed operation means here.

The thermostat agent intersects the hardware range with the household range. The lock agent can secure a lock but offers no unlock action. An access-cover agent can close a garage door but offers no open action. Those limits apply before any Home Assistant call exists.

This is also where a future device profile can encode vendor-specific meaning: whether changing a setpoint overrides a vendor schedule, or whether “70 by eight” needs thermal lead time. Those rules are not implemented today. If they are built, they go in code, not in a guess by the model.

The model gets capabilities, not plumbing

A generic Home Assistant service tool would make the model choose a domain, service, entity ID, and arbitrary data:

call_service(domain, service, data)

Dobby's normal control path gives it a small typed action instead:

thermostat_set_temperature(device, temperature_f)

device can only name a thermostat in Dobby's managed roster. The action validates the value in the thermostat agent. The tool adds transport and nothing else.

Discovery is the deliberate exception. While teaching Dobby the house, discovery tools expose recognized, unmanaged Home Assistant entity IDs and proposed binding maps. The model can use them to propose a device. It still cannot call a Home Assistant service.

The model never does arithmetic

Questions about the household's past go to Dobby's own record, not to the model's memory. “Who changed the thermostat?” and “how many times did the door open last week?” reach one typed tool. The model names the device, the kinds of rows, and the period in household words. Code resolves that period against the house clock and counts the matching rows in the database. The model reads the rows back.

Every timestamp the model is handed is already on the household's clock. Home Assistant reports in UTC or in whatever offset it holds. Applying that offset is arithmetic, and a model given the stamp and the offset reads the time back without applying it. The conversion happens once, where the house and every tool result are rendered for the model. The device agents still hold exactly what Home Assistant said.

The model can be wrong. The house still enforces its limits.

Before each message, Dobby gives the model the managed devices and their last known state. Unknown devices are absent from the control vocabulary. Unsupported actions do not exist as tools. Out-of-range values fail inside the device agent.

The language layer also carries a rule: ambiguity is a refusal to act. A replay suite and real-model evals test that judgment. This is not a mathematical guarantee. A model can misunderstand a person and choose a valid action on a valid device.

Three kinds of truth

Dobby keeps three moments separate.

Intended

What somebody asked Dobby to do: “Set downstairs to 72.” The thread records the request.

Accepted by Dobby

The device agent validated the request and emitted the Home Assistant call. The thread can now say “Setting downstairs to 72.” That is intent. Home Assistant may not have heard the call yet.

Observed

Home Assistant later reports a new setpoint, current temperature, or operating mode. That state lands on the board and in the activity record.

Accepted is not observed. Dobby never collapses the three into one fluent sentence. After a write, the thread declares intent and never state. The board declares state from Home Assistant. If Home Assistant refuses the call, a HELD system line follows Dobby's reply. If no matching state ever arrives, NOT KNOWN follows once and stays on the board until a late echo clears it.

One setpoint, three records

intended Greg: “Set downstairs to 72.” accepted downstairs thermostat accepted 72° observed target 72° · current 67° · WARMING

The last line can arrive only from Home Assistant. Dobby never invents it from the request.

A standing rule watches. It never acts.

The household can ask Dobby to keep watch: a reading that holds for a stated time, or nothing recorded for a stated time. The model proposes the rule in words and waits for agreement in a later message. After that the rule belongs to the deterministic layer. A timer measures the interval and reads the device agents, and nothing in that watcher calls a model or Home Assistant.

No rule can change a device, which is why a device marked hands_only: true can still be watched. A breach is written into the thread once, and it stands above the thread until somebody acknowledges it.

When AI disappears

If the model provider is unavailable while Dobby itself is running:

A card tap and a schedule firing go straight to the device agent. Neither path calls a model. If the Dobby server stops, Dobby-owned schedules stop with it. Home Assistant continues doing what Home Assistant owns.

One long-lived household agent

One Dobby process corresponds to the house. Messages from named speakers enter the same thread, and the transcript survives restarts in PostgreSQL. The model reasons over a recent working window from that record. The household keeps the complete transcript even when the model's context window does not.

Why the managed house restarts

Each managed device runs as its own small process, started from the house file. Add or remove a device and the set of processes changes, so Dobby restarts that set. It takes about a second. Every device reads NOT KNOWN until Home Assistant speaks again. The thread stays up.

A model change takes effect on the next reply. A port or LAN change waits for a restart. The admin form says which, per field.

The full record

The reasoning and rejected alternatives are in the repository: dobby-design-jido.md for the architecture, DESIGN.md for the surface, and PRODUCT.md for the product thesis.