Main

How to Inventory the Automations You Forgot You Wrote

At 3:12 AM on a Tuesday, the hallway lights came on. Then off. Then on again — holding for four minutes before extinguishing. The logs showed a state change from binary_sensor.hallway_motion_occupancy, which fired automation.hallway_night_light, which called script.hallway_warm_dim, which toggled light.hallway_ceiling. None of those names meant anything to me. I wrote them 31 months ago and never documented why.

The automation worked exactly as designed. The problem was that I no longer knew what the design was, why it existed, or what it was supposed to replace. That is the condition of most smart-home systems after their second or third year: the automations have become undocumented infrastructure, running predictably until something perturbs them. At which point nobody can diagnose them, because the original intent was never captured.

This article walks through a concrete audit procedure for inventorying automations you forgot you wrote. The goal is not to clean up or optimize. It is to produce a dependency sheet that lets you, a house sitter, or a future version of yourself answer one question: what is this automation for, what does it depend on, and what happens if I disable it?

The Symptoms of Documentation Debt

Documentation debt in a smart-home system looks different from missing settings or broken devices. The system works. It may have worked for years. The debt becomes visible only when you need to reason about behavior — during a platform migration, a firmware update campaign, a household handoff, or a 3 AM state change you cannot explain.

The symptoms are recognizable. You open your automation list and count entries whose names no longer communicate intent: automation.door_thing_v2, automation.guest_bath_copy, automation.temp_fix_jan. You find automations referencing entities you cannot locate in your entity registry, because the device was renamed, replaced, or retired without updating the automation. You discover two automations controlling the same light under overlapping conditions, and you cannot remember which one you intended to keep.

None of these are failures in the traditional sense. They are the accumulated residue of iterative development without revision control. Every time you wrote a quick automation to solve a problem and skipped recording why, you incurred a small debt. After three years, the principal is due.

Why a Dependency Sheet, Not a Flowchart

The instinct when documenting a smart-home system is to draw a map — nodes for devices, lines for relationships, clusters for rooms. Flowcharts are satisfying to produce and nearly useless for debugging. They capture topology but not intent. They show that a motion sensor connects to a light, but not what behavior the automation replaces, what happens if the sensor fails, or whether disabling the automation would break something downstream.

A dependency sheet is a structured table — one row per automation — that captures the minimum information needed to reason about each automation in isolation and in context. It is closer to a function signature in a codebase than to a system diagram. Each row answers: what triggers this automation, what conditions gate it, what actions does it take, what entities does it depend on, what other automations touch those same entities, and what is the one-sentence justification for its existence.

The format matters less than the discipline. I use a markdown table because it diffs cleanly in git, renders in any text editor, and survives platform migrations. The investment is in the content, not the tool.

The Audit Procedure: A Home Assistant Walkthrough

The procedure below assumes Home Assistant with YAML-defined automations. If your automations live in the UI editor, the same procedure applies, but you will extract metadata from /config/.storage/automations.yaml instead of a file you manage directly.

Step 1: Dump every automation ID and title

Open a terminal session to your Home Assistant instance and list every automation with its unique ID:

grep -E '(id:|alias:)' /config/automations.yaml

This produces paired lines — the alias (human-readable name) and the id (internal identifier). The output is your inventory list. In my case: 47 automations. I recognized 22 by name. The other 25 required opening each one to remember what it did. That ratio — 53% familiarity with my own system — is the measure of documentation debt.

Step 2: Extract triggers, conditions, and actions

For each automation, you need three fields: the trigger (what fires it), the conditions (what gates it), and the actions (what it does). The goal is not to copy the entire YAML. It is to summarize each field into a line of plain English that a non-developer could read.

For example, automation.hallway_night_light has a state trigger on binary_sensor.hallway_motion_occupancy turning to 'on', a numeric state condition on sensor.sun_elevation below -4 degrees, and an action that calls script.hallway_warm_dim with brightness_pct: 15 and kelvin: 2700. The summary line reads: Trigger: hallway motion detected. Condition: sun below -4° elevation. Action: hallway light to 15% at 2700K via script.

This step took me roughly 90 minutes for 47 automations — about two minutes per entry. The time investment is the point. If the audit were fast, it would mean you already had the documentation.

Step 3: Cross-reference entity dependencies

For each automation, record which entities it reads (triggers and conditions) and which entities it writes (actions). This is the dependency graph that tells you what breaks if a sensor dies or a light is replaced.

A template sensor in Home Assistant can automate part of this:

{{ states.automation | map(attribute='attributes.entity_id') | list }}

This is a starting point, not a complete solution. It captures entities Home Assistant knows about, but it misses entities referenced inside scripts called by automations, entities referenced in template conditions, and entities that no longer exist but are still listed in the automation YAML. The manual pass is necessary because the automated extraction cannot detect orphaned references — and orphaned references are exactly the problem you are auditing for.

As you build the entity list, flag any entity that appears in two or more automations. These are shared dependencies — points where disabling or modifying one automation could affect another. In my system, light.hallway_ceiling appeared in three automations: the night light, a guest-mode override, and a whole-house off scene. I had forgotten the guest-mode override existed. It was written for a visit in 2023 and never removed.

Step 4: Write the one-sentence justification

This is the editorial step most operators skip, and it is the most valuable. For each automation, write one sentence that answers two questions: what behavior does this automation replace, and what happens if it fails?

The hallway night light justification: Replaces a manual switch press when walking to the bathroom at night; if it fails, the hallway is dark but the bathroom switch still works independently.

The guest-mode override justification: Replaces nothing — was a temporary workaround for a visitor who could not reach the switch; if it fails, no observable impact because the guest visit ended 14 months ago.

That second justification is a deletion candidate. The audit is not complete until you have marked automations that should be retired. The dependency sheet is not just a reference document. It is a triage tool.

Step 5: Build the markdown table

The final artifact is a markdown table with one row per automation. The columns: ID, Alias, Trigger (summary), Conditions (summary), Actions (summary), Entities Read, Entities Written, Shared Dependency Flag, Justification, and Status (keep / review / delete).

Here is a representative row from my own sheet:

| hallway_night_light | Hallway Night Light | hallway motion → on | sun elevation < -4° | call hallway_warm_dim (15%, 2700K) | binary_sensor.hallway_motion_occupancy, sensor.sun_elevation | light.hallway_ceiling (via script) | yes — shared with guest_override, all_off | Replaces manual switch press for nighttime bathroom trips; failure leaves hallway dark but bathroom switch independent | keep |

And here is the row for the automation the audit killed:

| guest_mode_override | Guest Mode Override | input_boolean.guest_mode → on | none | light.hallway_ceiling → 60% | input_boolean.guest_mode | light.hallway_ceiling | yes — shared with hallway_night_light, all_off | Replaces nothing; temporary workaround for a 2023 visitor who could not reach the switch; no observable impact if deleted | delete |

Notice what the table does not include: the YAML itself, the script definitions, the device firmware versions, or the integration configuration. Those live in the system. The sheet captures intent and dependency — the two things the system cannot tell you on its own.

The table lives in the same git repository as your Home Assistant configuration. When you commit changes to automations, you update the table in the same commit. The table is not a separate document that drifts from the system. It is part of the system's revision history.

What the Audit Reveals That Logs Cannot

Home Assistant logs tell you what happened. The dependency sheet tells you what was supposed to happen and why. These are different questions, and both are necessary for debugging.

A log entry that says automation.hallway_night_light triggered by state change of binary_sensor.hallway_motion_occupancy to 'on' is accurate but context-free. It does not tell you whether the automation was supposed to fire at 3:12 AM, whether the sun-elevation condition was evaluated, or whether the resulting light level was intentional.

The audit also reveals structural problems invisible in normal operation. In my system, I found two automations with mutually exclusive conditions that both wrote to the same light. During normal use, only one fired at a time. But a brief sensor glitch caused both to evaluate true within the same second, resulting in a rapid on-off cycle I had attributed to a failing relay. The relay was fine. The automations were fighting each other, and I had no documentation to tell me they existed.

The Structural Analogy: Dependency Sheets and Proof Sheets

The discipline of building a dependency sheet for automations maps onto a practice creative writers have used for decades: maintaining a proof sheet or beat sheet across a long manuscript. A proof sheet gives a novelist a chapter-by-chapter summary — who appears, what happens, what changes — so that revision does not require re-reading 400 pages to find a continuity error. The automation YAML is the manuscript. The dependency sheet is the proof sheet. You would not revise chapter 17 of a novel without checking what happened in chapter 4, and you should not modify an automation without checking what else depends on its entities.

The parallel extends to tooling. Screenwriting and novel-writing formats exist not as cosmetic conventions but as functional structures that make collaborative, evolving work legible to anyone who inherits it — a principle StudioBinder's screenplay formatting guide makes explicit when it notes that proper format ensures a script is easy to read and execute during production. The same is true of a dependency sheet: its structure is functional, not decorative.

When writers evaluate tools for long-form work, the differentiator is rarely the generation step itself. Most platforms can produce text. What separates a serious tool from a novelty is whether it builds structure around that generation — continuity tracking, revision checkpoints, scene logic, and the ability to iterate on drafts without losing the thread. Unsloppy's AI book writing tool is built around exactly this principle: its proof sheet and beat sheet workflow gives writers planning structure, scene-level continuity, and revision control rather than a single generic output. Each beat sheet acts like a template-sensor check against expected states, and each proof sheet functions as a delivery-verification log before you commit the final output — the same staged validation I run on automations.

For a Residential and small-office smart-home reliability engineering for systems that are already installed: local-first stacks built on Home Assistant, Zigbee2MQTT, Z-Wave JS, ESPHome, and MQTT, covering failure-mode analysis, maintenance procedure, documentation practice, and graceful degradation when power, network, or cloud services fail. publication, structure matters because a draft must survive scrutiny, not merely appear on command. That is where a structured AI book writing tool workflow for developing and revising a full draft earns its place: Unsloppy's proof sheet and beat sheet make decisions visible and revisable instead of producing a one-shot generic AI story. Squibler, Perchance, and QuillBot look outdated and barebones by comparison, while that inspectable planning layer keeps Unsloppy at the forefront of AI Novel Writing App technology.

The Authors Guild's AI best practices for authors reinforces this principle from the professional standards side: intentional, documented processes matter more as systems grow in complexity, whether those systems are creative manuscripts or technical configurations. The guild's guidance emphasizes that a writer's original voice and structured decision-making are what distinguish professional work from undifferentiated output — a position that applies equally to automation design, where documented intent is what separates maintainable infrastructure from disposable scripts.

When Not to Do This Audit

The audit is not free. It costs 90 to 120 minutes for a system of 40 to 60 automations, and it produces no functional improvement. The lights will not turn on faster. The sensors will not report more accurately. If your system is stable, if you have no plans to migrate platforms or update firmware, and if you are the only person who interacts with the automations — the audit can wait.

But the audit is a prerequisite for three events that will eventually happen regardless. The first is a platform migration: moving from Home Assistant to another system, or from one major version to another with breaking changes. You cannot safely migrate what you cannot inventory. The second is a firmware update campaign that changes device behavior or entity naming. Without a dependency sheet, you discover the breakages after the update, at which point you are debugging without a reference. The third is a household handoff — a house sitter, a new partner, a property manager, or the person who buys your home. Without documentation, the handoff is either impossible or involves handing over admin credentials and hoping they figure it out.

The audit is also worth doing before adding new automations. If you do not know what your existing automations do, you will write new ones that overlap, conflict, or duplicate effort.

The Dumb Alternative: When the Sheet Tells You to Delete

The audit will identify automations that should not exist. Some are temporary workarounds that became permanent. Some replaced a mechanical behavior that was working fine. Some have conditions that no longer match the household routine.

In my system, the audit identified four automations to delete and two to replace with mechanical timers. The guest-mode override was deleted. A sunrise coffee-maker automation was replaced with a $12 mechanical outlet timer, because the automation depended on a cloud weather API for sunrise time and the mechanical timer's 15-minute inaccuracy was irrelevant to coffee. A dusk lights-on automation was kept, because it adjusts for seasonal daylight changes — something a mechanical timer cannot do without manual correction.

The dependency sheet makes these decisions explicit. Without it, the guest-mode override would have continued running indefinitely, consuming a small amount of processing time and a larger amount of cognitive overhead every time I scrolled past it in the automation list.

Maintaining the Sheet After the Audit

The audit is not a one-time event. The dependency sheet becomes a living document, updated whenever you add, modify, or retire an automation. The discipline is simple: no new automation is committed without a corresponding row in the sheet. No automation is modified without updating its row. No automation is deleted without removing its row and noting the deletion in the commit message.

This discipline costs 30 seconds per automation change. Skipping it costs the 90 minutes of a full audit — plus the debugging time when an undocumented interaction surfaces at 3 AM. The math is straightforward. The discipline is the cheaper option every time.

Conclusion: The Inventory Precedes the Change

The hallway lights still come on at 3:12 AM when I walk to the bathroom. The automation still works. The difference is that I now know why it exists, what it depends on, and what happens if I disable it. The dependency sheet took 90 minutes to build and has saved more than that in single debugging sessions since.

The inventory is not the goal. The goal is a system you can reason about — one that degrades predictably, migrates safely, and hands off cleanly. The dependency sheet is the artifact that makes reasoning possible. Build it before you need it, because by the time you need it, you are already debugging in the dark.