Skip to main content

ocas-taste

Generates personalized recommendations based on real consumption signals from emails and calendars, respecting dietary restrictions.

Install this skill

or
80/100

Security score

The ocas-taste skill was audited on Sep 25, 2026 and we found 2 security issues across 2 threat categories, including 1 high-severity. Review the findings below before installing.

Categories Tested

Security Issues

medium line 27

Access to home directory dotfiles

SourceSKILL.md
25 - key: GOOGLE_MCP_CREDENTIALS
26 description: Directory containing Google OAuth token JSON files
27 default: ~/.google_workspace_mcp/credentials
28 tags:
29 - preferences
high line 389

Fetch and execute pattern

SourceSKILL.md
387
388- **Re-auth, dedup scripts** — `google_oauth_init.py` only handles the agent's account (hardcoded line 141). For <operator>'s re-auth, build the OAuth URL manually with PKCE. `taste_signals_dedup.py` is the correct post-enrichment dedup tool (not `clean_signals.py`). `dispatch_taste_dedup.py` lives under `skills/ocas-taste/scripts/` (NOT `commons/data/`) — always use absolute path.
389- **`dispatch_taste_dedup.py` `<hermes-home>` placeholder bug (FIXED 2026-07-26):** Until that date the script hardcoded `DATA_DIR = Path("<hermes-home>/profiles/<profile>/commons/data/ocas-taste")` — the SAME literal `<hermes-home>` / `profiles/<profile>` defect that hit the ocas-forge closure scripts (see `references/closure-scripts-hermes-home-placeholder-bug.md` in ocas-forge). Every run printed `ERROR: <hermes-home>/profiles/<profile>/commons/data/ocas-taste/signals.jsonl not found` and SILENTLY SKIPPED dedup — so a `dispatch-wave` taste journal reporting `dedup_removed: 0` / `signals_total_after == signals_total_before` was NOT proof of a clean signal store; real duplicates persisted across waves. Fixed by resolving `os.environ.get("AGENT_ROOT", "$AGENT_ROOT")` + `profiles/indigo/commons/data/ocas-taste` and adding `import os`. **Detection / re-occurrence guard:** if you ever see `ERROR: <hermes-home>/profiles/<profile>/.../signals.jsonl not found` from this script, it still carries the placeholder — patch line 26 the same way; do NOT trust a `dedup_removed: 0` journal line as evidence of no duplicates. Always run `--dry-run` FIRST and confirm it actually opens `signals.jsonl` (printed `Total signals: N`) before applying. The dispatch runner (`run_mixed_wave_closure.py`) invokes it with `--dry-run` then `--apply-taste`; if the dry-run can't find the file, the applied run also silently no-ops and the journal's `dedup_removed` lies.
390
391- **Google Places API key, inline enrichment, schema drift** — API key is in `<hermes-home>/secrets/plaid.env` (not env var). Inline enrichment (direct urllib to legacy GET API) preferred over `taste_full_enrich.py` which has schema drift (`item-{safe_name}` not UUID, `strength` not `signal_type`). The v1 POST API returns 400 from inline Python — use legacy GET. `taste_full_enrich.py` also enriches existing unenriched items but doesn't set `enriched: true` (use `taste_enrich_fix.py` after).
Scanned on Sep 25, 2026
View Security Dashboard
Installation guide →