← Back to blog

The engine is OpenTide now

pip install opentide==0.1.0. First public beta. We are archiving the old engine, keeping pinned checkouts alive, and taking four weeks of bug reports.

By OpenTide Team

announcementdetectionops

The engine used to ship as a git submodule. It is a PyPI package now — pip install opentide==0.1.0 — CLI, MCP, and SDK on the same object graph. That is the default for new work. Notes: 0.1.0.

Not a hard cut. If you already have a pinned checkout of the old engine, it keeps working. We are not going to break your git history to prove a point. New work does not go into the archived tree.

  1. 01

    Engine on PyPI

    pip install opentide==0.1.0 — CLI, MCP, and SDK on one version.

  2. 02

    Old tree archived

    The old engine and companion repos go read-only. Pinned checkouts keep resolving.

  3. 03

    Four-week window

    Deployer bugs, docs, and migration questions. We are not adding platforms in this stretch.

Why we did this

You can already write detections for Sentinel, Splunk, Defender, SentinelOne, Carbon Black, CrowdStrike, and HarfangLab. What kept breaking was the shared engine: it was not a version you could pin, not a reviewable upgrade, and every instance rewrote the same CI glue.

The old engine lived in the client repo as a submodule. Imports walked git to find sys.path. You pinned a SHA, hoped the next pull left Orchestration/ alone, and could not write opentide==0.4 and go home.

Schemas lived in three places — YAML metaschemas, Python dataclasses, and the loaders that tried to keep them aligned. They drifted. Vocabularies were untyped. A couple of generators even duplicated their own enum descriptions.

CI needs three things from an engine: a schema that matches the objects, a capability report that is true, and an exit code you can gate on. So we rebuilt it as a package, in a new repository, instead of renovating the submodule in place. The old tree stays as history. The new one never inherited the sys.path tricks.

flowchart TB
  subgraph oldStack [Old stack]
    direction TB
    clientOld[Client repo] --> submodule[Git submodule]
    submodule --> sysPath["sys.path hacks"]
    sysPath --> scripts[Orchestration scripts]
  end
  subgraph newStack [New stack]
    direction TB
    clientNew[Client repo] --> pkg[opentide package]
    pkg --> cli[CLI]
    pkg --> sdk[SDK]
    pkg --> mcp[MCP]
  end
  oldStack -.->|soft cutover| newStack
import sys, git
sys.path.append(str(git.Repo(".", search_parent_directories=True).working_dir))
from Engines.modules.tide import DataTide
from Engines.modules.plugins import DeployTide

rule = DataTide.Models.mdr[uuid]
DeployTide.mdr["sentinel"].deploy(...)
python Orchestration/validate.py
from opentide import OpenTide

OpenTide.initialise()
rule = OpenTide.Rules[uuid]
rule.deploy("sentinel")
pip install opentide==0.1.0
opentide validate --strict
opentide deploy --platform sentinel --dry-run

What you get now

You pin a version, not a submodule SHA. pip install opentide==0.1.0, then lock it like any other dependency.

CLI, SDK, and MCP are the same package — opentide validate, from opentide import OpenTide, opentide-mcp. Not three engines, and not a pile of Orchestration/ scripts.

JSON Schema is generated from the models, so the types and the schema cannot drift. Models are the source of truth; the schema is what CI and editors actually consume. Detection content stays in your repo. That split is the point of a dependency.

  1. Validate

    Schema, query, and platform honesty checks

  2. Generate

    Schemas, templates, and indexes from your repo

  3. Deploy

    Seven platforms, dry-run before production

  4. Document

    Published narratives for analysts and auditors

The object model did not change in spirit. A threat is still what you defend against, an objective is still what you are trying to detect, a rule is still how you detect it on a platform. References still point rule → objective → threat. Coverage still flows the other way.

flowchart LR
  subgraph refs [References]
    direction LR
    Rule -->|detection_model| Objective
    Objective -->|threats| Threat
  end
  Threat -. "is covered by" .-> Objective
  Objective -. "is implemented by" .-> Rule

Seven platforms deploy. Five validate query syntax — KQL, SPL, S1QL, Lucene. CrowdStrike and HarfangLab cannot. The CLI and MCP report supported: false there instead of inventing a pass.

Soft rollout

We are archiving the old engine and companion repos. History stays. Issues stay. The READMEs will point here. New work goes in the package.

Pinned submodule SHAs and existing clones keep working. Existing production instances do not have to move this week. They should move when they next touch CI — not in a panic, and not by rewriting history.

There is no magic opentide migrate. The migration guide is the path: drop the submodule, replace Orchestration/ with the CLI, set OPENTIDE_REPO_ROOT, run opentide validate --strict. If you would rather have someone else do the mechanical edits, there is a prompt on that page. Review the diff as if a colleague wrote it.

Archive

The old engine and companion repos go read-only. SHAs and clones you already have are unaffected.

Migrate when you next touch CI

Remove the submodule. pip install opentide==0.1.0. Swap python Orchestration/validate.py for opentide validate --strict. Keep --platform; do not bring back --system.

Four weeks of support

We are not adding platforms in this stretch. We will fix deployer bugs, docs, setup, and migration questions. After that we can talk about 1.0.

Four weeks

The package works. The docs are in better shape than they have ever been. For four weeks we are not adding platforms. We will fix what you hit: validation that is too loud or too quiet, a deployer that misbehaves on a tenant you actually have, a setup wizard that writes the wrong MCP path, a migration step the guide forgot.

If something is wrong, file it on OpenTideHQ/opentide. That is the engine now. The archived tree will not grow new fixes.

The old engine ran in production for years before it was open-sourced. The work was to make that practice installable, and to stop lying about platforms that cannot validate a query. Then we take four weeks of bug reports.