@@ -84,6 +84,12 @@ parameters; `CLICKLISP_FORMAT` and `CLICKLISP_PLAY` override the output
8484format and the endpoint. One statement per invocation (the ClickHouse
8585HTTP interface is single-statement).
8686
87+ The same queries run as [ live demos] ( https://cl.clickhouse.com/#demos )
88+ in the browser: the site's deploy workflow builds the binary, compiles
89+ the example libraries with ` rules json ` , and each demo page sends the
90+ compiled SQL to the playground with typed ` param_ ` bindings — no server
91+ of ours in the path.
92+
8793## The query language
8894
8995Operators and clause names are matched by symbol * name* , so forms can be
@@ -168,8 +174,15 @@ Rules are validated (compiled) at load time and rendered on demand:
168174clicklisp rules --load rules.lisp # list
169175clicklisp rules sql --load rules.lisp --all # emit SQL for all
170176clicklisp rules sql --load rules.lisp ssh-bruteforce
177+ clicklisp rules json --load rules.lisp --all # machine-readable JSON
171178```
172179
180+ ` rules json ` dumps each rule as JSON — ` name ` , ` description ` , ` severity ` ,
181+ ` tags ` , the extracted ` {name:Type} ` ` params ` , compact ` sql ` , multiline
182+ ` sql_pretty ` , and the reconstructed ` form ` — for anything downstream that
183+ wants rules as data; it is what feeds the
184+ [ live demos] ( https://cl.clickhouse.com/#demos ) at build time.
185+
173186See [ examples/rules.lisp] ( examples/rules.lisp ) .
174187
175188Exit codes: ` 0 ` success, ` 1 ` bad input (a query that does not compile),
@@ -179,7 +192,7 @@ Exit codes: `0` success, `1` bad input (a query that does not compile),
179192
180193` defquery ` is ` defrule ` minus the detection metadata: named queries for
181194any domain, served by the same ` rules ` commands.
182- [ examples/analytics/] ( examples/analytics/ ) has three libraries built on
195+ [ examples/analytics/] ( examples/analytics/ ) has four libraries built on
183196the playground's example datasets:
184197
185198- [ uk-price-paid.lisp] ( examples/analytics/uk-price-paid.lisp ) — UK
@@ -189,11 +202,21 @@ the playground's example datasets:
189202- [ repo-health.lisp] ( examples/analytics/repo-health.lisp ) — engineering
190203 analytics (code churn, bus factor, comment-to-code ratio) over
191204 ` clickhouse git-import ` tables; the whole library is one macro
192- parameterized by table names, so it runs against * your* repo locally
193- or the playground's pre-imported ClickHouse and Grafana mirrors.
205+ parameterized by table names, so it runs against * your* repo locally,
206+ and [ repo-health-playground.lisp] ( examples/analytics/repo-health-playground.lisp )
207+ re-invokes it against the playground's pre-imported ClickHouse mirror
208+ (load both files; the second registration wins).
194209- [ hackernews.lisp] ( examples/analytics/hackernews.lisp ) — text search,
195210 array lambdas, CTE composition, and a query that calls back into a
196211 clicklisp executable UDF.
212+ - [ github-events.lisp] ( examples/analytics/github-events.lisp ) — a
213+ ` defrule ` threat pack over 11 billion rows of public GitHub events
214+ (` github.events ` ): branch-reset storms, mass ref deletion, tag
215+ retargeting, star storms, bulk collaborator adds, commit-hour
216+ anomalies, each tagged with MITRE ATT&CK technique IDs. Two rules
217+ default to historical windows because the dataset's loader stopped
218+ populating ` push_size ` and tag ` CreateEvent ` s around October 2025 —
219+ see the file header.
197220
198221Rule files are full Common Lisp, and queries are data — so a macro can
199222generate a family of queries with no copy-paste and no templating
@@ -365,6 +388,15 @@ compiling Lisp at `CREATE FUNCTION` time.
365388- ** release** — pushing a tag ` vX.Y.Z ` (which must match ` version.sexp ` )
366389 builds both static binaries and publishes them with SHA256SUMS to a
367390 GitHub release.
391+ - ** pages** — builds the binary with the distro ECL, generates the demo
392+ data (` make site-data ` ), builds the site, and deploys it to
393+ [ cl.clickhouse.com] ( https://cl.clickhouse.com ) — so the demos are
394+ compiled by the same commit they document.
395+
396+ Supply-chain posture: every workflow action is pinned to a commit SHA
397+ (dependabot keeps the pins fresh), workflows run with least-privilege
398+ ` permissions ` , the ECL source tarball is SHA256-verified before it is
399+ built, and the Alpine build image is pinned by digest.
368400
369401## Layout
370402
@@ -377,6 +409,8 @@ src/main.lisp CLI entry point
377409build/build.lisp ECL AOT build (c:build-program; works on static ECL)
378410scripts/build-static.sh static musl build, run inside alpine:3.22
379411scripts/play.sh pipe SQL from stdin to the public ClickHouse playground
412+ scripts/gen-site-data.sh compile the example libraries to JSON for the site demos
380413examples/ detection rules, analytics libraries, UDFs, server config
414+ site/ cl.clickhouse.com — docs plus live demos of the libraries
381415tests/ zero-dependency harness + suite
382416```
0 commit comments