# Comparison With Other Automation Systems > How BountyHub workflows compare to CI/CD pipelines, cron + scripts, and automation platforms for bug bounty work. ## BountyHub Workflows vs. Other Systems If you have hunted with a folder of shell scripts, a cron tab, or a CI system repurposed for recon, BountyHub workflows will feel familiar — but they solve different problems. ### vs. CI/CD Pipelines (GitHub Actions, GitLab CI) CI systems are built for a different lifecycle: an event happens (a push), a pipeline runs once to completion, and it exits. Bug bounty hunting is the opposite: continuous, event-driven, and always on.
Aspect CI pipeline BountyHub workflow
Lifecycle Trigger → run → exit Continuous activities reacting to events
Language YAML Starlark — typed, validated at save time
Data flow Implicit filesystem sharing within a job Explicit resources; references define ordering
Parallelism Matrix hacks, brittle First-class: step.parallel , step.for_each
Secrets Repo/org secrets interpolated into YAML config.* references resolved at execution; never serialized
Long-running Hostile (runner limits) Designed for it: timeouts, durable state
A typical "recon in GitHub Actions" setup is a YAML file with `cron` schedule, a pile of `run: |` blocks piping tools together, and `artifacts:` stanzas. It works until you need branching logic, per-target fan-out with concurrency limits, or typed data handling — then it collapses into unmaintainable shell. The same hunt as a BountyHub workflow is explicit about all three: ```bhw step.for_each( items = path.file("live.txt").lines().unique().partition(partition.count(20)), do = lambda batch: [ step.exec(command = ["nuclei", "-l", batch.as_file(), "-severity", "critical"]), ], concurrency = 10, ) ``` ### vs. Cron + Shell Scripts Scripts are how everyone starts. They fail in predictable ways: - **No structure.** Concurrency is `&` and `wait`; failure handling is `|| true` sprinkled everywhere. A crashed scan at hour 3 of 6 loses everything after it. - **No types.** Every interchange format is "text I hope I parsed right". BountyHub transforms are statically type-checked before your workflow ever runs. - **No state.** If the box reboots mid-scan, you start over. Workflow execution is durable: branches, steps, and waiting states survive recovery. - **No visibility.** Scripts log to files you never read. Every workflow run has structured step status, artifacts, and history. ### vs. One-Off Automation Platforms (n8n, Zapier) Low-code platforms excel at connecting SaaS APIs. They are a poor fit for security tooling: no process execution, no filesystem model, and expressing "run subfinder, normalize, partition across 20 workers, scan each batch" through a visual graph is misery. BountyHub keeps the declarative benefits — validated definitions, triggers, reusable modules — while speaking the native language of security tooling: processes, files, and pipelines. ### What Stays the Same BountyHub deliberately keeps the good ideas from those systems: - **Triggers** feel like cron and webhooks — `trigger.cron("0 0 * * *")`, `trigger.on(scan.succeeded())`, `trigger.dispatch()`. - **Conditions** feel like `if:` in Actions — `cond = lambda run: ...`. - **Modules** feel like reusable actions or Terraform modules — published, versioned building blocks with explicit contracts (`load()` + `step.module(inputs = {...})`). - **Artifacts** feel like CI artifacts — `upload_artifact` / `download_artifact` move files between phases. ### The Core Difference Other systems run jobs. BountyHub runs your hunting methodology: activities that discover assets, transform and store them, scan them in bounded parallel batches, triage findings with agents, and notify you — continuously, with every phase validated before it ever executes.