Repository navigation
0.4.0
0.4.0 — First-user fixes
22 September 2026. Minor on the public 0.3.0 beta.
Fixes the first-user bugs filed against 0.3.0 and the CI harness gaps that let them ship. Several fixes change output that scripts can depend on — read Changed before upgrading a pipeline. If you generated GitHub CI with opentide setup ci, regenerate it — see Security.
Install
pip install opentide==0.4.0
export OPENTIDE_REPO_ROOT=/path/to/detection-repo
opentide validate --strictRegenerate generated CI and hooks to pick up the fixed templates:
opentide setup ci <github|gitlab|azure> --yes
opentide setup hooks --yesSecurity
- The inflight job from
opentide setup ci githubpushed the pull request head to the default branch, so an up-to-date pull request landed there unreviewed. Inflight jobs on every CI now commit only.opentide/inflight/shards, from a worktree of the default branch. Regenerate withopentide setup ci <github|gitlab|azure> --yes(#244).
Changed
opentide validate queryis an offline syntax check (KQL, SPL, S1QL, Lucene) by default and needs no SDK, credentials, or network. The tenant round-trip isvalidate query --live(#239).validate queryfor CrowdStrike and HarfangLab returns the normalok/statusenvelope withsupported: false(#247).queryis required and non-blank on Splunk and Carbon Black configurations (#233).opentide --json setupwithout--yesexits with one JSON error instead of starting the wizard (#255).- MCP
searchalways returns a list;platform=matches the configuration key exactly;coveragefor a parent technique includes sub-technique rules and reportsmatched_techniques(#252, #253). - MCP
opentide://vocabulariesis an index (metadata,entry_count,uri); entries live atopentide://vocabularies/{name}(#254). - MCP
run_queryis an explicit stub (stub: true,rows: null) (#258). mcpis pinned<2; the unusedfastmcpdependency is gone;opentide[sentinel]declares the Azure packages it imports (#256).- Positional
PATHonsetupsubcommands is deprecated in favour of--path/-C(#248).
Fixed
deploy metadataandgenerate inflight pruneno longer run their parent command first (#243).opentide info coverage --technique T1059parses in either order (#257).- Every
setupsubcommand accepts--path/-Cand--yes/-y, also when given before the subcommand; othersetupoptions there are refused rather than ignored, without hiding the subcommand's--help(#248). validate --file objects/rules/x.yamlhonours the directory, in the ID check and the MCPvalidation_reporttool too (#240).- Unparseable object YAML is a
yaml_parsevalidation issue, not a traceback (#250). generate docs --changed/generate inflighthandle repositories without commits, non-maintrunks, untracked rules, non-ASCII file names, pushed feature branches, and workspaces nested inside the checkout (#241, #251).generate extract sentinel|defenderreport the missing extra, tenant, or key instead of failing at import (#242).opentide generate exploreris registered; the GitHub CI template calls it instead ofopentide explorer build(#202).- Sentinel-only runs load only the Sentinel engine, and an engine that fails to load is reported instead of a traceback (#246).
- GitLab inflight jobs use
${CI_JOB_TOKEN}; Azure inflight jobs actually commit and push; GitHub and Azure jobs target the repository's default branch instead ofmain; inflight jobs retry when another job publishes first and keep other pull requests' shards (#244). - The pre-commit hook validates the commit's worktree, not an exported
OPENTIDE_REPO_ROOT; it covers nested and multiple workspaces, fails when its workspace is gone, and is not installed into a user-widecore.hooksPath(#249). --no-color,NO_COLOR,FORCE_COLOR=0, andPY_COLORS=0strip every ANSI escape, Typer help and usage errors included (#282).- MCP reads
rule.techniques/threat.actors, filters UUID searches, and matches UUIDs case-insensitively insearchandget_chaining(#252), resolvesopentide://schemas/ruleand versioned template IDs (#254), andvalidate_queryreports real findings (#245). opentide-mcpwithout themcpextra prints the install line instead of a traceback (#256).splunk::2.xrules validate and deploy with the same field mapping, and a migratedcron_scheduleis scheduled (#233).- Tutorial and CLI reference samples match live output (#247).
Tests
CI now runs the first-user paths these bugs lived on (#259): real-PTY setup (#260), real query validators (#261), opentide-mcp from the wheel (#262), an argv matrix (#263), unmocked MCP over stdio (#264), hooks that git commit (#265), unmocked extract/explorer (#266), repo-relative --file (#267), git baselines (#268), GitLab/Azure job scripts (#269), and every documented command checked against the CLI (#270).
Not in this release: #189, which waits on OpenTideHQ/specifications#12.
Verify
python -c "import opentide; print(opentide.__version__)"
opentide setup --yes --name "Tutorial Detections" --org "Example Corp" --platform sentinel --path /tmp/tutorial-detections
opentide --repo /tmp/tutorial-detections generate
opentide --repo /tmp/tutorial-detections validate --strict
opentide --json --repo /tmp/tutorial-detections validate query --platform sentinelExpect 0.4.0. validate query must succeed with mode: offline-syntax on a plain pip install opentide (no Azure SDK).
Links
License: EUPL-1.2. Issues: OpenTideHQ/opentide.