Claude skills for property security ops live in a folder a leasing manager can edit.
Most writing about Claude skills today is about scanning code for vulnerabilities. Property security operations need a different shape. Each event class (loiter, tailgate, package theft, force entry, after-hours pool, pre-action parking lot) is its own folder with its own dwell threshold, arming schedule, prompt template, output schema, and dispatch rule. This page is the layout we ship on every Cyrano unit and the files a property manager actually edits when they want the rule to change before the next overnight shift.
See the skill folder live on a production unitWhy the existing playbooks do not fit a property
Almost every guide on Claude skills published in the last six months is about cybersecurity work: STRIDE threat modeling, secret scanning, vulnerability triage, MITRE ATT&CK mapping. Those skills are about reading text (a config file, a packet capture, a CVE description) and producing text (an analyst note, a ticket draft). A property security operation is the opposite shape. The input is video. The output is a dispatch decision: who gets a text, who gets a phone call, what color the chip is in the dashboard, whether to wake the on-call leasing agent at 02:14.
That difference forces a different file layout. A code-scanning skill needs a prompt and maybe a tool. A loitering skill needs a prompt, a dwell threshold, an arming schedule (so the pool polygon is only armed after 22:00), an output schema (because the dispatch logic downstream is JSON-driven), and a dispatch file (because the on-call routing differs by property and by time of day). Those four things are different files. Bundling them into one prompt collapses the only configuration surface the property manager actually cares about.
Below is the layout we ship on every Cyrano unit, the runtime that invokes it, and the audit trail every dispatched alert leaves on disk.
One frame fires; one skill folder runs; one verdict comes back
The skill folder, on disk
This is the unit a property manager edits. One folder per event class. Four files plus a versioned history directory. Nothing about this layout is novel; the choice to expose it as a property-manager-editable surface is.
triggers.json: where two properties at the same vendor diverge
The Atlanta Class C with a known after-hours pool problem and the Baton Rouge garden-style with a known parking-lot pre-action problem run the same Cyrano firmware. Their loitering skills are different because their triggers.json files are different. Dwell threshold, armed zones, arming schedule, cooldown to avoid alert storms. The dashboard renders this as a form; the file is the source of truth.
“A regional manager who has never written a line of code can edit a markdown file and the rule is live on the next event. That is the part the SaaS dashboards do not let you have.”
Cyrano deployment notes, 30-property pilot
instructions.md: the prompt the manager actually edits
Plain markdown, on disk, in the skill folder. The dashboard editor renders it as a textarea with a diff view against the previous version stored in .history/. SIGHUP after save. The next event uses the new file.
Six default skills, what they trigger on
These are the folders that ship pre-populated on a new unit. Properties commonly add a seventh and eighth (a leasing-hours skill and a fence-line skill); both are folders, not features.
loiter
Dwell threshold 90s in armed zones. Armed schedule per day-of-week. Cooldown 600s per track. Most common skill by event volume.
tailgate
1.2s threshold at controlled entry points. Two-track-overlap detector. Fires only when the inner door has been authorized in the last 4s.
package_theft
900s threshold near mailroom or doorstep with motion cluster. Compares the bag-shape on arrival to the bag-shape on departure.
force_entry
Immediate, no dwell. Detects pry-tool-shaped objects and active manipulation of a lock, gate, or door handle. Highest-priority dispatch.
after_hours_pool
30s dwell in pool polygon between 22:00 and 06:00, configurable per property. Often the first skill a manager edits.
pre_action_parking_lot
240s dwell in unmarked-figure-near-vehicle pattern, fired only when the lot is armed. Catches the prowl before the smash.
The runtime that invokes the skill
The runtime is short because the skill folder carries the load. The detector decides a person is in an armed zone. The dwell timer in triggers.json holds the track. When the threshold is met, this is the call:
One loiter event, end to end on a production unit
Editing a skill in the field, the four-step path
A regional manager who decides the after-hours pool window should start at 21:00 instead of 22:00 changes one number in one file. That is the entire deploy.
From manager decision to live rule
Open the skill in the dashboard
Skills tab, click after_hours_pool. Renders the four files as forms with a diff view against the prior version.
Change the arming schedule
Slide the start time from 22:00 to 21:00 in triggers.json. Save.
Runtime reloads on file watch
inotify on /var/lib/cyrano/skills/ triggers a SIGHUP. The next dwell evaluation reads the new schedule.
Audit trail captures the change
.history/ now contains the prior triggers.json with an ISO timestamp. Any future alert can answer 'which schedule was active when this fired'.
Numbers that come out of the skill layout
Per 25-camera property, per day, with the six default skills gating Claude calls. The skill folder is the entire reason these numbers are not five orders of magnitude higher.
Frames captured
0M
per property per day
Skill invocations
0
Claude calls per property per day
Cost per property
$0
Anthropic spend per month
Default skills
0
folders in /var/lib/cyrano/skills/
Cybersecurity skills vs. property security skills
The two are different shapes. The table below is the working comparison we use when a property manager asks why the off-the-shelf cyber-security skill collections do not solve their problem.
| Feature | Cybersecurity skill | Property security skill |
|---|---|---|
| Input shape | Text: code, logs, packet captures | Video: 5-frame stitched 2x3 image per event |
| Trigger | User-invoked from a CLI or chat | Dwell threshold met inside an armed-zone polygon |
| Output consumer | Analyst, ticket, code change | On-call manager SMS, phone call, dashboard chip |
| Per-property variance | Usually zero (same skill for all repos) | High: dwell, schedule, dispatch all differ per property |
| Required side files | instructions.md, optional script | instructions.md + triggers.json + output.schema.json + dispatch.json |
| Audit demand | PR review trail | Per-event input image + rendered prompt + raw response, kept 90+ days |
| Edit cadence | Once per skill, then stable | Whenever an incident exposes a policy gap (often weekly) |
What a manager actually sees on disk after one alert
The four files below are the entire audit surface. There is no opaque vendor service in the middle. If the model said HIGH, the on-call manager can open the literal image the model saw.
The audit JSON below is what a 6-month-after compliance inspection actually pulls. Notice thatskill_instructions_history_pointerpoints at the exact prior version of the prompt that was active when the alert fired, not the current one.
Things a Claude skill for property security does NOT need
Most cybersecurity-skill content carries a pile of knobs that do not survive contact with a property. The list below is the part of every skill bundle we removed because nothing on a property uses it.
Removed from the property skill bundle
- Multi-step planning loops. The skill is one call per event, not an agent loop.
- Tool selection at runtime. The triggers.json file names the allowed MCP tools statically.
- User-facing chat. The output goes to dispatch.json, never to a chat panel.
- Cross-skill orchestration. Each event class is its own folder with no shared state.
- Latency budget over 4 seconds. An on-call manager waiting 8 seconds for a verdict is a product bug.
- Knowledge bases > 1 MB. The instructions.md plus output.schema.json fit in under 8 KB combined.
MCP tools the loitering skill is allowed to call
Two of them. Listed in the mcp_tools_allowed field of triggers.json. The rest of the on-device tool surface (camera control, network config, model swap) is explicitly not accessible to the skill at runtime, by design.
search_resident_roster
Looks up whether a face match against the property's resident roster (opt-in only) explains the figure inside the armed zone.
lookup_property_policy
Fetches the posted property policy for the polygon: pool hours, smoking zones, parking permit rules, fence-line classification.
search_recent_alerts
Returns whether the same track has fired an alert in the last 600 seconds. Used to suppress duplicate dispatches.
The uncopyable part
The path is the product surface.
On a Cyrano unit the entire skill bundle is a working directory at /var/lib/cyrano/skills/. Every dispatched alert is a folder at /var/lib/cyrano/events/<event_id>/ with four readable files. Every prior version of every skill is a file at /var/lib/cyrano/skills/<event_class>/.history/. A regional manager can put the whole thing under git, push changes per property, and the runtime reloads on file-watch. That is what makes Claude skills usable here. The thing the cybersecurity skill collections do not give a property manager is the path; without the path you have a vendor feature, not an editable skill.
Things the skill-folder layout quietly prevents
Each one is a real failure mode we have seen on a property when the skill is one big system prompt instead of a folder. The file layout is what stops them.
Five questions to ask before you adopt any Claude skill bundle for a property
If a vendor or an internal team cannot answer them with a file path, a number, or a behavior description, they have a demo. They do not yet have a property security operation.
Where does the prompt for each event class live, and who can edit it. Where do the dwell threshold and arming schedule live, and is changing them a deploy. What is the strict JSON shape Claude is required to return, and what does the runtime do with a malformed response. Where does the dispatch routing live (who gets the SMS, who gets the call), and is it editable per property. Where on disk are the input image, the rendered prompt, and the raw response written so a future audit can open them in one click.
On a Cyrano unit those answers are/var/lib/cyrano/skills/<event_class>/instructions.mdedited by the regional manager;triggers.jsonin the same folder, edited as a form or a JSON file;output.schema.jsonalso in the same folder, with a strict-validate-or-reject runtime;dispatch.jsonagain in the same folder, per-property; and the four-file folder at /var/lib/cyrano/events/<event_id>/ for every single dispatched alert.
See the skill folder open on a production unit
A 15-minute call. We open /var/lib/cyrano/skills/ on a live unit, change the after-hours pool start time from 22:00 to 21:00 in triggers.json, replay the last loitering alert against the new schedule, and walk through the four files written to /var/lib/cyrano/events/<id>/. You leave with the per-event arithmetic for your own camera count.
Claude skills for property security operations: frequently asked questions
What is a Claude skill in the context of property security operations?
A skill is a folder on the edge device that bundles together everything Claude needs to give one kind of verdict for one kind of event. On a Cyrano unit a skill has four artifacts: an instructions file (the prompt template), a triggers file (the dwell threshold and arming schedule that decides when the skill is even invoked), an output schema (the strict JSON shape Claude has to return), and a dispatch file (who gets paged, what the SMS body looks like, whether to ring the on-call phone). One folder per event class. Loitering is one skill. Tailgating is another. Package theft is another. Force entry is another. They are not different prompts in one big system; they are different skills with different file layouts in /var/lib/cyrano/skills/.
Why one skill per event class instead of one big system prompt?
Because property managers edit them. The loitering skill at a Class C property in Atlanta has a 90-second dwell threshold, treats the pool area as armed only after 22:00, and pages the on-call leasing agent. The loitering skill at a 6-building portfolio in Baton Rouge has a 60-second threshold, treats the parking lot as armed 24/7, and pages a dispatched off-duty officer. Those are not configuration toggles in a SaaS dashboard; they are differences in the skill folder, and they should be editable as text files on the device that produces the alerts. Bundling them into one prompt means every change is a deploy and every property is the same. Splitting them into per-event-class skills means a manager who decides 'we treat anyone in the pool after 22:00 as HIGH regardless of dwell' edits one file and the rule is live on the next event.
Where do these skills physically live on the device?
On a Cyrano unit the path is /var/lib/cyrano/skills/<event_class>/. The folder for the loitering skill contains four files: instructions.md (the prompt sent to Claude alongside the stitched 5-frame burst), triggers.json (dwell threshold in seconds, armed-zones polygon ids, arming schedule by day-of-week and hour, optional cooldown to avoid alert storms), output.schema.json (the strict JSON envelope Claude must return — threat_level, one_line_summary, policy_match), and dispatch.json (the operator routing rules: SMS template, phone-call escalation policy, dashboard chip color). A fifth file, .history/, holds versioned copies of every prior instructions.md so an audit can answer 'which prompt was active when alert e_4193 fired'.
What is the difference between a Claude skill and an MCP tool here?
An MCP tool is something Claude can call to get information or take an action: 'fetch the resident roster', 'search the footage index', 'send an SMS to the on-call manager'. A skill is the larger unit that decides when those tools are used and what verdict shape Claude has to produce. Concretely, the loitering skill on a Cyrano unit names two MCP tools in its frontmatter: search_resident_roster (to check whether the figure on the bench at 02:14 is a known resident) and lookup_property_policy (to check whether the bench is in an armed zone after-hours per the property's posted rules). The skill is the unit a manager edits; MCP tools are the calls that skill is allowed to make. We use both, but the per-property differences live at the skill level, not the tool level.
How is the skill actually invoked when a camera fires an event?
Three steps, all local until the very last one. The on-device detector decides a bounding box is a person inside an armed zone. The dwell timer in /var/lib/cyrano/skills/<event_class>/triggers.json holds the track for the configured threshold (loiter 90s, tailgate 1.2s, package 900s). When the threshold is met, the runtime loads instructions.md and output.schema.json from the same skill folder, stitches a 5-frame burst into one 2x3 image, and emits exactly one Claude messages.create call carrying the prompt, the schema, and the image. The verdict comes back, gets validated against output.schema.json, and dispatch.json decides who gets the SMS and the phone call. If the verdict fails the schema check, the operator sees the local-only event with a 'verdict_pending' flag and the request goes into the outbox queue.
What is the on-disk path for an alert that has already been dispatched?
Every dispatched alert leaves four files in /var/lib/cyrano/events/<event_id>/: claude_input.jpg (the literal 2x3 stitched image that went over the wire), claude_prompt.txt (the rendered prompt the skill produced for this specific event), claude_response.json (the parsed JSON verdict Claude returned), and operator_alert.json (the SMS body, the call script, and the dashboard chip color the dispatch.json file produced). Every one of those is openable from the dashboard 'show inputs' affordance for any alert in the past 90 days. That auditability is non-negotiable on a security product. If the model said HIGH and dispatched a guard, the on-call manager has to be able to see what the model saw and what it was asked to decide.
What happens when the WAN link to Anthropic is down for hours?
The detection layer never blocks on a remote API. The on-device verdict (zone hit, dwell threshold met, event class matched) is dispatched to the operator immediately with whatever fields the local model can fill, including the local VLM's one-line summary if the local-VLM escalation threshold was satisfied. The 5-frame stitched burst plus the rendered prompt are written to /var/lib/cyrano/outbox/claude/<event_id>.ndjson as an append-only record. When the link returns, the queue drains in order, Claude's verdict is appended to the event record after the fact, and the operator's incident view updates with the higher-confidence verdict. The natural-language footage search index is rebuilt for the lagged events as their verdicts arrive.
Which event classes ship as default skills on a Cyrano unit?
Six: loiter (dwell threshold 90s in armed zones), tailgate (1.2s threshold at controlled entry points, two-track-overlap), package_theft (900s threshold near mailroom or doorstep with motion cluster), force_entry (immediate, on detection of pry-tool-shaped object or active manipulation of a lock or gate), after_hours_pool (dwell threshold 30s in pool polygon between 22:00 and 06:00, configurable per property), and pre_action_parking_lot (dwell threshold 240s in unmarked-figure-near-vehicle pattern, fired only when the lot is armed). Each one is a folder under /var/lib/cyrano/skills/. Properties commonly add a seventh and eighth: a leasing-hours-violation skill for after-hours leasing-office traffic, and a fence-line skill for perimeter cuts.
How does a property manager actually edit a skill in production?
Two ways. The dashboard has a 'skills' tab where the four files for each event class render as an editable form: dwell threshold as a number input, arming schedule as a calendar grid, instructions.md in a text editor with a diff view against the prior version, output.schema.json read-only by default. Saving the form writes the four files atomically into /var/lib/cyrano/skills/<event_class>/, copies the prior versions into .history/, and SIGHUPs the runtime so the next event uses the new files. The second way is direct SSH for portfolio operators who want to manage the skills as a git repo: clone /var/lib/cyrano/skills/, edit, push back, the runtime watches the directory with inotify and reloads. Both paths produce the same audit trail.
What does the cost structure look like once skills are gating Claude calls?
On a 25-camera multifamily property the skills emit roughly 250 Claude requests per day across all event classes (the median we see in production), each carrying one stitched 2x3 image and a rendered prompt. That is ~1.31 million image tokens plus ~50 input text tokens per request and ~120 output tokens per response. At Sonnet 4 vision pricing this is roughly $0.04 per property per day or about $1.20 per month. The naive alternative — sending every frame from every camera to Claude with no skill-level dwell gating — would be roughly $97,000 per property per day at the same pricing. The skill folder is the architecture that turns the latter number into the former.
Can the skills bundle live in a git repo so portfolio managers version it across properties?
Yes. /var/lib/cyrano/skills/ is a working directory and we recommend operators treat it that way. A regional manager can keep a portfolio_skills repo with a baseline set of folders (loiter, tailgate, package_theft, force_entry, after_hours_pool, pre_action_parking_lot) and per-property overrides as branches. The unit's reload behavior is filesystem-watch based, so a git pull on the device puts the new skill into effect on the next event. The .history/ directory inside each skill folder is the on-device audit log; the git repo is the portfolio-wide change log. Both are useful for different audits.
Comments (••)
Leave a comment to see what others are saying.Public and anonymous. No signup.