trigger-policy
Enforce FlowTrigger safety rules — no autonomous merge, no recursive trigger creation, max active triggers, allowed_actions / forbidden_actions ACLs. Validates trigger YAMLs at `.flow/triggers/*.trigger.yaml` against `schemas/v1/trigger.schema.json` AND cross-checks policy.forbidden_actions includes merge + release; refuses triggers that grant Tier 3 autonomy. Use when /flow:trigger create, /flow:trigger run, or /flow:watch is invoked. This skill MUST be consulted because triggers can fire without user supervision — a trigger granting merge autonomy is the single fastest path to an untrusted-merge incident, and recursive trigger creation is the loop-bomb shape of the runtime layer.
What this skill does
# Trigger Policy
You own FlowTrigger safety. Triggers fire without direct user supervision in many cases (CI events, scheduled runs); the policy in this skill is the last line of defense against unintended-action triggers.
## Iron Law
**`merge` and `release` MUST appear in every trigger's `policy.forbidden_actions`. Triggers cannot grant Tier 3 autonomy regardless of any other configuration. This is non-negotiable.**
## Inputs
The invoking command MUST pass:
1. **Trigger YAML path** — either a template under `plugins/flow/triggers/templates/` or a project-local trigger at `.flow/triggers/<id>.trigger.yaml`.
2. **Mode** — `validate | enforce`. Validate is read-only (used by /flow:trigger validate); enforce is the gate before /flow:trigger run actually dispatches the target command.
## Outputs
Structured JSON report:
```json
{
"trigger_id": "pr-123-watch",
"schema_valid": true,
"tier3_violations": [],
"recursion_violations": [],
"missing_required_forbidden": [],
"cross_reference_violations": [],
"concurrency_violations": [],
"overall": "pass"
}
```
Exit code: 0 on pass; 1 on policy violation; 2 on schema invalid.
## Workflow
### Step 1: Schema validation
```bash
python3 -m jsonschema -i "${TRIGGER_YAML}" "plugins/flow/schemas/v1/trigger.schema.json"
```
Failure → `overall: schema_invalid` (exit 2).
### Step 2: Tier 3 absolute deny
Verify `policy.forbidden_actions` contains both `merge` AND `release`. Missing either → `tier3_violations.append({"action": "merge_or_release", "reason": "must be forbidden"})`. Hard fail.
### Step 3: Recursion policy check
Verify `recursion_policy.triggered_runs_may_create_triggers` is `false` (or unset; default is false). Same for `triggered_runs_may_modify_triggers` and `triggered_runs_may_enable_triggers`. Any set to `true` requires explicit Tier 3 authorization — surface as `recursion_violations` and require AskUserQuestion at /flow:trigger create time.
### Step 4: Allowed-types check
Verify `trigger.type` is in `flow.triggers.allowedTypes` (cascade-resolved; default `[manual, hook, loop_prompt]`). Trigger types `github_actions | local_cron | local_daemon` are valid schema but disabled in v3.0 — surface as `tier3_violations` if the project's setting doesn't permit them.
### Step 5: Active-trigger count
Count `.flow/triggers/*.trigger.yaml` files with `metadata.enabled: true` AND lifecycle != disabled. If count >= `flow.triggers.maxActiveTriggers` (cascade-resolved; default 5), refuse to enable a new trigger. The user must `/flow:trigger disable` an existing one first.
### Step 6: Concurrency sanity check
If `concurrency.policy: cancel_previous` is set on a trigger whose target invokes a Tier 2 action (e.g., push, commit), surface a warning — cancel_previous + Tier 2 can produce partial commits.
### Step 7: Target workflow cross-reference
If `target.workflow` is set, verify the referenced workflow exists. Check both locations:
```bash
WF="${target_workflow}"
PLUGIN_PATH="plugins/flow/workflows/${WF}.workflow.yaml"
LOCAL_PATH=".flow/workflows/${WF}.workflow.yaml"
[ -f "$PLUGIN_PATH" ] || [ -f "$LOCAL_PATH" ]
```
Missing → `cross_reference_violations.append({"type": "missing_target_workflow", "name": target_workflow, "checked_paths": [PLUGIN_PATH, LOCAL_PATH]})`. **Hard fail** (exit 1) — a trigger that points at a non-existent workflow can never do meaningful work and is broken by construction. This catches typos (e.g., `address` instead of `address-pr`) at trigger creation time rather than at runtime when `/flow:run trigger <id>` tries to dispatch.
If `target.workflow` is absent (the trigger uses `target.command` directly without naming a workflow), this step is a no-op.
### Step 8: Compose overall verdict
| Condition | overall |
|---|---|
| schema fails | `schema_invalid` (exit 2) |
| `tier3_violations` non-empty | `tier3_violation` (exit 1; HARD FAIL) |
| `recursion_violations` non-empty | `recursion_violation` (exit 1) |
| `cross_reference_violations` non-empty | `cross_reference_failed` (exit 1; HARD FAIL — missing target workflow) |
| `concurrency_violations` non-empty | `concurrency_warning` (exit 0 — soft warning) |
| else | `pass` (exit 0) |
## Anti-patterns
- ❌ Allowing a trigger that grants merge/release autonomy. Non-negotiable.
- ❌ Allowing recursive trigger creation without explicit user approval. Loop-bomb shape.
- ❌ Treating soft-warning concurrency violations as hard fails (over-blocks).
- ❌ Skipping the active-trigger count check — unbounded trigger growth defeats the maxActiveTriggers budget.
## Reuse map
- `plugins/flow/schemas/v1/trigger.schema.json` — schema this skill validates against.
- `plugins/flow/triggers/templates/` — plugin-shipped templates.
- `plugins/flow/commands/trigger.md` — `/flow:trigger` command that invokes this skill.
- `plugins/flow/commands/watch.md` — `/flow:watch` command that creates triggers from templates.
- `plugins/flow/references/flow-triggers.md` — user-facing trigger documentation.
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.