HumboldtJoker commited on
Commit
7bf9b8d
·
verified ·
1 Parent(s): 9f58be2

Clean up nested duplicate: v2/v2/selftest.py

Browse files
Files changed (1) hide show
  1. v2/v2/selftest.py +0 -201
v2/v2/selftest.py DELETED
@@ -1,201 +0,0 @@
1
- """Rivet v2 self-test — the full pipeline, offline, no model required.
2
-
3
- Covers: config parsing (fallback parser specifically), BDI seeding,
4
- intent classification, plan construction + DAG validation, Pharos
5
- routing (keyword fallback), the tool guard, and two end-to-end runs
6
- through the real DAG executor with a fake model:
7
-
8
- 1. a destructive-SQL draft -> gate BLOCKS
9
- 2. a clean draft -> gate passes, confidence graded
10
-
11
- Run: python selftest.py
12
- Exit: 0 all passed, 1 otherwise.
13
- """
14
-
15
- import json
16
- import sys
17
- import tempfile
18
- from pathlib import Path
19
-
20
- V2_ROOT = Path(__file__).parent
21
- sys.path.insert(0, str(V2_ROOT))
22
-
23
- PASS, FAIL = 0, 0
24
-
25
-
26
- def check(name: str, condition: bool, detail: str = ""):
27
- global PASS, FAIL
28
- if condition:
29
- PASS += 1
30
- print(f" ok {name}")
31
- else:
32
- FAIL += 1
33
- print(f" FAIL {name} {detail}")
34
-
35
-
36
- class FakeModel:
37
- """ModelClient stand-in with scripted replies."""
38
-
39
- def __init__(self, reply_text: str):
40
- self.reply_text = reply_text
41
- self.calls = []
42
-
43
- def generate(self, prompt, system="", knowledge="", max_tokens=1024):
44
- from engine.model_client import ModelReply
45
- self.calls.append({"prompt": prompt, "system": system,
46
- "knowledge": knowledge})
47
- return ModelReply(
48
- text=self.reply_text, ok=True, backend="fake",
49
- knowledge_injected="system_prompt" if knowledge else "none",
50
- )
51
-
52
-
53
- def main() -> int:
54
- print("== config ==")
55
- from engine.config import _parse_subset, load_config
56
- cfg_text = (V2_ROOT / "kintsugi_config.yaml").read_text()
57
- cfg_fallback = _parse_subset(cfg_text)
58
- check("fallback parser: model section",
59
- cfg_fallback.get("model", {}).get("name") == "qwen2.5-coder:32b",
60
- str(cfg_fallback.get("model")))
61
- check("fallback parser: constraints list",
62
- len(cfg_fallback.get("beliefs", {}).get("constraints", [])) == 3)
63
- check("fallback parser: nested scalar types",
64
- cfg_fallback["session"]["ttl_seconds"] == 3600
65
- and cfg_fallback["tools"]["repo_write_enabled"] is False)
66
- cfg = load_config(V2_ROOT / "kintsugi_config.yaml")
67
- check("load_config parses", isinstance(cfg, dict) and "org" in cfg)
68
-
69
- print("== kintsugi core ==")
70
- from kintsugi_core import KINTSUGI_SOURCE, BDIStore
71
- print(f" (kintsugi source: {KINTSUGI_SOURCE})")
72
- check("kintsugi imports resolve", True)
73
-
74
- print("== BDI seeding ==")
75
- from engine.beliefs import seed_bdi
76
- context_dir = (V2_ROOT / ".." / "context").resolve()
77
- bdi = BDIStore("selftest_org")
78
- seed_bdi(bdi, cfg, context_dir)
79
- beliefs = bdi.list_beliefs()
80
- shared = bdi.get_belief("belief_constraint_shared_db")
81
- check("beliefs seeded", len(beliefs) >= 15, f"got {len(beliefs)}")
82
- check("shared-db constraint at confidence 1.0",
83
- shared is not None and shared.confidence == 1.0)
84
- check("audit findings became beliefs",
85
- bdi.get_belief("belief_audit_c2") is not None)
86
- check("desires seeded", len(bdi.list_desires()) == 3)
87
-
88
- print("== tool guard ==")
89
- from tools.guard import check_command
90
- check("guard blocks unlisted binary",
91
- check_command(["curl", "http://x"]) != "")
92
- check("guard blocks suspicious pattern",
93
- check_command(["git", "log", ";rm -rf /"]) != "")
94
- check("guard allows clean git", check_command(["git", "log"]) == "")
95
-
96
- print("== migration classification ==")
97
- from skills.migration_safety import classify_sql, extract_sql
98
- destructive = classify_sql("ALTER TABLE students DROP COLUMN score;")
99
- additive = classify_sql(
100
- "ALTER TABLE students ADD COLUMN score int DEFAULT 0;")
101
- check("DROP COLUMN classified destructive", destructive["destructive"])
102
- check("ADD COLUMN classified additive",
103
- additive["additive"] and not additive["destructive"])
104
- prose = extract_sql("You should never drop a table in prod.")
105
- fenced = extract_sql("```sql\nDROP TABLE users;\n```")
106
- check("prose SQL not extracted", prose == [])
107
- check("fenced SQL extracted", len(fenced) == 1)
108
-
109
- print("== intent classification ==")
110
- from engine.planner import classify_intent
111
- check("migration intent",
112
- classify_intent("Add a migration for a new lessons column") == "migration")
113
- check("auth intent",
114
- classify_intent("Why does verifyToken reject the Bearer token?") == "auth")
115
- check("question intent",
116
- classify_intent("What does the campus use for state?") == "question")
117
-
118
- print("== pharos routing (keyword fallback) ==")
119
- with tempfile.TemporaryDirectory() as tmp:
120
- import subprocess
121
- result = subprocess.run(
122
- [sys.executable, str(V2_ROOT / "pharos" / "build_campus_pack.py"),
123
- "--context-dir", str(context_dir), "--out", tmp],
124
- capture_output=True, text=True,
125
- )
126
- check("campus pack builds", result.returncode == 0, result.stderr[:300])
127
- from pharos.pack_loader import PackLibrary, PharosRouter
128
- library = PackLibrary(tmp)
129
- check("campus pack loads",
130
- len(library.packs) == 1
131
- and len(library.packs[0].triples) >= 40,
132
- f"packs={[p.name for p in library.packs]}")
133
- router = PharosRouter(library)
134
- # force keyword path even if sentence-transformers is installed —
135
- # the fallback must work on a bare box
136
- router._st_model = None
137
- routed = router.route(
138
- "How do I write a safe migration for the shared database?")
139
- check("keyword routing finds campus pack",
140
- "campus_architecture" in routed.pack_names,
141
- routed.explanation)
142
-
143
- print("== end-to-end: destructive draft is BLOCKED ==")
144
- import rivet as rivet_mod
145
- bad_model = FakeModel(
146
- "Just drop the old column:\n```sql\nALTER TABLE students DROP "
147
- "COLUMN legacy_score;\n```\nThat cleans it up."
148
- )
149
- agent = rivet_mod.RivetAgent(model_client=bad_model)
150
- out = agent.ask("Write a migration to remove legacy_score from students",
151
- user="selftest")
152
- check("plan used migration intent", out.get("intent") == "migration",
153
- json.dumps(out)[:300])
154
- check("gate blocked destructive SQL", out.get("gate_passed") is False,
155
- json.dumps(out.get("flags", []))[:300])
156
- check("blocked answer withholds the SQL",
157
- "DROP COLUMN" not in out.get("response", "").upper()
158
- or "BLOCKED" in out.get("response", ""))
159
- check("shared-db belief consulted",
160
- "belief_constraint_shared_db" in out.get("beliefs_consulted", []))
161
-
162
- print("== end-to-end: clean draft passes ==")
163
- good_model = FakeModel(
164
- "Add the column additively:\n```sql\nALTER TABLE students ADD "
165
- "COLUMN score integer DEFAULT 0;\n```\nWhat it changes: one new "
166
- "nullable-with-default column. What could break: nothing — old "
167
- "code ignores it. Tests: extend the students model test."
168
- )
169
- agent2 = rivet_mod.RivetAgent(model_client=good_model)
170
- out2 = agent2.ask("Add a migration for a students score column",
171
- user="selftest2")
172
- check("gate passed clean answer", out2.get("gate_passed") is True,
173
- json.dumps(out2.get("flags", []))[:400])
174
- check("confidence graded (MEDIUM without source reads)",
175
- out2.get("confidence") == "MEDIUM", out2.get("confidence"))
176
- check("gate annotations attached",
177
- "Discipline Gate" in out2.get("response", "")
178
- or "Confidence" in out2.get("response", ""))
179
- check("synthesis saw beliefs in prompt",
180
- "ORGANIZATIONAL BELIEFS" in good_model.calls[0]["prompt"]
181
- and "share one PostgreSQL" in good_model.calls[0]["prompt"])
182
-
183
- print("== end-to-end: auth question flags review ==")
184
- auth_model = FakeModel(
185
- "The middleware order is verifyToken then rejectIfIneligible. "
186
- "To add a route guard use requireAdmin."
187
- )
188
- agent3 = rivet_mod.RivetAgent(model_client=auth_model)
189
- out3 = agent3.ask("How should I change the JWT auth middleware to add "
190
- "a new admin route?", user="selftest3")
191
- check("auth intent planned", out3.get("intent") == "auth", out3.get("intent"))
192
- check("security review required",
193
- "security" in out3.get("requires_review", []),
194
- json.dumps(out3)[:300])
195
-
196
- print(f"\n{PASS} passed, {FAIL} failed")
197
- return 0 if FAIL == 0 else 1
198
-
199
-
200
- if __name__ == "__main__":
201
- sys.exit(main())