Generated banner for Let Fate Decide
Generated logo for Let Fate Decide

Let Fate Decide

Trail of BitsOfficialPublished by Trail of Bits

  • Skill
  • Role or persona
  • Agent tooling
  • CC-BY-SA-4.0
  • Low risk
  • Has scripts

From the author

Draws 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 asking clarifying questions when the user's tone is casual or playful rather than precision-seeking.
— the description by Trail of Bits

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

let-fate-decide provides a structured, randomized approach to decision-making when users provide ambiguous, nonchalant, or playful prompts. By drawing a 12-house Zodiac Tarot spread, the agent generates a narrative framework to guide its next steps, helping to break analysis paralysis or resolve ties between multiple valid technical approaches. It is designed to be used as a creative lens for discovery and hypothesis generation, particularly in security and engineering contexts, rather than as a replacement for rigorous evidence-based verification.

What it does

  • Performs a 12-house Zodiac Tarot spread using cryptographically secure randomness.
  • Maps archetypal card meanings to technical contexts like audit stages, failure classes, and domain-specific challenges.
  • Provides a structured narrative to help prioritize investigation paths or architectural decisions.
  • Supports legacy modes for custom-sized card draws.
  • Integrates with technical context lenses to translate abstract readings into actionable engineering tasks.
  • Ensures reproducibility and transparency by outputting the full spread in JSON format.

When to use it

  • When a user prompt is vague, ambiguous, or lacks specific requirements.
  • When the user employs casual or nonchalant language like 'YOLO', 'whatever', or 'let fate decide'.
  • When you need to break a tie between multiple reasonable technical approaches.
  • When you need a creative, non-obvious angle for security discovery or hypothesis generation.
  • When the user's tone is playful and precision is not the primary goal.

Advantages

  • Injects genuine entropy into planning to avoid repetitive or biased decision-making.
  • Provides a consistent, structured framework for interpreting ambiguous requests.
  • Helps surface blind spots by forcing consideration of different archetypal perspectives.
  • Maintains a clear separation between the creative 'reading' and the required technical evidence.
  • Reduces the need for back-and-forth clarifying questions in casual interactions.

Usage examples

“I don't know, just pick a way to test this API, let fate decide.”
The agent draws the 12-house spread, interprets the cards through the 'Audit Pipeline' and 'Domain' lenses, and proposes a specific testing strategy based on the resulting narrative.
“YOLO, how should I refactor this legacy module?”
The agent performs a reading to identify potential risks and architectural priorities, then suggests a refactoring plan aligned with the cards' themes.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/trailofbits/let-fate-decide/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip let-fate-decide.zip -d .agents/skills

Documentation by Trail of Bits

Let Fate Decide

When the path forward is unclear, let the cards speak.

Quick Start

Resolve the drawing script from this SKILL.md's installed location, not the shell's working directory. In the commands below, replace <resolved-script-path> with that absolute path, keeping the quotes. Relative links and JSON file paths resolve from the directory containing this SKILL.md.

  1. Run the drawing script:

    uv run --no-config "<resolved-script-path>"
  2. The script outputs JSON for the default 12 Houses of the Zodiac spread: 12 houses, each with 1 Major Arcana card and 2 Minor Arcana cards. Each house and card includes a file path relative to this SKILL.md's directory.

  3. Read each house file and each card's meaning file to understand the draw. For faster reads, use --content to include house and card text directly in the JSON:

    uv run --no-config "<resolved-script-path>" --content
  4. Interpret the spread using the interpretation guide

  5. When the task belongs to a specialized technical workflow, use technical context lenses to translate the reading into an audit, verification, domain, failure-class, or stakeholder lens

  6. Apply the interpretation to the task at hand

When to Use

  • Vague prompts: The user's request is ambiguous and multiple reasonable approaches exist

  • Explicit invocations: "I'm feeling lucky", "let fate decide", "dealer's choice", "surprise me", "whatever you think", "YOLO"

  • Casual delegation: "whatever", "up to you", "your call", "idk", "just do something", "wing it", "I trust you", "doesn't matter", "do what you want", "I don't care", "any approach works", "you pick"

  • Yu-Gi-Oh energy: "Heart of the cards", "I believe in the heart of the cards", "you've activated my trap card", "it's time to duel"

  • Shrug-like brevity: Very short prompts that fully delegate the decision without expressing a preference

  • Redraw requests: "Try again" or "draw again" when no actual system changes occurred (this means draw new cards, not re-run the same approach)

  • Tie-breaking: When you are about to arbitrarily pick between 2+ valid approaches, draw cards instead of silently choosing one

When NOT to Use

  • The user has given clear, specific instructions

  • The task has a single obvious correct approach

  • As the deciding authority for safety-critical work (security, data integrity, production deployments, release approval, incident response)

  • The user explicitly asks you NOT to use Tarot

  • The user's tone is precision-seeking rather than casual -- ask clarifying questions instead to gather actual requirements

Security and Correctness Use

This skill may be used inside a security, audit, or correctness pipeline as a creative lens for discovery: choosing which angle to inspect next, breaking analysis paralysis, generating hypotheses, or surfacing blind spots.

It is never sufficient by itself. In security and correctness contexts, the reading must be followed by ordinary engineering evidence: source review, tests, proofs, traces, reproduction steps, exploitability analysis, or other domain-appropriate verification. Do not treat a favorable card as permission to ship, suppress a finding, skip validation, or overrule a concrete risk.

How It Works

The Draw

The script uses secrets for cryptographic randomness:

  1. Builds separate Major Arcana (22 cards) and Minor Arcana (56 cards) decks

  2. Performs Fisher-Yates shuffles via secrets.randbelow() (no modulo bias)

  3. Deals the default 12 Houses of the Zodiac spread

  4. Each house receives 1 Major Arcana card followed by 2 Minor Arcana cards

  5. Each of the 36 cards independently has a 50% chance of being reversed

The default spread records a conservative unordered-card entropy budget exceeding 100 bits: roughly log2(C(22,12)) bits from Major Arcana selection, log2(C(56,24)) bits from Minor Arcana selection (assuming secrets.randbelow() is cryptographically secure), plus 36 reversal bits. The exact values are computed and reported in the JSON output under entropy_bits. The actual ordered assignment of cards to houses contains more entropy.

The Spread

The default spread is 12 Houses of the Zodiac:

HouseRepresentsQuestion It Answers
1SelfHow should this work begin?
2ResourcesWhat values, assets, or constraints matter?
3CommunicationWhat needs to be clarified or connected?
4FoundationsWhat context or dependency anchors the task?
5CreativityWhere should experimentation or delight shape the work?
6PracticeWhat quality, maintenance, or execution concern matters?
7PartnershipWho or what must this integrate with?
8TransformationWhat risk, shared state, or deep change is present?
9ExplorationWhat principle or broader strategy guides the path?
10CallingWhat delivery or long-term outcome is being served?
11CommunityWhat system, network, or shared aspiration is involved?
12The HiddenWhat blind spot, ending, or unconscious factor matters?

Within each house, the Major Arcana card sets the archetypal theme and the two Minor Arcana cards provide practical detail.

For compatibility with older workflows, draw_cards.py --legacy returns the previous 4-card hand, and draw_cards.py --legacy <count> returns a custom hand of 1-78 cards. A positional count without --legacy is rejected, because the new default spread has a fixed shape.

Reference Files

Each house's meaning is in its own markdown file under houses/. House files describe how the house applies across technical contexts including building new projects, vulnerability discovery, correctness verification, and common audit, verification, domain, failure-class, and stakeholder workflows.

Each card's meaning is in its own markdown file under cards/:

Interpretation

After drawing, read each house file and each card file, then synthesize meaning. See the interpretation guide for the full interpretation workflow. For cross-domain translation, see technical context lenses.

Key rules:

  • Reversed cards invert or complicate the upright meaning

  • Major Arcana cards carry more weight than Minor Arcana

  • The spread tells a story across all 12 houses; don't interpret cards in isolation

  • Map abstract meanings to concrete technical decisions

  • In security, audit, and correctness work, use the reading to choose an investigation path, then require evidence before accepting or dismissing any risk

  • Never output interpretation as a text-only turn. Include the interpretation alongside your next tool call (the action that implements the chosen option). Prefer --content so all 36 card meanings and all 12 house meanings are available from the draw output.

Example Session (House-Level Fragment)

A real reading synthesizes all 12 houses; the fragment below shows only what one house contributes so the format is clear. Do not stop after one house in actual use.

User: "I dunno, just make it work somehow"

[Draw cards]
1st House (Self): The Magician (upright), Five of Swords (reversed),
                  Ten of Pentacles (upright)

House contribution: The starting stance is resourceful and tool-rich
(Magician), but the practical details warn against combative edge-case work
(Five of Swords reversed) while still favoring maintainable craft
(Ten of Pentacles). This is one input into the overall reading; combine with
the remaining 11 houses before deciding on an approach.

The named draw agent returns a more compact form for portent questions: 3 concise bullets covering the dominant theme, the main risk or blind spot, and the recommended next action.

Error Handling

If the drawing script fails:

  • Script crashes with traceback: Report the error to the user and skip the reading. Do not invent cards or simulate a draw — the whole point is real entropy.

  • Card file not found: Note the missing file, interpret the card from its name and suit alone, and continue with the reading.

  • Never fake entropy: If the script cannot run, do not simulate a draw using your own "randomness." Tell the user the draw failed.

Rationalizations to Reject

RationalizationWhy Wrong
"The cards said to, so I must"Cards inform direction, they don't override safety or correctness
"This reading justifies my pre-existing preference"Be honest if the reading challenges your instinct
"The reversed card means do nothing"Reversed means a different angle, not inaction
"Major Arcana overrides user requirements"User requirements always take priority over card readings
"I'll keep drawing until I get what I want"One draw per decision point; accept the reading
"The reading says the risk is fine"Cards can suggest what to inspect; only evidence can dismiss a security or correctness concern

Files

scripts/test_draw_cards.py

#!/usr/bin/env python3
"""Tests for draw_cards.py."""
# /// script
# requires-python = ">=3.11"
# dependencies = []
# ///

import json
import math
import subprocess
import sys
from collections import Counter
from pathlib import Path

# Import the module under test
sys.path.insert(0, str(Path(__file__).parent))
import draw_cards

SKILL_DIR = Path(__file__).parent.parent


def test_build_deck_has_78_cards():
    deck = draw_cards.build_deck()
    assert len(deck) == 78, f"Expected 78 cards, got {len(deck)}"


def test_build_deck_has_22_major_arcana():
    deck = draw_cards.build_deck()
    majors = [c for c in deck if c[0] == "major"]
    assert len(majors) == 22, f"Expected 22 major arcana, got {len(majors)}"


def test_build_deck_has_56_minor_arcana():
    deck = draw_cards.build_deck()
    minors = [c for c in deck if c[0] != "major"]
    assert len(minors) == 56, f"Expected 56 minor arcana, got {len(minors)}"


def test_build_minor_deck_has_56_cards():
    deck = draw_cards.build_minor_deck()
    assert len(deck) == 56, f"Expected 56 minor cards, got {len(deck)}"


def test_build_minor_deck_excludes_major_arcana():
    deck = draw_cards.build_minor_deck()
    assert all(suit != "major" for suit, _ in deck)


def test_build_deck_all_unique():
    deck = draw_cards.build_deck()
    card_ids = [c[1] for c in deck]
    assert len(card_ids) == len(set(card_ids)), "Duplicate card IDs found"


def test_build_deck_four_suits_14_each():
    deck = draw_cards.build_deck()
    suits = Counter(c[0] for c in deck if c[0] != "major")
    for suit in ["wands", "cups", "swords", "pentacles"]:
        assert suits[suit] == 14, f"Expected 14 {suit}, got {suits[suit]}"


def test_draw_cards_returns_requested_count():
    for n in [1, 2, 4, 10]:
        hand = draw_cards.draw_cards(n)
        assert len(hand) == n, f"draw({n}) returned {len(hand)} cards"


def test_draw_cards_default_is_4():
    hand = draw_cards.draw_cards()
    assert len(hand) == 4


def test_draw_zodiac_spread_default_shape():
    hand = draw_cards.draw_zodiac_spread()
    assert hand["spread"] == draw_cards.SPREAD_NAME
    assert len(hand["houses"]) == 12


def test_draw_cards_clamps_to_78():
    hand = draw_cards.draw_cards(100)
    assert len(hand) == 78


def test_draw_cards_zero_returns_empty():
    hand = draw_cards.draw_cards(0)
    assert len(hand) == 0


def test_draw_cards_card_structure():
    hand = draw_cards.draw_cards(1)
    card = hand[0]
    assert "suit" in card
    assert "card_id" in card
    assert "reversed" in card
    assert "position" in card
    assert "file" in card
    assert isinstance(card["reversed"], bool)
    assert card["position"] == 1
    assert card["file"].startswith("cards/")
    assert card["file"].endswith(".md")


def test_draw_cards_positions_are_sequential():
    hand = draw_cards.draw_cards(4)
    positions = [c["position"] for c in hand]
    assert positions == [1, 2, 3, 4]


def test_draw_cards_no_duplicate_cards():
    hand = draw_cards.draw_cards(78)
    card_ids = [c["card_id"] for c in hand]
    assert len(card_ids) == len(set(card_ids)), "Duplicate cards drawn"


def test_zodiac_spread_shape():
    spread = draw_cards.draw_zodiac_spread()
    assert spread["spread"] == "12 Houses of the Zodiac"
    bits = spread["entropy_bits"]
    expected_major = round(math.log2(math.comb(22, 12)), 2)
    expected_minor = round(math.log2(math.comb(56, 24)), 2)
    assert bits["major_arcana"] == expected_major
    assert bits["minor_arcana"] == expected_minor
    assert bits["reversals"] == 36.0
    assert bits["total"] == round(expected_major + expected_minor + 36.0, 2)
    assert bits["total"] >= 100, "Entropy budget must clear the 100-bit floor"
    assert len(spread["houses"]) == 12
    for house in spread["houses"]:
        assert set(house) == {"house", "name", "focus", "file", "cards"}
        assert house["file"].startswith("houses/")
        assert house["file"].endswith(".md")
        assert len(house["cards"]) == 3


def test_zodiac_house_files_exist():
    spread = draw_cards.draw_zodiac_spread()
    for house in spread["houses"]:
        path = SKILL_DIR / house["file"]
        assert path.exists(), f"Missing house file: {path}"


def test_zodiac_focus_matches_house_domain():
    spread = draw_cards.draw_zodiac_spread()
    for house in spread["houses"]:
        text = (SKILL_DIR / house["file"]).read_text()
        domain = next(
            line[len("**Domain**: ") :].strip()
            for line in text.splitlines()
            if line.startswith("**Domain**: ")
        )
        assert house["focus"] == domain, (
            f"focus/Domain drift in {house['file']}: {house['focus']!r} != {domain!r}"
        )


def test_zodiac_house_files_cover_technical_contexts():
    spread = draw_cards.draw_zodiac_spread()
    for house in spread["houses"]:
        text = (SKILL_DIR / house["file"]).read_text()
        assert "## Building New Projects" in text
        assert "## Vulnerability Discovery" in text
        assert "## Correctness Verification" in text
        assert "## Technical Workflow Lenses" in text


def test_technical_context_lenses_reference_exists():
    reference = SKILL_DIR / "references" / "TECHNICAL_CONTEXT_LENSES.md"
    text = reference.read_text()
    assert "## Audit Pipeline Stage" in text
    assert "## Evidence Mode" in text
    assert "## Domain Lens" in text
    assert "## Failure Class Lens" in text
    assert "## Human and Organizational Lens" in text
    assert "## House Affinity Map" in text


def test_security_framing_requires_evidence():
    skill_text = (SKILL_DIR / "SKILL.md").read_text()
    guide_text = (SKILL_DIR / "references" / "INTERPRETATION_GUIDE.md").read_text()
    assert "Security and Correctness Use" in skill_text
    assert "never sufficient by itself" in skill_text
    assert "only evidence can dismiss a security or correctness concern" in skill_text
    assert "cannot prove safety, dismiss a finding, or replace" in guide_text


def test_numbered_ranks_are_numeric_across_all_suits():
    word_ranks = ("Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten")
    for card_file in (SKILL_DIR / "cards").glob("*/*.md"):
        if card_file.parent.name == "major":
            continue
        text = card_file.read_text()
        for word in word_ranks:
            assert f"**Rank**: {word}" not in text, (
                f"{card_file} still uses word-form rank '{word}'; use the digit form"
            )


def test_reviewed_cards_avoid_unsafe_shortcuts():
    """Regression guard: these exact phrases were removed in 1.2.0; do not reintroduce.

    This is an exact-string blacklist, not a semantic check. Add new bad phrases
    here as they are identified during review; rewordings of existing phrases
    will not trip this test and must be caught manually.
    """
    risky_phrases = (
        "Follow your intuition on this one",
        "The solution that feels right probably is",
        "Ship it.",
        "The approach is sound.",
        "The approach will succeed.",
        "Speed matters here—refine later.",
    )
    for card_file in (SKILL_DIR / "cards").glob("*/*.md"):
        text = card_file.read_text()
        for phrase in risky_phrases:
            assert phrase not in text, f"{phrase!r} still appears in {card_file}"


def test_zodiac_spread_content_includes_house_content():
    spread = draw_cards.draw_zodiac_spread(include_content=True)
    for house in spread["houses"]:
        assert "content" in house
        assert house["content"].startswith("# ")


def test_zodiac_spread_uses_one_major_per_house():
    spread = draw_cards.draw_zodiac_spread()
    major_cards = []
    for house in spread["houses"]:
        card = house["cards"][0]
        assert card["role"] == "major_arcana"
        assert card["suit"] == "major"
        major_cards.append(card["card_id"])
    assert len(major_cards) == 12
    assert len(set(major_cards)) == 12


def test_zodiac_spread_uses_two_minors_per_house():
    spread = draw_cards.draw_zodiac_spread()
    minor_cards = []
    for house in spread["houses"]:
        for card in house["cards"][1:]:
            assert card["role"] in {"minor_arcana_1", "minor_arcana_2"}
            assert card["suit"] != "major"
            minor_cards.append(card["card_id"])
    assert len(minor_cards) == 24
    assert len(set(minor_cards)) == 24


def test_zodiac_spread_all_cards_can_be_reversed():
    spread = draw_cards.draw_zodiac_spread()
    cards = [card for house in spread["houses"] for card in house["cards"]]
    assert len(cards) == 36
    assert all(isinstance(card["reversed"], bool) for card in cards)


def test_zodiac_spread_positions_are_sequential():
    spread = draw_cards.draw_zodiac_spread()
    positions = [card["position"] for house in spread["houses"] for card in house["cards"]]
    assert positions == list(range(1, 37))


def test_fisher_yates_preserves_elements():
    deck = draw_cards.build_deck()
    original = sorted(deck)
    draw_cards.fisher_yates_shuffle(deck)
    assert sorted(deck) == original, "Shuffle changed deck elements"


def test_fisher_yates_single_element():
    deck = [("major", "00-the-fool")]
    draw_cards.fisher_yates_shuffle(deck)
    assert deck == [("major", "00-the-fool")]


def test_fisher_yates_empty():
    deck = []
    draw_cards.fisher_yates_shuffle(deck)
    assert deck == []


def test_is_reversed_returns_bool():
    for _ in range(20):
        assert isinstance(draw_cards.is_reversed(), bool)


def test_shuffle_produces_varying_orders():
    """Run 5 shuffles; at least 2 should differ (p(all same) ~ 0)."""
    orders = []
    for _ in range(5):
        deck = draw_cards.build_deck()
        draw_cards.fisher_yates_shuffle(deck)
        orders.append(tuple(c[1] for c in deck))
    assert len(set(orders)) >= 2, "All 5 shuffles identical"


def test_reversal_produces_both_values():
    """Over 100 flips, both True and False should appear."""
    results = {draw_cards.is_reversed() for _ in range(100)}
    assert True in results, "Never got reversed=True in 100 flips"
    assert False in results, "Never got reversed=False in 100 flips"


def test_no_os_urandom_import():
    """Verify os.urandom is not used; os may be imported for path operations."""
    source = Path(__file__).parent / "draw_cards.py"
    text = source.read_text()
    assert "os.urandom" not in text, "os.urandom still referenced"


def test_uses_secrets_module():
    """Verify secrets module is used."""
    source = Path(__file__).parent / "draw_cards.py"
    text = source.read_text()
    assert "import secrets" in text
    assert "secrets.randbelow" in text
    assert "secrets.randbits" in text


def test_cli_default_output():
    """Run the script and verify JSON output with the default spread."""
    result = subprocess.run(
        [sys.executable, str(Path(__file__).parent / "draw_cards.py")],
        capture_output=True,
        text=True,
    )
    assert result.returncode == 0
    spread = json.loads(result.stdout)
    assert spread["spread"] == draw_cards.SPREAD_NAME
    assert len(spread["houses"]) == 12


def test_cli_legacy_custom_count():
    result = subprocess.run(
        [sys.executable, str(Path(__file__).parent / "draw_cards.py"), "--legacy", "2"],
        capture_output=True,
        text=True,
    )
    assert result.returncode == 0
    cards = json.loads(result.stdout)
    assert len(cards) == 2


def test_cli_legacy_default_count():
    result = subprocess.run(
        [sys.executable, str(Path(__file__).parent / "draw_cards.py"), "--legacy"],
        capture_output=True,
        text=True,
    )
    assert result.returncode == 0
    cards = json.loads(result.stdout)
    assert len(cards) == 4


def test_cli_positional_count_without_legacy_is_error():
    """Positional count requires --legacy; the new default has a fixed shape."""
    result = subprocess.run(
        [sys.executable, str(Path(__file__).parent / "draw_cards.py"), "4"],
        capture_output=True,
        text=True,
    )
    assert result.returncode == 1
    assert "--legacy" in result.stderr


def test_cli_invalid_arg():
    result = subprocess.run(
        [sys.executable, str(Path(__file__).parent / "draw_cards.py"), "--legacy", "abc"],
        capture_output=True,
        text=True,
    )
    assert result.returncode == 1
    assert "Error" in result.stderr


def test_cli_out_of_range():
    result = subprocess.run(
        [sys.executable, str(Path(__file__).parent / "draw_cards.py"), "--legacy", "0"],
        capture_output=True,
        text=True,
    )
    assert result.returncode == 1

    result = subprocess.run(
        [sys.executable, str(Path(__file__).parent / "draw_cards.py"), "--legacy", "79"],
        capture_output=True,
        text=True,
    )
    assert result.returncode == 1


def test_no_secure_randbelow_function():
    """Regression: the custom secure_randbelow must be removed."""
    source = Path(__file__).parent / "draw_cards.py"
    text = source.read_text()
    assert "def secure_randbelow" not in text, "Custom secure_randbelow still exists"


def test_constants_are_immutable():
    """Constants must be tuples to prevent mutation."""
    assert isinstance(draw_cards.MAJOR_ARCANA, tuple), "MAJOR_ARCANA is not a tuple"
    assert isinstance(draw_cards.RANKS, tuple), "RANKS is not a tuple"
    assert isinstance(draw_cards.SUITS, tuple), "SUITS is not a tuple"
    assert isinstance(draw_cards.ZODIAC_HOUSES, tuple), "ZODIAC_HOUSES is not a tuple"


def test_draw_cards_rejects_non_int():
    """draw_cards() must reject non-int types cleanly."""
    for bad in [None, "3", 2.5, True, False, [4]]:
        try:
            draw_cards.draw_cards(bad)
            assert False, f"draw_cards({bad!r}) should have raised TypeError"
        except TypeError:
            pass


if __name__ == "__main__":
    tests = [v for k, v in sorted(globals().items()) if k.startswith("test_")]
    passed = failed = 0
    for test in tests:
        try:
            test()
            passed += 1
            print(f"  PASS  {test.__name__}")
        except AssertionError as e:
            failed += 1
            print(f"  FAIL  {test.__name__}: {e}")
        except Exception as e:
            failed += 1
            print(f"  ERROR {test.__name__}: {e}")
    print(f"\n{passed} passed, {failed} failed, {passed + failed} total")
    sys.exit(1 if failed else 0)

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Declares allowed tools, Needs Python

Security

What our scanner noticed· Low risk

  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Trail of Bits
Publisher
Trail of Bits (Official)
Source
trailofbits/skills · plugins/let-fate-decide/skills/let-fate-decide · commit e4dd0bb
Licence
Creative Commons Attribution-ShareAlike 4.0 International (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Trail of Bits.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download let-fate-decide.zip