Friday’s Party: The Manifest
So I said to myself…
Self, if you’re going to build a Library, you’d better know what’s on the shelves.
And that’s where the Manifest comes in.
Ok we’ve already established the fact we’ve built this insane ‘index’ simulated a library, and some goofy monastery. There had to be cabinets somewhere… Right?
Dont worry if you want goofy constructs - buckle up this is gonna get fun.
Cabinets… Contain Drawers. (that’s the smallest unit I care to worry about right now Sooo…
‘Cabinets / Volumes’ are A Fez Trigger Template Sensor and Drawers are the Keys inside them. - and a drawer can have nested JSON… (yeahhh… exactly)
We tell Friday in her instructions to write deep for static data and wide for dynamic fast changing data. Tell her to stuff stuff in the ‘most authoritative’ drawer (more on that in, yes a future episode) for the subject (we’ve already established she’s good at categorization…), give her tools, an indexer, a way to read the index and - poof instant file system.
That’s all well and good but she has to know what’s THERE before we can find ANYTHING.
OK - notice I said ( cabinet / volume ) above - you can morph the name into your choice. Cabinet seems to work better in my install simply because it’s what I SAY. Volume - or George may work better for you - just be CONSISITENT. In my case it creates a context collision with PHYSICAL cabinets - something future me can deal with when ERP comes online.
What’s in a manifest? It’s a map - a root for the LLM to hang initial context and breadcrumb the rest of the storage map. So at a MINIMUM, it needs a way to list your volumes / cabinets / georgies / wth-evers, what’s special about 'em - and any context (There’s that word again) you can give the llm in a clear, concise manner.
if you EVER wanted to be as INFO dense but character sparse as possible – this is it. The MORE you can tell the LLM here without burning conte…
oh -I didn’t tell you? THIS - like the top-level Zen Index dump are CORE - if you do nothing else drop the manifest if you use files and the index root dump if you have an index. - between that, tool use with good descriptions and build philosophies and live context with good aliasing, you’re almost 90% there… There IS a light at the end of the tunnel and it is NOT a train… Trust me… ![]()
Here’s an abbreviated manifest for Friday right now…
NOTE - YES, there’s obvious things wrong in there, give me a break we’re hand building a directory structure and this is base format… But this SHOULD Give you a good idea what’s in a cabinet schema. The tool below is the authoritative source for schema for now.
manifest output sample:
sensor.zen_dojo_cabinet:
entity_id: sensor.zen_dojo_cabinet
friendly_name: Zen Dojo Cabinet
context:
what_is_this: >-
Welcome to your Dojo - the tools and weapons of your trade. Learn and
wield them well. Contains drawers for componnts.
why_is_it_here: >-
Serves as root for Kung Fu components (indexable unit of context +
actions).
usage_policy:
- >-
Prefer modifying in place unless scale or security requires a new drawer
or volume.
- >-
Please cross-link by label and purpose. Prefer to leave breadcrumbs if
the data is authoritative elsewhere.
- Summarize or prune as needed.
growth_logic:
on_split: >-
Create a new subcabinet only if a drawer outgrows space or requires
special access.
split_triggers:
- Exceeds index or storage limits.
- New security domain.
- Needs its own schedule or routine.
metadata:
id: 8-REDACTED-4
schema_version: null
labels:
- data_storage_cabinet
- inventory
- cabinet
- zen_dojo_cabinet
- dojo
timestamps:
last_changed: "2025-09-03T19:12:44.968678+00:00"
last_updated: "2025-09-03T19:12:44.968678+00:00"
stats:
drawer_count: 29
capacity:
chars_used: 52992
chars_max: 131072
percent_used: 40.4
warning: false
access:
writeable: true
readable: true
drawers:
- programs
- auto_fu
- index_mastery
- command_index
- kung_fu
...
- salt_sentinel
- print_shop
- my_household [mount:1cd683f8-1-REDACTED-]
- my_family [mount:dedede5b-5e80-1-REDACTED-]
- ai_partner [mount:dedede5b-5e80-1-REDACTED-]
- test_drawer
- alert_manager
...
- laundry_manager
- grocy_manager
- grocy_api_endpoints
- hot_tub_manager
drawer_index: {}
acls_by_category: {}
Context? Labels? (Yes same ones - enforced, we just dump any label not in the index later on write - you’ll see…) mounts??? Yep - have to deal with the fact that…
Under the hood this is a HA trigger text sensor, we’re just taking the complexity out of it and describing it in a way your LLM understands, but it comes along with all the same baggage a HA trigger text sensor entity has… Now, you get warnings about DB size over 16K, things go goofy at 32k - Don’t try 1M, Just DON’T… (See the big poofy explosive cloud above - THIS was the cause…) Have good backups. You have been warned.
The best way to deal with all that baggage is keep guardrails on the LLM and make sure it never EVER gets close. (see above…, Nathan how do we keep the LLM from lying, this is on the other side of that equation - strict control of the input side too… Keeping it out of danger.)
We just set a hard limit of about 16K (yes, my math may be mathing wrong, don’t care - just needed a limit and a ratio,)
- set your own limit you’ll see where it is…
- My name is NOT Matt Parker - for Maths see Stand-up Maths on YouTube… He’s a great guy - Get his book, no he did not pay me - it’s just a good book if you like math stuffs…
The Zen Dojotools Manifest:
sequence:
- variables:
zen_default_fam_cab: |-
{{ expand(label_entities('Zen Default Household Cabinet'))
| selectattr('domain','eq','sensor')
| map(attribute='entity_id')
| list
| first
| default() }}
manifest_key: zen_library_manifest
read_hidden: "{{ show_hidden | default(false) }}"
hide_labels:
- hidden_volume
- read_only_volume
- system_volume
- hidden_cabinet
- read_only_cabinet
- system_cabinet
ignore_label_prefixes:
- _
- .
always_hide_drawers:
- AI_Cabinet_VolumeInfo
exempt_labels:
- internal
- hidden
- system
max_chars: 131072
warn_threshold: 0.8
controller_schema: 1
manifest: |-
{% macro build_drawer_index(vars) %}
{%- if vars is mapping %}
{%- set label_index_raw = vars.get('_label_index') %}
{%- if label_index_raw is mapping %}
{%- set label_index_value = label_index_raw.get('value') %}
{%- if label_index_value is mapping %}
{%- set drawer_index = {} %}
{%- for label, drawers in label_index_value.items() %}
{%- set clean_label = label | lower %}
{%- if drawers is iterable and not drawers is string %}
{%- set clean_drawers = drawers | select('string') | list | unique %}
{%- elif drawers is string %}
{%- set clean_drawers = [drawers] %}
{%- else %}
{%- set clean_drawers = ['_unknown_drawer'] %}
{%- endif %}
{%- set drawer_index = drawer_index | combine({ (clean_label): clean_drawers }) %}
{%- endfor %}
{{ drawer_index | tojson }}
{%- elif label_index_value is sequence %}
{%- set drawer_index = {} %}
{%- for label in label_index_value %}
{%- if label is string %}
{%- set drawer_index = drawer_index | combine({ (label | lower): ['_unknown_drawer'] }) %}
{%- endif %}
{%- endfor %}
{{ drawer_index | tojson }}
{%- else %}
{{ {"wtf-errorcode": ["unknown-label-index-format"]} | tojson }}
{%- endif %}
{%- else %}
{{ {"wtf-errorcode": ["missing-label-index"]} | tojson }}
{%- endif %}
{%- else %}
{{ {"wtf-errorcode": ["vars-not-dict"]} | tojson }}
{%- endif %}
{% endmacro %}
{% macro acls_by_category(info) %}
{%- set raw_acls = info.get('acls', {}) %}
{%- set ns_acl = namespace(by_cat={}) %}
{%- for category, entries in raw_acls.items() if entries is sequence %}
{%- set direct = entries | selectattr('entity_guid', 'defined') | map(attribute='entity_guid') | list %}
{%- set family = entries | selectattr('family_guid', 'defined') | map(attribute='family_guid') | list %}
{%- set nested = [] %}
{%- for entry in entries if entry is mapping %}
{%- for key, val in entry.items() if val is mapping %}
{%- if 'entity_guid' in val %}
{%- set nested = nested + [val.entity_guid] %}
{%- endif %}
{%- if 'family_guid' in val %}
{%- set nested = nested + [val.family_guid] %}
{%- endif %}
{%- if 'household_guid' in val %}
{%- set nested = nested + [val.household_guid] %}
{%- endif %}
{%- endfor %}
{%- endfor %}
{%- set all_guids = (direct + family + nested) | reject('none') | unique | list %}
{%- if all_guids | length > 0 %}
{%- set ns_acl.by_cat = ns_acl.by_cat | combine({ category: all_guids }) %}
{%- endif %}
{%- endfor %}
{{ ns_acl.by_cat | tojson }}
{% endmacro %}
{%- set result = namespace(data={}) %}
{%- for ent in states.sensor | map(attribute='entity_id') | list %}
{%- set vars = state_attr(ent, 'variables') %}
{%- if vars is mapping and (vars.get('AI_Cabinet_VolumeInfo') is not none) %}
{%- set info = vars.AI_Cabinet_VolumeInfo.value %}
{%- set st = states[ent] if states[ent] is defined else none %}
{%- set friendly = st.attributes.friendly_name | default(ent) %}
{%- set lc = st.last_changed.isoformat() if st else none %}
{%- set lu = st.last_updated.isoformat() if st else none %}
{%- set volume_labels = labels(ent) | default([]) %}
{%- set skip_hidden = (not read_hidden)
and (hide_labels | select('in', volume_labels) | list | count > 0)
and (volume_labels | select('in', exempt_labels) | list | count == 0) %}
{%- if skip_hidden %}
{%- continue %}
{%- endif %}
{%- set raw_drawers = vars.keys() | list | default([]) %}
{%- set filtered_drawers_ns = namespace(items=[]) %}
{%- for d in raw_drawers %}
{%- if d not in always_hide_drawers and not d.startswith('_') and not d.startswith('.') %}
{%- set val = vars.get(d, {}) %}
{%- set val_value = val.get('value') if val is mapping else {} %}
{%- if val is mapping and val_value is mapping and val_value.get('mount_point', false) %}
{%- set drawer_name = d ~ ' [mount:' ~
(
val_value.get('target_entity_id')
if val_value.get('target_entity_id')
else val_value.get('target_volume_id')
if val_value.get('target_volume_id')
else '?'
)
~ ']' %}
{%- else %}
{%- set drawer_name = d %}
{%- endif %}
{%- set filtered_drawers_ns.items = filtered_drawers_ns.items + [drawer_name] %}
{%- endif %}
{%- endfor %}
{%- set filtered_drawers = filtered_drawers_ns.items %}
{%- set raw_json = vars | tojson %}
{%- set char_count = raw_json | length %}
{%- set pct_chars = (char_count / max_chars * 100) | round(1) %}
{%- set warning = pct_chars >= (warn_threshold * 100) %}
{%- set flags = info.get('flags', {}) %}
{%- set writeable = (not flags.get('read_only', false))
and (info.get('schema_version', 0) | float <= controller_schema)
and not warning %}
{%- set readable = not warning %}
{%- set drawer_index_json = build_drawer_index(vars) %}
{%- set drawer_index_obj = drawer_index_json | trim | from_json %}
{%- set acls_obj = acls_by_category(info) | from_json %}
{%- set rec = {
'entity_id' : ent,
'friendly_name' : friendly,
'context' : vars.get('_context', {}) | default([]),
'metadata' : {
'id' : info.get('id'),
'schema_version' : info.get('schema_version'),
'labels' : volume_labels,
'timestamps' : { 'last_changed': lc, 'last_updated': lu }
},
'stats' : { 'drawer_count': filtered_drawers | count },
'capacity' : {
'chars_used' : char_count,
'chars_max' : max_chars,
'percent_used' : pct_chars,
'warning' : warning
},
'access' : { 'writeable': writeable, 'readable': readable },
'drawers' : filtered_drawers,
'drawer_index' : drawer_index_obj,
'acls_by_category': acls_obj
} %}
{%- set result.data = result.data | combine({ (ent): rec }) %}
{%- endif %}
{%- endfor %}
{{ result.data }}
final_response: "{{manifest}}"
- event: set_variable_legacy
event_data:
key: "{{ manifest_key }}"
value: "{{ final_response }}"
set_timestamp: "{{ true }}"
volume_entity: "{{ zen_default_fam_cab }}"
- alias: Return Manifest Data
stop: Pass variable to response
response_variable: final_response
- set_conversation_response: "{{final_response}}"
alias: Zen DojoTools Manifest
description: >
Authoritative manifest scanner for AI_Cabinet volumes. Extracts metadata,
context, capacity, access flags, ACLs, and drawers. Designed to drive secure
CRUD tools. Theoretically Mount point aware Attempts to write a copy to the
default house manifest drawer on execution.
fields:
show_hidden:
selector:
boolean: {}
name: show hidden
description: Include hidden/system volumes in results?
icon: mdi:home-map-marker
First note how simple it is - It’s reading a preset label:
label_entities('Zen Default Household Cabinet')
and collecting the ents, and filtering it a bunch to make sure we have only one…
This is the cabinet you will use for your house stuff. Anything in here is fair game and the manifest has to be if this is going to work. Don’t worry, the manifest only gets pub info. The next thing it does is hunt for your sensor that is a ‘cabinet’ that has that label and grab hold and as soon as it’s compiled its output - manifest writes it right there in a known drawer in the root of the default household cabinet, if it can. If it doesn’t find it, can’t - it will warn. (This will become important in… Yep - another episo… you guys are getting good at this…)
…But in short - we’re making the map of cabinets here - if we can’t hit the default family cab right here, and NOW… We have bigger fish to fry. I’ll return your data but… Yeah. here’s your data - and a big ol’ warning.
So you make a label named ‘Zen Default Household Cabinet’ Or pick your own name, update the script, and tag the sensor entity for the correct Fez Trigger Text Sensor (see workaround script post above), also, I do recommend making a triggered automation to run the script every time HA restarts, we’ll take care of the rest of the refreshes later.
Now repeat after me…
From this point forward THOU SHALT NOT EVER give an LLM raw read or write access inside the sensor data without going through your script(s). THIS INCLUDES any script you have for attribute dumps… If you have them SPECIFICALLY filter out a Fez sensor… All of my other tools are writing around what I want the LLM to see - (yes, another episode…). This was the origin of the Inspect tool a few posts above… Friday's Party: Creating a Private, Agentic AI using Voice Assistant tools - #129 by NathanCu
We’ll be storing some metadata outside of its reach and not that I’m saying bad juju WILL happen… I’m just saying I wouldn’t want something nice to happen to your shiny new storage system…
Explore around in it a bit and see what we’re considering valid - feel free to make suggestions. No I’m not exposing the index at manifest level YET - but you see the plumbing.
Build a few bare minimum Fez Trigger Sensors, set them up to work with the workaround script above, tagged with the correct labels from our index according to the filters this script is targeting…
Map to addressable storage. Cached in a known location for late ruse and updated every single time this is run where it has access to the file tool and cabinets.
I got the bugs in files out - it’s up next and deserves it’s own post but I’ll pause here before we move into the actual file script.
Next steps for Manifest - a diagnostic mode to show issues in file cabinet sensors, possible repairs.
Coming up - Admin tool to stamp / format a cabinet. For now it’s by hand, sorry. (Tool gap - there’s your schema - go…)
Before we move on to the actual File Cabinet I need way more coffee.
Oh - and don’t think I forgot about the party coming up…
Oh and I have to get my Git repo up apparently… The File script… She PHAT.


























