mod: Ext 12 — temporal burst detection, 292/292
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Reports gain an :at tick (deterministic, supplied). mod/decide-temporal counts reports about a subject within [now-window, now], asserts burst_count/2, and a (:burst-at-least K) rule fires only on a real burst. 3 reports at 10/11/12 → hide; 3 at 1/2/12 (window 5) → keep, while the plain count rule escalates both. Fifth report field threaded through rebuild helpers, non-breaking. +15 tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
156
lib/mod/tests/temporal.sx
Normal file
156
lib/mod/tests/temporal.sx
Normal file
@@ -0,0 +1,156 @@
|
||||
;; lib/mod/tests/temporal.sx — Ext 12: burst detection over a time window.
|
||||
|
||||
(define mod-tm-count 0)
|
||||
(define mod-tm-pass 0)
|
||||
(define mod-tm-fail 0)
|
||||
(define mod-tm-failures (list))
|
||||
|
||||
(define
|
||||
mod-tm-test!
|
||||
(fn
|
||||
(name got expected)
|
||||
(begin
|
||||
(set! mod-tm-count (+ mod-tm-count 1))
|
||||
(if
|
||||
(= got expected)
|
||||
(set! mod-tm-pass (+ mod-tm-pass 1))
|
||||
(begin
|
||||
(set! mod-tm-fail (+ mod-tm-fail 1))
|
||||
(append!
|
||||
mod-tm-failures
|
||||
(str name "\n expected: " expected "\n got: " got)))))))
|
||||
|
||||
(define
|
||||
mod-tm-at
|
||||
(fn (id about t) (mod/with-at (mod/mk-report id "u" about "off-topic") t)))
|
||||
|
||||
(define
|
||||
mod-tm-rules
|
||||
(list
|
||||
(mod/mk-rule "burst-hide" :hide (list (list :burst-at-least 3)))
|
||||
(mod/mk-rule "default-keep" :keep (list))))
|
||||
|
||||
;; ── window-count helper ──
|
||||
|
||||
(define
|
||||
mod-tm-burst
|
||||
(list
|
||||
(mod-tm-at "r1" "bob" 10)
|
||||
(mod-tm-at "r2" "bob" 11)
|
||||
(mod-tm-at "r3" "bob" 12)))
|
||||
(define
|
||||
mod-tm-slow
|
||||
(list
|
||||
(mod-tm-at "r1" "bob" 1)
|
||||
(mod-tm-at "r2" "bob" 2)
|
||||
(mod-tm-at "r3" "bob" 12)))
|
||||
|
||||
(mod-tm-test!
|
||||
"window-count: all 3 within window"
|
||||
(mod/window-count "bob" mod-tm-burst 12 5)
|
||||
3)
|
||||
(mod-tm-test!
|
||||
"window-count: only 1 within window"
|
||||
(mod/window-count "bob" mod-tm-slow 12 5)
|
||||
1)
|
||||
(mod-tm-test!
|
||||
"window-count: subject filter"
|
||||
(mod/window-count "eve" mod-tm-burst 12 5)
|
||||
0)
|
||||
|
||||
;; ── burst fires; slow accumulation does not ──
|
||||
|
||||
(mod-tm-test!
|
||||
"burst (3 in window) → hide"
|
||||
(get
|
||||
(mod/decide-temporal
|
||||
(first mod-tm-burst)
|
||||
mod-tm-burst
|
||||
mod-tm-rules
|
||||
12
|
||||
5)
|
||||
:action)
|
||||
"hide")
|
||||
(mod-tm-test!
|
||||
"slow accumulation (1 in window) → keep"
|
||||
(get
|
||||
(mod/decide-temporal
|
||||
(first mod-tm-slow)
|
||||
mod-tm-slow
|
||||
mod-tm-rules
|
||||
12
|
||||
5)
|
||||
:action)
|
||||
"keep")
|
||||
|
||||
;; ── contrast: the plain count rule fires on BOTH (3 total reports) ──
|
||||
(mod-tm-test!
|
||||
"count rule fires on slow case (distinct from burst)"
|
||||
(get
|
||||
(mod/decide-report (first mod-tm-slow) mod-tm-slow mod/default-rules)
|
||||
:action)
|
||||
"escalate")
|
||||
|
||||
;; ── decision shape ──
|
||||
|
||||
(define
|
||||
mod-tm-d
|
||||
(mod/decide-temporal
|
||||
(first mod-tm-burst)
|
||||
mod-tm-burst
|
||||
mod-tm-rules
|
||||
12
|
||||
5))
|
||||
(mod-tm-test! "burst decision rule" (get mod-tm-d :rule) "burst-hide")
|
||||
(mod-tm-test!
|
||||
"burst decision tagged strategy"
|
||||
(get mod-tm-d :strategy)
|
||||
"temporal")
|
||||
(mod-tm-test!
|
||||
"burst recorded in proof"
|
||||
(get (get mod-tm-d :proof) :burst)
|
||||
3)
|
||||
(mod-tm-test!
|
||||
"burst proof goal solved"
|
||||
(get (first (get (get mod-tm-d :proof) :goals)) :solved)
|
||||
true)
|
||||
|
||||
;; ── window boundary is inclusive ──
|
||||
|
||||
(define
|
||||
mod-tm-edge
|
||||
(list
|
||||
(mod-tm-at "r1" "bob" 7)
|
||||
(mod-tm-at "r2" "bob" 8)
|
||||
(mod-tm-at "r3" "bob" 9)))
|
||||
(mod-tm-test!
|
||||
"window boundary inclusive (now-window = at)"
|
||||
(mod/window-count "bob" mod-tm-edge 12 5)
|
||||
3)
|
||||
|
||||
;; ── schema :at round-trips and survives evidence attach ──
|
||||
|
||||
(mod-tm-test!
|
||||
"report-at reads timestamp"
|
||||
(mod/report-at (mod-tm-at "r1" "bob" 42))
|
||||
42)
|
||||
(mod-tm-test!
|
||||
"default report-at is 0"
|
||||
(mod/report-at (mod/mk-report "r1" "a" "b" "x"))
|
||||
0)
|
||||
(mod-tm-test!
|
||||
"attach-evidence preserves :at"
|
||||
(mod/report-at
|
||||
(mod/attach-evidence
|
||||
(mod-tm-at "r1" "bob" 42)
|
||||
(mod/mk-evidence "k" "v")))
|
||||
42)
|
||||
|
||||
;; ── cond->goal :burst-at-least ──
|
||||
|
||||
(mod-tm-test!
|
||||
"cond->goal :burst-at-least"
|
||||
(mod/cond->goal (list :burst-at-least 3) "Id")
|
||||
"report(Id, _, Sb), burst_count(Sb, Nb), Nb >= 3")
|
||||
|
||||
(define mod-temporal-tests-run! (fn () {:failures mod-tm-failures :total mod-tm-count :passed mod-tm-pass :failed mod-tm-fail}))
|
||||
Reference in New Issue
Block a user