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>
157 lines
3.5 KiB
Plaintext
157 lines
3.5 KiB
Plaintext
;; 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}))
|