chiasmus 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +124 -0
- package/dist/formalize/engine.d.ts +47 -0
- package/dist/formalize/engine.d.ts.map +1 -0
- package/dist/formalize/engine.js +189 -0
- package/dist/formalize/engine.js.map +1 -0
- package/dist/formalize/validate.d.ts +15 -0
- package/dist/formalize/validate.d.ts.map +1 -0
- package/dist/formalize/validate.js +124 -0
- package/dist/formalize/validate.js.map +1 -0
- package/dist/llm/anthropic.d.ts +27 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +86 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/mock.d.ts +21 -0
- package/dist/llm/mock.d.ts.map +1 -0
- package/dist/llm/mock.js +29 -0
- package/dist/llm/mock.js.map +1 -0
- package/dist/llm/openai-compatible.d.ts +20 -0
- package/dist/llm/openai-compatible.d.ts.map +1 -0
- package/dist/llm/openai-compatible.js +46 -0
- package/dist/llm/openai-compatible.js.map +1 -0
- package/dist/llm/types.d.ts +11 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +2 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/mcp-server.d.ts +12 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +446 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/skills/bm25.d.ts +22 -0
- package/dist/skills/bm25.d.ts.map +1 -0
- package/dist/skills/bm25.js +71 -0
- package/dist/skills/bm25.js.map +1 -0
- package/dist/skills/learner.d.ts +21 -0
- package/dist/skills/learner.d.ts.map +1 -0
- package/dist/skills/learner.js +123 -0
- package/dist/skills/learner.js.map +1 -0
- package/dist/skills/library.d.ts +36 -0
- package/dist/skills/library.d.ts.map +1 -0
- package/dist/skills/library.js +173 -0
- package/dist/skills/library.js.map +1 -0
- package/dist/skills/starters.d.ts +3 -0
- package/dist/skills/starters.d.ts.map +1 -0
- package/dist/skills/starters.js +381 -0
- package/dist/skills/starters.js.map +1 -0
- package/dist/skills/types.d.ts +54 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/solvers/correction-loop.d.ts +34 -0
- package/dist/solvers/correction-loop.d.ts.map +1 -0
- package/dist/solvers/correction-loop.js +52 -0
- package/dist/solvers/correction-loop.js.map +1 -0
- package/dist/solvers/prolog-solver.d.ts +3 -0
- package/dist/solvers/prolog-solver.d.ts.map +1 -0
- package/dist/solvers/prolog-solver.js +93 -0
- package/dist/solvers/prolog-solver.js.map +1 -0
- package/dist/solvers/session.d.ts +11 -0
- package/dist/solvers/session.d.ts.map +1 -0
- package/dist/solvers/session.js +25 -0
- package/dist/solvers/session.js.map +1 -0
- package/dist/solvers/types.d.ts +44 -0
- package/dist/solvers/types.d.ts.map +1 -0
- package/dist/solvers/types.js +2 -0
- package/dist/solvers/types.js.map +1 -0
- package/dist/solvers/z3-solver.d.ts +3 -0
- package/dist/solvers/z3-solver.d.ts.map +1 -0
- package/dist/solvers/z3-solver.js +81 -0
- package/dist/solvers/z3-solver.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
export const STARTER_TEMPLATES = [
|
|
2
|
+
// ─── Z3 Templates ────────────────────────────────────────
|
|
3
|
+
{
|
|
4
|
+
name: "policy-contradiction",
|
|
5
|
+
domain: "authorization",
|
|
6
|
+
solver: "z3",
|
|
7
|
+
signature: "Check if access control rules can ever produce contradictory allow/deny decisions for the same request",
|
|
8
|
+
skeleton: `
|
|
9
|
+
; Principals, resources, and actions as enumerated types
|
|
10
|
+
{{SLOT:type_declarations}}
|
|
11
|
+
|
|
12
|
+
; Decision variables
|
|
13
|
+
(declare-const principal {{SLOT:principal_type}})
|
|
14
|
+
(declare-const resource {{SLOT:resource_type}})
|
|
15
|
+
(declare-const action {{SLOT:action_type}})
|
|
16
|
+
(declare-const allowed Bool)
|
|
17
|
+
(declare-const denied Bool)
|
|
18
|
+
|
|
19
|
+
; Policy rules
|
|
20
|
+
{{SLOT:policy_rules}}
|
|
21
|
+
|
|
22
|
+
; Check: can both allowed and denied be true simultaneously?
|
|
23
|
+
(assert allowed)
|
|
24
|
+
(assert denied)`,
|
|
25
|
+
slots: [
|
|
26
|
+
{
|
|
27
|
+
name: "type_declarations",
|
|
28
|
+
description: "SMT-LIB declare-datatypes for principals, resources, actions",
|
|
29
|
+
format: "(declare-datatypes ((Principal 0)) (((alice) (bob) ...)))",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "principal_type",
|
|
33
|
+
description: "The type name for principals",
|
|
34
|
+
format: "Principal",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "resource_type",
|
|
38
|
+
description: "The type name for resources",
|
|
39
|
+
format: "Resource",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "action_type",
|
|
43
|
+
description: "The type name for actions",
|
|
44
|
+
format: "Action",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "policy_rules",
|
|
48
|
+
description: "Implications mapping (principal, resource, action) to allowed/denied",
|
|
49
|
+
format: "(assert (=> (and (= principal alice) (= action read)) allowed))",
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
normalizations: [
|
|
53
|
+
{
|
|
54
|
+
source: "AWS IAM JSON",
|
|
55
|
+
transform: "Map each Statement's Effect/Principal/Action/Resource to allow/deny implications",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
source: "Kubernetes RBAC",
|
|
59
|
+
transform: "Expand rules[].{verbs, resources, apiGroups} into action/resource allow implications",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
source: "natural language",
|
|
63
|
+
transform: "Extract entities, classify as principal/resource/action, map to implications",
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "policy-reachability",
|
|
69
|
+
domain: "authorization",
|
|
70
|
+
solver: "z3",
|
|
71
|
+
signature: "Check if a specific principal can ever access a specific resource through any combination of roles or rules",
|
|
72
|
+
skeleton: `
|
|
73
|
+
{{SLOT:type_declarations}}
|
|
74
|
+
|
|
75
|
+
(declare-const principal {{SLOT:principal_type}})
|
|
76
|
+
(declare-const resource {{SLOT:resource_type}})
|
|
77
|
+
(declare-const action {{SLOT:action_type}})
|
|
78
|
+
(declare-const can_access Bool)
|
|
79
|
+
|
|
80
|
+
; Role assignments and permission rules
|
|
81
|
+
{{SLOT:role_rules}}
|
|
82
|
+
|
|
83
|
+
; Target: can this specific principal access this specific resource?
|
|
84
|
+
(assert (= principal {{SLOT:target_principal}}))
|
|
85
|
+
(assert (= resource {{SLOT:target_resource}}))
|
|
86
|
+
(assert can_access)`,
|
|
87
|
+
slots: [
|
|
88
|
+
{
|
|
89
|
+
name: "type_declarations",
|
|
90
|
+
description: "SMT-LIB declare-datatypes for principals, resources, actions",
|
|
91
|
+
format: "(declare-datatypes ...)",
|
|
92
|
+
},
|
|
93
|
+
{ name: "principal_type", description: "Type name for principals", format: "Principal" },
|
|
94
|
+
{ name: "resource_type", description: "Type name for resources", format: "Resource" },
|
|
95
|
+
{ name: "action_type", description: "Type name for actions", format: "Action" },
|
|
96
|
+
{
|
|
97
|
+
name: "role_rules",
|
|
98
|
+
description: "Rules that derive can_access from roles and permissions",
|
|
99
|
+
format: "(assert (=> (and (= principal alice) ...) can_access))",
|
|
100
|
+
},
|
|
101
|
+
{ name: "target_principal", description: "The principal to check", format: "alice" },
|
|
102
|
+
{ name: "target_resource", description: "The resource to check", format: "secret_doc" },
|
|
103
|
+
],
|
|
104
|
+
normalizations: [
|
|
105
|
+
{
|
|
106
|
+
source: "Django permissions",
|
|
107
|
+
transform: "Extract user/group assignments and permission checks into role rules",
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
source: "natural language",
|
|
111
|
+
transform: "Identify the target principal and resource, extract role hierarchy",
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "config-equivalence",
|
|
117
|
+
domain: "configuration",
|
|
118
|
+
solver: "z3",
|
|
119
|
+
signature: "Check if two configurations are functionally equivalent or find an input where they differ",
|
|
120
|
+
skeleton: `
|
|
121
|
+
; Input variables representing all possible inputs
|
|
122
|
+
{{SLOT:input_declarations}}
|
|
123
|
+
|
|
124
|
+
; Output of config A
|
|
125
|
+
{{SLOT:config_a_logic}}
|
|
126
|
+
|
|
127
|
+
; Output of config B
|
|
128
|
+
{{SLOT:config_b_logic}}
|
|
129
|
+
|
|
130
|
+
; Check: is there any input where the two configs produce different outputs?
|
|
131
|
+
(assert (not (= {{SLOT:output_a}} {{SLOT:output_b}})))`,
|
|
132
|
+
slots: [
|
|
133
|
+
{
|
|
134
|
+
name: "input_declarations",
|
|
135
|
+
description: "Declare input variables covering the input space",
|
|
136
|
+
format: "(declare-const port Int) (declare-const src_ip Int)",
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "config_a_logic",
|
|
140
|
+
description: "Assertions encoding the first configuration's behavior",
|
|
141
|
+
format: "(declare-const result_a Bool) (assert (=> (> port 80) result_a))",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: "config_b_logic",
|
|
145
|
+
description: "Assertions encoding the second configuration's behavior",
|
|
146
|
+
format: "(declare-const result_b Bool) (assert (=> (>= port 80) result_b))",
|
|
147
|
+
},
|
|
148
|
+
{ name: "output_a", description: "Output variable from config A", format: "result_a" },
|
|
149
|
+
{ name: "output_b", description: "Output variable from config B", format: "result_b" },
|
|
150
|
+
],
|
|
151
|
+
normalizations: [
|
|
152
|
+
{
|
|
153
|
+
source: "firewall rules",
|
|
154
|
+
transform: "Encode each rule set as boolean logic over port/protocol/address variables",
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
source: "Kubernetes NetworkPolicy",
|
|
158
|
+
transform: "Map ingress/egress rules to boolean expressions over pod labels and ports",
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: "constraint-satisfaction",
|
|
164
|
+
domain: "dependency",
|
|
165
|
+
solver: "z3",
|
|
166
|
+
signature: "Find a valid assignment satisfying version constraints, dependency requirements, and compatibility rules",
|
|
167
|
+
skeleton: `
|
|
168
|
+
; Version variables for each package
|
|
169
|
+
{{SLOT:version_declarations}}
|
|
170
|
+
|
|
171
|
+
; Version range constraints (available versions)
|
|
172
|
+
{{SLOT:range_constraints}}
|
|
173
|
+
|
|
174
|
+
; Dependency requirements (A requires B >= version)
|
|
175
|
+
{{SLOT:dependency_rules}}
|
|
176
|
+
|
|
177
|
+
; Incompatibility constraints
|
|
178
|
+
{{SLOT:incompatibility_rules}}`,
|
|
179
|
+
slots: [
|
|
180
|
+
{
|
|
181
|
+
name: "version_declarations",
|
|
182
|
+
description: "Declare an Int variable for each package version",
|
|
183
|
+
format: "(declare-const pkg_a Int) (declare-const pkg_b Int)",
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: "range_constraints",
|
|
187
|
+
description: "Constrain each package to its available version range",
|
|
188
|
+
format: "(assert (and (>= pkg_a 1) (<= pkg_a 3)))",
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: "dependency_rules",
|
|
192
|
+
description: "Conditional version requirements between packages",
|
|
193
|
+
format: "(assert (=> (>= pkg_a 2) (>= pkg_b 3)))",
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: "incompatibility_rules",
|
|
197
|
+
description: "Pairs of versions that cannot coexist",
|
|
198
|
+
format: "(assert (not (and (= pkg_a 2) (= pkg_b 1))))",
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
normalizations: [
|
|
202
|
+
{
|
|
203
|
+
source: "package.json",
|
|
204
|
+
transform: "Parse semver ranges into integer constraints, map peer/optional deps to conditional rules",
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
source: "requirements.txt",
|
|
208
|
+
transform: "Parse version specifiers (>=, ==, !=) into SMT constraints",
|
|
209
|
+
},
|
|
210
|
+
],
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: "schema-consistency",
|
|
214
|
+
domain: "validation",
|
|
215
|
+
solver: "z3",
|
|
216
|
+
signature: "Check if data validation rules are contradictory, redundant, or have gaps — find inputs that pass some rules but fail others",
|
|
217
|
+
skeleton: `
|
|
218
|
+
; Input field variables
|
|
219
|
+
{{SLOT:field_declarations}}
|
|
220
|
+
|
|
221
|
+
; Validation rule set A
|
|
222
|
+
{{SLOT:rule_set_a}}
|
|
223
|
+
|
|
224
|
+
; Validation rule set B
|
|
225
|
+
{{SLOT:rule_set_b}}
|
|
226
|
+
|
|
227
|
+
; Check: is there an input that passes A but fails B (or vice versa)?
|
|
228
|
+
(assert (and {{SLOT:passes_a}} (not {{SLOT:passes_b}})))`,
|
|
229
|
+
slots: [
|
|
230
|
+
{
|
|
231
|
+
name: "field_declarations",
|
|
232
|
+
description: "Declare variables for each input field",
|
|
233
|
+
format: "(declare-const age Int) (declare-const name_len Int)",
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: "rule_set_a",
|
|
237
|
+
description: "Assertions for the first set of validation rules",
|
|
238
|
+
format: "(declare-const valid_a Bool) (assert (=> (and (>= age 18) ...) valid_a))",
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: "rule_set_b",
|
|
242
|
+
description: "Assertions for the second set of validation rules",
|
|
243
|
+
format: "(declare-const valid_b Bool) (assert (=> (and (> age 17) ...) valid_b))",
|
|
244
|
+
},
|
|
245
|
+
{ name: "passes_a", description: "Variable indicating input passes rule set A", format: "valid_a" },
|
|
246
|
+
{ name: "passes_b", description: "Variable indicating input passes rule set B", format: "valid_b" },
|
|
247
|
+
],
|
|
248
|
+
normalizations: [
|
|
249
|
+
{
|
|
250
|
+
source: "JSON Schema",
|
|
251
|
+
transform: "Map minimum/maximum/pattern/required to integer/boolean constraints",
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
source: "Zod schema",
|
|
255
|
+
transform: "Extract .min()/.max()/.refine() chains into SMT assertions",
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
},
|
|
259
|
+
// ─── Prolog Templates ────────────────────────────────────
|
|
260
|
+
{
|
|
261
|
+
name: "rule-inference",
|
|
262
|
+
domain: "rules",
|
|
263
|
+
solver: "prolog",
|
|
264
|
+
signature: "Given a set of facts and rules, derive what conclusions follow — determine eligibility, compliance, or derived properties",
|
|
265
|
+
skeleton: `
|
|
266
|
+
% Facts about entities
|
|
267
|
+
{{SLOT:facts}}
|
|
268
|
+
|
|
269
|
+
% Rules that derive new conclusions
|
|
270
|
+
{{SLOT:rules}}`,
|
|
271
|
+
slots: [
|
|
272
|
+
{
|
|
273
|
+
name: "facts",
|
|
274
|
+
description: "Ground facts about the domain",
|
|
275
|
+
format: "role(alice, admin). department(alice, engineering).",
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
name: "rules",
|
|
279
|
+
description: "Prolog rules that derive conclusions from facts",
|
|
280
|
+
format: "can_approve(X) :- role(X, admin), department(X, Dept).",
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
normalizations: [
|
|
284
|
+
{
|
|
285
|
+
source: "business rules document",
|
|
286
|
+
transform: "Extract if-then rules and entity facts into Prolog clauses",
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
source: "natural language",
|
|
290
|
+
transform: "Identify entities, properties, and conditional relationships",
|
|
291
|
+
},
|
|
292
|
+
],
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: "graph-reachability",
|
|
296
|
+
domain: "analysis",
|
|
297
|
+
solver: "prolog",
|
|
298
|
+
signature: "Check if node A can reach node B through any path in a directed graph — data flow, dependency chains, call graphs",
|
|
299
|
+
skeleton: `
|
|
300
|
+
% Direct edges in the graph
|
|
301
|
+
{{SLOT:edges}}
|
|
302
|
+
|
|
303
|
+
% Transitive reachability
|
|
304
|
+
reaches(A, B) :- edge(A, B).
|
|
305
|
+
reaches(A, B) :- edge(A, Mid), reaches(Mid, B).`,
|
|
306
|
+
slots: [
|
|
307
|
+
{
|
|
308
|
+
name: "edges",
|
|
309
|
+
description: "Direct edges as edge(from, to) facts",
|
|
310
|
+
format: "edge(user_input, handler). edge(handler, database).",
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
normalizations: [
|
|
314
|
+
{
|
|
315
|
+
source: "import graph",
|
|
316
|
+
transform: "Map import statements to edge(importer, imported) facts",
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
source: "data flow",
|
|
320
|
+
transform: "Map data transformations to edge(source, sink) facts",
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
source: "call graph",
|
|
324
|
+
transform: "Map function calls to edge(caller, callee) facts",
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
name: "permission-derivation",
|
|
330
|
+
domain: "authorization",
|
|
331
|
+
solver: "prolog",
|
|
332
|
+
signature: "Given a role hierarchy and permission assignments, derive what actions a user can perform on which resources",
|
|
333
|
+
skeleton: `
|
|
334
|
+
% Role assignments
|
|
335
|
+
{{SLOT:role_assignments}}
|
|
336
|
+
|
|
337
|
+
% Role hierarchy (parent inherits child permissions)
|
|
338
|
+
{{SLOT:role_hierarchy}}
|
|
339
|
+
|
|
340
|
+
% Permission assignments to roles
|
|
341
|
+
{{SLOT:permissions}}
|
|
342
|
+
|
|
343
|
+
% Inheritance logic
|
|
344
|
+
has_role(User, Role) :- role(User, Role).
|
|
345
|
+
has_role(User, Role) :- role(User, R), inherits(R, Role).
|
|
346
|
+
has_role(User, Role) :- role(User, R), inherits(R, Mid), has_role_via(Mid, Role).
|
|
347
|
+
has_role_via(Role, Role).
|
|
348
|
+
has_role_via(Start, End) :- inherits(Start, Mid), has_role_via(Mid, End).
|
|
349
|
+
|
|
350
|
+
% Permission check
|
|
351
|
+
can(User, Action, Resource) :- has_role(User, Role), permission(Role, Action, Resource).`,
|
|
352
|
+
slots: [
|
|
353
|
+
{
|
|
354
|
+
name: "role_assignments",
|
|
355
|
+
description: "Which users have which roles",
|
|
356
|
+
format: "role(alice, admin). role(bob, editor).",
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
name: "role_hierarchy",
|
|
360
|
+
description: "Role inheritance relationships",
|
|
361
|
+
format: "inherits(admin, editor). inherits(editor, viewer).",
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
name: "permissions",
|
|
365
|
+
description: "What each role can do",
|
|
366
|
+
format: "permission(viewer, read, docs). permission(editor, write, docs).",
|
|
367
|
+
},
|
|
368
|
+
],
|
|
369
|
+
normalizations: [
|
|
370
|
+
{
|
|
371
|
+
source: "Django groups/permissions",
|
|
372
|
+
transform: "Map Group→Permission assignments to role/permission facts, group hierarchy to inherits",
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
source: "Kubernetes RBAC",
|
|
376
|
+
transform: "Map ClusterRole/Role bindings to role facts, aggregate rules to permission facts",
|
|
377
|
+
},
|
|
378
|
+
],
|
|
379
|
+
},
|
|
380
|
+
];
|
|
381
|
+
//# sourceMappingURL=starters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"starters.js","sourceRoot":"","sources":["../../src/skills/starters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { SolverType } from "../solvers/types.js";
|
|
2
|
+
/** A slot in a template skeleton that must be filled */
|
|
3
|
+
export interface SlotDef {
|
|
4
|
+
/** Slot name, matches {{SLOT:name}} in skeleton */
|
|
5
|
+
name: string;
|
|
6
|
+
/** What this slot expects */
|
|
7
|
+
description: string;
|
|
8
|
+
/** Expected format/type hint */
|
|
9
|
+
format: string;
|
|
10
|
+
}
|
|
11
|
+
/** A normalization recipe for mapping domain inputs to slot values */
|
|
12
|
+
export interface Normalization {
|
|
13
|
+
/** What kind of input this handles */
|
|
14
|
+
source: string;
|
|
15
|
+
/** How to transform it */
|
|
16
|
+
transform: string;
|
|
17
|
+
}
|
|
18
|
+
/** A reusable formalization template */
|
|
19
|
+
export interface SkillTemplate {
|
|
20
|
+
/** Unique identifier */
|
|
21
|
+
name: string;
|
|
22
|
+
/** Problem domain (authorization, configuration, dependency, validation, rules, analysis) */
|
|
23
|
+
domain: string;
|
|
24
|
+
/** Which solver this targets */
|
|
25
|
+
solver: SolverType;
|
|
26
|
+
/** Natural language description for search/matching */
|
|
27
|
+
signature: string;
|
|
28
|
+
/** The formal spec with {{SLOT:name}} markers */
|
|
29
|
+
skeleton: string;
|
|
30
|
+
/** Slots that need to be filled */
|
|
31
|
+
slots: SlotDef[];
|
|
32
|
+
/** Known normalization recipes */
|
|
33
|
+
normalizations: Normalization[];
|
|
34
|
+
}
|
|
35
|
+
/** Runtime metadata tracked per template */
|
|
36
|
+
export interface SkillMetadata {
|
|
37
|
+
name: string;
|
|
38
|
+
reuseCount: number;
|
|
39
|
+
successCount: number;
|
|
40
|
+
lastUsed: string | null;
|
|
41
|
+
promoted: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** Template with its metadata attached */
|
|
44
|
+
export interface SkillWithMetadata {
|
|
45
|
+
template: SkillTemplate;
|
|
46
|
+
metadata: SkillMetadata;
|
|
47
|
+
}
|
|
48
|
+
/** Search result from the skill library */
|
|
49
|
+
export interface SkillSearchResult {
|
|
50
|
+
template: SkillTemplate;
|
|
51
|
+
metadata: SkillMetadata;
|
|
52
|
+
score: number;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/skills/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,wDAAwD;AACxD,MAAM,WAAW,OAAO;IACtB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,6FAA6F;IAC7F,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,MAAM,EAAE,UAAU,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,kCAAkC;IAClC,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC;AAED,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,0CAA0C;AAC1C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,aAAa,CAAC;CACzB;AAED,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,aAAa,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/skills/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { SolverInput, SolverResult } from "./types.js";
|
|
2
|
+
/** A function that takes a broken spec + error and returns a patched spec */
|
|
3
|
+
export type SpecFixer = (attempt: SolverInput, error: string, round: number) => Promise<SolverInput | null>;
|
|
4
|
+
/** Record of a single correction attempt */
|
|
5
|
+
export interface CorrectionAttempt {
|
|
6
|
+
round: number;
|
|
7
|
+
input: SolverInput;
|
|
8
|
+
result: SolverResult;
|
|
9
|
+
}
|
|
10
|
+
/** Result of the full correction loop */
|
|
11
|
+
export interface CorrectionResult {
|
|
12
|
+
/** Final solver result (may be success or the last error) */
|
|
13
|
+
result: SolverResult;
|
|
14
|
+
/** Whether the loop converged to a valid result */
|
|
15
|
+
converged: boolean;
|
|
16
|
+
/** Number of rounds taken */
|
|
17
|
+
rounds: number;
|
|
18
|
+
/** Full history of attempts */
|
|
19
|
+
history: CorrectionAttempt[];
|
|
20
|
+
}
|
|
21
|
+
export interface CorrectionLoopOptions {
|
|
22
|
+
maxRounds?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Run a bounded correction loop: submit spec to solver, if it errors
|
|
26
|
+
* call the fixer to patch it, resubmit, repeat up to maxRounds.
|
|
27
|
+
*
|
|
28
|
+
* The loop stops when:
|
|
29
|
+
* - The solver returns a non-error result (sat/unsat/unknown/success) → converged
|
|
30
|
+
* - The fixer returns null (gives up) → not converged
|
|
31
|
+
* - Max rounds reached → not converged
|
|
32
|
+
*/
|
|
33
|
+
export declare function correctionLoop(initialInput: SolverInput, fixer: SpecFixer, options?: CorrectionLoopOptions): Promise<CorrectionResult>;
|
|
34
|
+
//# sourceMappingURL=correction-loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"correction-loop.d.ts","sourceRoot":"","sources":["../../src/solvers/correction-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK5D,6EAA6E;AAC7E,MAAM,MAAM,SAAS,GAAG,CACtB,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,KACV,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;AAEjC,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,yCAAyC;AACzC,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,MAAM,EAAE,YAAY,CAAC;IACrB,mDAAmD;IACnD,SAAS,EAAE,OAAO,CAAC;IACnB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,YAAY,EAAE,WAAW,EACzB,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,gBAAgB,CAAC,CA+C3B"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SolverSession } from "./session.js";
|
|
2
|
+
const DEFAULT_MAX_ROUNDS = 5;
|
|
3
|
+
/**
|
|
4
|
+
* Run a bounded correction loop: submit spec to solver, if it errors
|
|
5
|
+
* call the fixer to patch it, resubmit, repeat up to maxRounds.
|
|
6
|
+
*
|
|
7
|
+
* The loop stops when:
|
|
8
|
+
* - The solver returns a non-error result (sat/unsat/unknown/success) → converged
|
|
9
|
+
* - The fixer returns null (gives up) → not converged
|
|
10
|
+
* - Max rounds reached → not converged
|
|
11
|
+
*/
|
|
12
|
+
export async function correctionLoop(initialInput, fixer, options = {}) {
|
|
13
|
+
const maxRounds = options.maxRounds ?? DEFAULT_MAX_ROUNDS;
|
|
14
|
+
const history = [];
|
|
15
|
+
let currentInput = initialInput;
|
|
16
|
+
for (let round = 1; round <= maxRounds; round++) {
|
|
17
|
+
const solverType = currentInput.type === "z3" ? "z3" : "prolog";
|
|
18
|
+
const session = await SolverSession.create(solverType);
|
|
19
|
+
let result;
|
|
20
|
+
try {
|
|
21
|
+
result = await session.solve(currentInput);
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
session.dispose();
|
|
25
|
+
}
|
|
26
|
+
history.push({ round, input: currentInput, result });
|
|
27
|
+
// Non-error results mean the solver accepted the spec
|
|
28
|
+
if (result.status !== "error") {
|
|
29
|
+
return { result, converged: true, rounds: round, history };
|
|
30
|
+
}
|
|
31
|
+
// Last round — don't try to fix, just return
|
|
32
|
+
if (round === maxRounds) {
|
|
33
|
+
return { result, converged: false, rounds: round, history };
|
|
34
|
+
}
|
|
35
|
+
// Ask fixer to patch the spec
|
|
36
|
+
const patched = await fixer(currentInput, result.error, round);
|
|
37
|
+
if (patched === null) {
|
|
38
|
+
// Fixer gave up
|
|
39
|
+
return { result, converged: false, rounds: round, history };
|
|
40
|
+
}
|
|
41
|
+
currentInput = patched;
|
|
42
|
+
}
|
|
43
|
+
// Should not reach here, but satisfy TypeScript
|
|
44
|
+
const lastAttempt = history[history.length - 1];
|
|
45
|
+
return {
|
|
46
|
+
result: lastAttempt.result,
|
|
47
|
+
converged: false,
|
|
48
|
+
rounds: history.length,
|
|
49
|
+
history,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=correction-loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"correction-loop.js","sourceRoot":"","sources":["../../src/solvers/correction-loop.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAgC7B;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,YAAyB,EACzB,KAAgB,EAChB,UAAiC,EAAE;IAEnC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAC;IAC1D,MAAM,OAAO,GAAwB,EAAE,CAAC;IAExC,IAAI,YAAY,GAAG,YAAY,CAAC;IAEhC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC;QAChD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAa,CAAC,CAAC,CAAC,QAAiB,CAAC;QAClF,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAEvD,IAAI,MAAoB,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC7C,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;QAErD,sDAAsD;QACtD,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC9B,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC7D,CAAC;QAED,6CAA6C;QAC7C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC9D,CAAC;QAED,8BAA8B;QAC9B,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC/D,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,gBAAgB;YAChB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC9D,CAAC;QAED,YAAY,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,gDAAgD;IAChD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChD,OAAO;QACL,MAAM,EAAE,WAAW,CAAC,MAAM;QAC1B,SAAS,EAAE,KAAK;QAChB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prolog-solver.d.ts","sourceRoot":"","sources":["../../src/solvers/prolog-solver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAA2C,MAAM,YAAY,CAAC;AA6ClF,wBAAgB,kBAAkB,IAAI,MAAM,CAyD3C"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import pl from "tau-prolog";
|
|
2
|
+
const MAX_ANSWERS = 1000;
|
|
3
|
+
const MAX_INFERENCES = 100_000;
|
|
4
|
+
// Tau Prolog is callback-based; these wrap it in promises.
|
|
5
|
+
function consult(session, program) {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
session.consult(program, {
|
|
8
|
+
success: () => resolve(),
|
|
9
|
+
error: (err) => reject(err),
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function query(session, goal) {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
session.query(goal, {
|
|
16
|
+
success: () => resolve(),
|
|
17
|
+
error: (err) => reject(err),
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function nextAnswer(session) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
session.answer({
|
|
24
|
+
success: (ans) => resolve(ans),
|
|
25
|
+
fail: () => resolve(null),
|
|
26
|
+
error: (err) => reject(err),
|
|
27
|
+
limit: () => reject(new Error("inference limit exceeded")),
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function formatError(session, err) {
|
|
32
|
+
if (err instanceof Error)
|
|
33
|
+
return err.message;
|
|
34
|
+
try {
|
|
35
|
+
return session.format_answer(err) || String(err);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return String(err);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function createPrologSolver() {
|
|
42
|
+
let disposed = false;
|
|
43
|
+
return {
|
|
44
|
+
type: "prolog",
|
|
45
|
+
async solve(input) {
|
|
46
|
+
if (input.type !== "prolog") {
|
|
47
|
+
return { status: "error", error: "Expected prolog input type" };
|
|
48
|
+
}
|
|
49
|
+
const session = pl.create(MAX_INFERENCES);
|
|
50
|
+
try {
|
|
51
|
+
await consult(session, input.program);
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
return { status: "error", error: formatError(session, e) };
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
await query(session, input.query);
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
return { status: "error", error: formatError(session, e) };
|
|
61
|
+
}
|
|
62
|
+
const answers = [];
|
|
63
|
+
try {
|
|
64
|
+
for (let i = 0; i < MAX_ANSWERS; i++) {
|
|
65
|
+
const ans = await nextAnswer(session);
|
|
66
|
+
if (ans === null)
|
|
67
|
+
break;
|
|
68
|
+
const bindings = {};
|
|
69
|
+
const links = ans.links;
|
|
70
|
+
if (links) {
|
|
71
|
+
for (const [name, term] of Object.entries(links)) {
|
|
72
|
+
bindings[name] = term.toString?.()
|
|
73
|
+
?? term.id
|
|
74
|
+
?? String(term);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const formatted = pl.format_answer(ans) ?? "";
|
|
78
|
+
answers.push({ bindings, formatted });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
return { status: "error", error: formatError(session, e) };
|
|
83
|
+
}
|
|
84
|
+
return { status: "success", answers };
|
|
85
|
+
},
|
|
86
|
+
dispose() {
|
|
87
|
+
if (!disposed) {
|
|
88
|
+
disposed = true;
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=prolog-solver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prolog-solver.js","sourceRoot":"","sources":["../../src/solvers/prolog-solver.ts"],"names":[],"mappings":"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"}
|