ocas-spot — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited ocas-spot (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Spot automates appointment and reservation availability checks, bookings, and persistent monitoring across service venues. It maintains a registry of known venues, a watchlist for ongoing availability monitoring, and handles the full booking flow.
ocas-voyageocas-sandsSpot owns: availability checks, appointment bookings, venue registry management, booking history, watchlist management, platform detection, and platform knowledge base maintenance.
Spot does not own: general travel planning (Voyage), calendar sync, restaurant reservations on unsupported platforms, or platforms requiring authentication Spot does not hold.
spot.discover [type] [location] [--open-now] [--price 1|2|3|4] [--min-rating N] — find and compare venues using Yelp before adding one to the registry. Fans out in parallel: Yelp API business search, delivery eligibility check (where applicable), and public page verification. Fetches reviews for the top 3 candidates in parallel. Returns a ranked shortlist with decision signals. Flows into spot.venue.add → spot.check → spot.book.
After discovery, user selects from shortlist. Selected venue is auto-populated into spot.venue.add using the Yelp alias. If YELP_API_KEY is not set, Spot falls back to public Yelp page navigation — same output, slower, less structured.
spot.check [venue] [service] [date_range] — Check availability at a venue. venue may be a registered name or booking URL. date_range defaults to next 30 days. Returns available dates and time slots.
spot.book [venue] [service] [datetime] [--name NAME] [--email EMAIL] [--phone PHONE] — Book an appointment. Reads contact defaults from config.json if flags omitted. Writes BookingRecord to bookings.jsonl. Emits Place + Concept/Event Signals to Elephas and an InsightProposal to Vesper (via journal briefing payload). If the venue location matches an active Voyage itinerary destination (checked via {agent_root}/commons/data/ocas-voyage/itineraries/), appends a Travel Context entry to that itinerary record.
spot.list [--upcoming] [--all] — List bookings from bookings.jsonl. Default: next 30 days.
spot.watch.add [venue] [party_size] [--dates DATE[,DATE]] [--range FROM TO] [--time HH:MM-HH:MM] [--priority high|normal] — Add a venue to the watchlist. Writes a WatchRecord to watch.jsonl. venue may be a registered name or URL. If platform is unknown, runs spot.platform.probe automatically.
spot.watch.list — List all active WatchRecords from watch.jsonl.
spot.watch.remove [watch_id] — Mark a WatchRecord as inactive (sets active: false). Does not delete.
spot.watch.sweep [--platform PLATFORM] — Check all active WatchRecords for new availability. On new availability, writes an InsightProposal to Vesper and updates the record. Always updates last_checked.
spot.venue.add [name] [url] [--service NAME:ID] [--staff ID] — Register a venue. Runs platform detection, writes VenueRecord to venues.jsonl.
spot.venue.list — List all registered venues with platform, status, and last-checked date.
spot.platform.probe [url] — Detect booking platform type. Follows Universal Decision Tree in references/platforms/README.md. Returns platform type, confidence, and recommended approach.
spot.opentable.login — Open a visible browser window for manual OpenTable login. Saves session state to {agent_root}/commons/data/ocas-spot/opentable-session.json. Run once; re-run if checks start failing. See references/platforms/opentable.md.
spot.update — Pull latest release from GitHub. Preserves {agent_root}/commons/data/ocas-spot/ and journals. See references/self-update.md for the update procedure.
See references/nlp-parsing.md for the full parameter extraction table. Extract structured parameters from natural language before calling any command. When time_window is extracted, filter returned times to that window before presenting results. Resolve ambiguous date language ("next Saturday") against today's date before calling any script.
See references/booking-workflow.md for the full 7-step booking procedure.
Spot supports 20+ booking platforms across three architectural patterns:
| Pattern | Platforms | Auth |
|---|---|---|
| REST API | Acuity Scheduling, Calendly | None / API token |
| Public Widget API | SevenRooms (availability) | None |
| Browser Automation | Square Appointments, Resy, Tock, OpenTable, Meevo, Vagaro, Mindbody, Fresha, StyleSeat, Booksy, GlossGenius, SimplyBook.me, Boulevard, Mangomint, DaySmart, Yelp Reservations, ResDiary, Eat App, SevenRooms (booking) | Session / none |
Status key: ✅ Production · ⚠️ Working (known limitations) · 🆕 New (untested) · ❌ Blocked (bot detection)
Full platform directory and decision tree: references/platforms/README.md Bot block status and bypasses: references/platform-access-matrix.md Key platform quirks: references/platform-notes.md
See references/cron-sweep-pattern.md for the cron-specific sweep flow including browser lifecycle management.
watch.jsonl.time_window if set.last_found. If new times exist, write an InsightProposal to Vesper (via journal briefing payload) and update last_found + last_checked.last_checked, even when no availability found.run_id, timestamp, type (Action|Observation), results[] array containing one entry per venue checked, each with watch_id, venue, platform, status, and change details. See references/journal-schema.md for the canonical schema.{agent_root}/commons/data/ocas-sands/intake/{check_id}.conflict.json. After booking: event creation request to {agent_root}/commons/data/ocas-sands/intake/{event_id}.event.json. External venue confirmation is authoritative — never roll back on Sands failure.{agent_root}/commons/data/ocas-voyage/itineraries/ for matching destinations. Appends Travel Context entry if matched.references/vpn-integration.md.Every spot.check, spot.book, spot.watch.add, and spot.watch.sweep run writes a journal to {agent_root}/commons/journals/ocas-spot/YYYY-MM-DD/{run_id}.json.
spot.check, spot.watch.sweep with no new availabilityspot.book, spot.watch.sweep when an InsightProposal is writtenSee references/journal-schema.md for the full journal JSON schema.
See references/storage-layout.md for the full directory tree and record schemas (VenueRecord, BookingRecord, WatchRecord).
During spot.init, cron registration for spot jobs is handled via cronjob(action='create', ...). No heartbeat registry needed. See references/self-update.md for the cron registration pattern.
See references/okrs.md for all targets (journal coverage, sweep latency, platform coverage, booking accuracy, bot block recovery, onboarding time, schedule adherence).
When Spot encounters failures — bot blocks, VPN disconnects, platform timeouts, or data corruption — it follows these principles:
tun0 drops mid-sweep, pause, reconnect via ocas-vpn, and resume from the last completed entry..quarantine/ and reconstruct last valid state from journal outputs.intents.jsonl and evidence.jsonl.spot.init:
config.json with defaults: { "timezone": "America/Los_Angeles", "name": null, "email": null, "phone": null }spot.discover works without YELP_API_KEY (page mode). For API mode, create a free key at https://www.yelp.com/developers/v3/manage_app and add to env config.For bot-blocked platforms (Tock, OpenTable, Mindbody, Fresha), VirtualPerson provides a headed Chrome environment that's harder to detect than headless Chromium. Patched files for VPN Gate integration are at references/virtualperson-patches/. See ocas-vpn skill for VPN setup. Connect via CDP: p.chromium.connect_over_cdp("http://127.0.0.1:9222").
ocas-vpn resolves ~80% of blocks; if VPN is unavailable, the booking will fail.mcp_stealth_browser_* tools). The built-in browser_navigate fails with ERR_INSUFFICIENT_RESOURCES on Square pages. The full verified flow is in references/stealth-browser-square-flow-20260608.md. Key: execute_script works for window.location.href only — use query_elements + click_element for all DOM interaction.navigate call on a fresh instance can fail with [Errno 111] Connect call failed. Re-spawn a new instance and retry. This is a race condition, not a persistent failure.disabled attribute on market-button[data-testid^='date-'] elements is the correct availability check. query_elements returns attributes.disabled — if present, the date is unavailable. For past dates this is expected. For future dates this means the booking window hasn't reached that date yet (venue only books ~1 week out) OR the date is fully booked. Preserve last_found and re-check in a few days.query_elements even if partially off-screen. The calendar shows ~3 weeks at a time (past days as disabled, current week, future weeks up to the booking window — beyond which dates are also disabled). Use data-testid^='date-' to get all dates; check disabled attribute and data-testid value (N vs N-selected) to identify the target date.market-button[data-testid='time-slot'] elements render for all available slots. Unlike dates, time slots do NOT use the disabled attribute to indicate unavailability — if a slot is listed, it's bookable. If a date is clicked and no time-slot elements appear, the date has zero availability (outside window or fully booked).click_element(selector="#accept-recommended-btn-handler") (CSS ID selector is faster than text_match). Without dismissing it, subsequent clicks may not register on overlapping elements.references/platforms/<platform>.md. Always read the per-platform doc before attempting a new platform.api.sevenrooms.com is merchant-only./root/.hermes/commons/journals/ocas-spot/YYYY-MM-DD/{run_id}.json, NOT under profiles/indigo/. Writing journals to the profile-scoped path means other profiles and the Vesper aggregator won't find them.Spot uses cronjob for appointment monitoring. On platforms without cronjob, the user triggers checks manually. Yelp API calls and browser automation are platform-independent.
| File | When to read | |
|---|---|---|
references/nlp-parsing.md | Before parsing natural language input — parameter extraction table | |
references/booking-workflow.md | Before executing any booking — full 7-step procedure | |
references/platform-notes.md | Before browser automation — key platform quirks and selectors | |
references/self-update.md | When running spot.update — update procedure | |
references/journal-schema.md | When writing journal entries — full JSON schema example | |
references/storage-layout.md | When creating or inspecting data files — directory tree and record schemas | |
references/okrs.md | During OKR evaluation — all targets | |
references/stealth-config.md | Before any browser automation — shared stealth config | |
references/platforms/README.md | Before probing or booking on any platform — decision tree, index, and per-platform patterns | |
references/platforms/NEW_PLATFORM.md | When onboarding a new booking platform | |
references/schemas.md | Before creating VenueRecord, BookingRecord, or WatchRecord | |
references/vpn-integration.md | When bot detection blocks access and VPN fallback is needed | |
references/virtualperson-integration.md | When VirtualPerson headed Chrome is available for bot-blocked platforms | |
references/platform-access-matrix.md | Before checking which platforms are accessible from current IP | |
scripts/acuity.js | When checking Acuity Scheduling availability (REST API) | |
scripts/square.js | When checking Square Appointments availability (Playwright) | |
scripts/sevenrooms.py | When checking SevenRooms availability (public widget API, no auth) or booking (browser automation via Playwright) | |
references/sevenrooms-api-notes.md | SevenRooms API research notes — endpoint reference, response fields, community repos | |
references/stealth-browser-square-flow-20260608.md | Square flow via stealth browser — execute_script returns null, use query_elements + click_element only. Primary reference for Square automation. | |
references/platform-access-matrix.md | Before checking which platforms are accessible — now includes both HTTP access AND automation status (two separate tables). | |
references/cron-sweep-pattern.md | Before running watch sweeps via cron — browser lifecycle, error handling, and sequencing for automated sweeps. | |
references/watch-sweep-behavior.md | Before designing or modifying sweep logic — detailed behavioral spec for watch sweep edge cases. |
Run spot.update to pull the latest release. See references/self-update.md for the full procedure.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.