| 1 | """Self-test: proves the anti-slop gate + anti-drift memory actually enforce.""" |
| 2 | import sys |
| 3 | from memory import Memory |
| 4 | |
| 5 | m = Memory() |
| 6 | ok = True |
| 7 | |
| 8 | def check(name, cond): |
| 9 | global ok |
| 10 | print(("PASS " if cond else "FAIL ") + name) |
| 11 | ok = ok and cond |
| 12 | |
| 13 | t = m.upsert_target("github.com/example/loader", "ml-model-loaders", |
| 14 | lang="c", commit="deadbeef", released_at="2026-06-10") |
| 15 | h = m.add_hypothesis(t, "memory-corruption", "src/parse.c", 42, |
| 16 | "gguf_read(fd)", "memcpy(dst,src,n)", "joern") |
| 17 | check("target+hypothesis created", bool(t) and bool(h)) |
| 18 | |
| 19 | refused = False |
| 20 | try: |
| 21 | m.promote_to_finding(h, "RCE via Deserialization", "CRITICAL", "should not exist") |
| 22 | except PermissionError: |
| 23 | refused = True |
| 24 | check("finding REFUSED without execution proof (anti-slop gate)", refused) |
| 25 | |
| 26 | p = m.add_proof(h, "REPLICA_CONFIRMED", "asan", |
| 27 | "/opt/cyclops-v2/oracle/crashes/crash-001.txt", |
| 28 | "ASan heap-buffer-overflow WRITE of size 8 in gguf parse, PC controlled") |
| 29 | f = m.promote_to_finding(h, "RCE via Deserialization", "CRITICAL", |
| 30 | "GGUF parser heap overflow -> load-time RCE", |
| 31 | novel=True, cve_checked=True) |
| 32 | check("finding ALLOWED once proof attached", bool(p) and bool(f)) |
| 33 | |
| 34 | h2 = m.add_hypothesis(t, "command-injection", "src/x.c", 99, "argv", "system()", "joern") |
| 35 | m.add_proof(h2, "DISPROVEN", "replica", "", "guarded: input is shell-escaped before system()") |
| 36 | refused2 = False |
| 37 | try: |
| 38 | m.promote_to_finding(h2, "RCE via Command Injection", "HIGH", "nope") |
| 39 | except PermissionError: |
| 40 | refused2 = True |
| 41 | check("DISPROVEN hypothesis cannot become a finding", refused2) |
| 42 | |
| 43 | m.clear_axis(t, "ml-model-loaders", "pickle-deserialization", "CLEAN", |
| 44 | "no torch.load/pickle path; format is pure binary") |
| 45 | check("axis cleared + recalled", m.is_axis_cleared(t, "pickle-deserialization") == "CLEAN") |
| 46 | check("uncleared axis returns None", m.is_axis_cleared(t, "integer-overflow") is None) |
| 47 | |
| 48 | m.cache_put("k1", "v1") |
| 49 | check("redis cache roundtrip", m.cache_get("k1") == "v1") |
| 50 | m.mark_analysis_done(t, "joern-cpg") |
| 51 | check("analysis dedup (don't re-CPG same commit)", m.analysis_done(t, "joern-cpg")) |
| 52 | m.enqueue("targets", {"repo": "x", "n": 1}) |
| 53 | check("redis queue roundtrip", m.dequeue("targets")["n"] == 1) |
| 54 | |
| 55 | print("\nnode counts:", m.stats()) |
| 56 | print("RESULT:", "ALL PASS" if ok else "FAILURES PRESENT") |
| 57 | sys.exit(0 if ok else 1) |