jfl 0.5.0 → 0.6.1

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.
Files changed (135) hide show
  1. package/dist/commands/context-hub.d.ts +1 -0
  2. package/dist/commands/context-hub.d.ts.map +1 -1
  3. package/dist/commands/context-hub.js +246 -2
  4. package/dist/commands/context-hub.js.map +1 -1
  5. package/dist/commands/peter.d.ts +2 -0
  6. package/dist/commands/peter.d.ts.map +1 -1
  7. package/dist/commands/peter.js +242 -52
  8. package/dist/commands/peter.js.map +1 -1
  9. package/dist/commands/setup.d.ts +12 -0
  10. package/dist/commands/setup.d.ts.map +1 -0
  11. package/dist/commands/setup.js +322 -0
  12. package/dist/commands/setup.js.map +1 -0
  13. package/dist/commands/train.d.ts +33 -0
  14. package/dist/commands/train.d.ts.map +1 -0
  15. package/dist/commands/train.js +510 -0
  16. package/dist/commands/train.js.map +1 -0
  17. package/dist/commands/verify.d.ts +14 -0
  18. package/dist/commands/verify.d.ts.map +1 -0
  19. package/dist/commands/verify.js +276 -0
  20. package/dist/commands/verify.js.map +1 -0
  21. package/dist/dashboard-static/assets/index-CW9ZxqX8.css +1 -0
  22. package/dist/dashboard-static/assets/index-DNN__p4K.js +121 -0
  23. package/dist/dashboard-static/index.html +2 -2
  24. package/dist/index.js +99 -3
  25. package/dist/index.js.map +1 -1
  26. package/dist/lib/agent-session.d.ts.map +1 -1
  27. package/dist/lib/agent-session.js +12 -4
  28. package/dist/lib/agent-session.js.map +1 -1
  29. package/dist/lib/eval-snapshot.js +1 -1
  30. package/dist/lib/eval-snapshot.js.map +1 -1
  31. package/dist/lib/pi-sky/bridge.d.ts +55 -0
  32. package/dist/lib/pi-sky/bridge.d.ts.map +1 -0
  33. package/dist/lib/pi-sky/bridge.js +264 -0
  34. package/dist/lib/pi-sky/bridge.js.map +1 -0
  35. package/dist/lib/pi-sky/cost-monitor.d.ts +21 -0
  36. package/dist/lib/pi-sky/cost-monitor.d.ts.map +1 -0
  37. package/dist/lib/pi-sky/cost-monitor.js +126 -0
  38. package/dist/lib/pi-sky/cost-monitor.js.map +1 -0
  39. package/dist/lib/pi-sky/eval-sweep.d.ts +27 -0
  40. package/dist/lib/pi-sky/eval-sweep.d.ts.map +1 -0
  41. package/dist/lib/pi-sky/eval-sweep.js +141 -0
  42. package/dist/lib/pi-sky/eval-sweep.js.map +1 -0
  43. package/dist/lib/pi-sky/event-router.d.ts +32 -0
  44. package/dist/lib/pi-sky/event-router.d.ts.map +1 -0
  45. package/dist/lib/pi-sky/event-router.js +176 -0
  46. package/dist/lib/pi-sky/event-router.js.map +1 -0
  47. package/dist/lib/pi-sky/experiment.d.ts +9 -0
  48. package/dist/lib/pi-sky/experiment.d.ts.map +1 -0
  49. package/dist/lib/pi-sky/experiment.js +83 -0
  50. package/dist/lib/pi-sky/experiment.js.map +1 -0
  51. package/dist/lib/pi-sky/index.d.ts +16 -0
  52. package/dist/lib/pi-sky/index.d.ts.map +1 -0
  53. package/dist/lib/pi-sky/index.js +16 -0
  54. package/dist/lib/pi-sky/index.js.map +1 -0
  55. package/dist/lib/pi-sky/stratus-gate.d.ts +28 -0
  56. package/dist/lib/pi-sky/stratus-gate.d.ts.map +1 -0
  57. package/dist/lib/pi-sky/stratus-gate.js +61 -0
  58. package/dist/lib/pi-sky/stratus-gate.js.map +1 -0
  59. package/dist/lib/pi-sky/swarm.d.ts +28 -0
  60. package/dist/lib/pi-sky/swarm.d.ts.map +1 -0
  61. package/dist/lib/pi-sky/swarm.js +208 -0
  62. package/dist/lib/pi-sky/swarm.js.map +1 -0
  63. package/dist/lib/pi-sky/types.d.ts +139 -0
  64. package/dist/lib/pi-sky/types.d.ts.map +1 -0
  65. package/dist/lib/pi-sky/types.js +2 -0
  66. package/dist/lib/pi-sky/types.js.map +1 -0
  67. package/dist/lib/pi-sky/voice-bridge.d.ts +20 -0
  68. package/dist/lib/pi-sky/voice-bridge.d.ts.map +1 -0
  69. package/dist/lib/pi-sky/voice-bridge.js +91 -0
  70. package/dist/lib/pi-sky/voice-bridge.js.map +1 -0
  71. package/dist/lib/policy-head.d.ts +16 -1
  72. package/dist/lib/policy-head.d.ts.map +1 -1
  73. package/dist/lib/policy-head.js +117 -19
  74. package/dist/lib/policy-head.js.map +1 -1
  75. package/dist/lib/predictor.d.ts +10 -0
  76. package/dist/lib/predictor.d.ts.map +1 -1
  77. package/dist/lib/predictor.js +46 -7
  78. package/dist/lib/predictor.js.map +1 -1
  79. package/dist/lib/setup/agent-generator.d.ts +18 -0
  80. package/dist/lib/setup/agent-generator.d.ts.map +1 -0
  81. package/dist/lib/setup/agent-generator.js +114 -0
  82. package/dist/lib/setup/agent-generator.js.map +1 -0
  83. package/dist/lib/setup/context-analyzer.d.ts +16 -0
  84. package/dist/lib/setup/context-analyzer.d.ts.map +1 -0
  85. package/dist/lib/setup/context-analyzer.js +112 -0
  86. package/dist/lib/setup/context-analyzer.js.map +1 -0
  87. package/dist/lib/setup/doc-auditor.d.ts +54 -0
  88. package/dist/lib/setup/doc-auditor.d.ts.map +1 -0
  89. package/dist/lib/setup/doc-auditor.js +629 -0
  90. package/dist/lib/setup/doc-auditor.js.map +1 -0
  91. package/dist/lib/setup/domain-generator.d.ts +7 -0
  92. package/dist/lib/setup/domain-generator.d.ts.map +1 -0
  93. package/dist/lib/setup/domain-generator.js +58 -0
  94. package/dist/lib/setup/domain-generator.js.map +1 -0
  95. package/dist/lib/setup/smart-eval-generator.d.ts +38 -0
  96. package/dist/lib/setup/smart-eval-generator.d.ts.map +1 -0
  97. package/dist/lib/setup/smart-eval-generator.js +378 -0
  98. package/dist/lib/setup/smart-eval-generator.js.map +1 -0
  99. package/dist/lib/setup/smart-recommender.d.ts +63 -0
  100. package/dist/lib/setup/smart-recommender.d.ts.map +1 -0
  101. package/dist/lib/setup/smart-recommender.js +329 -0
  102. package/dist/lib/setup/smart-recommender.js.map +1 -0
  103. package/dist/lib/setup/spec-generator.d.ts +63 -0
  104. package/dist/lib/setup/spec-generator.d.ts.map +1 -0
  105. package/dist/lib/setup/spec-generator.js +310 -0
  106. package/dist/lib/setup/spec-generator.js.map +1 -0
  107. package/dist/lib/setup/violation-agent-generator.d.ts +32 -0
  108. package/dist/lib/setup/violation-agent-generator.d.ts.map +1 -0
  109. package/dist/lib/setup/violation-agent-generator.js +255 -0
  110. package/dist/lib/setup/violation-agent-generator.js.map +1 -0
  111. package/package.json +1 -1
  112. package/packages/pi/extensions/context.ts +88 -55
  113. package/packages/pi/extensions/hub-resolver.ts +63 -0
  114. package/packages/pi/extensions/index.ts +16 -3
  115. package/packages/pi/extensions/memory-tool.ts +9 -4
  116. package/packages/pi/extensions/session.ts +68 -16
  117. package/packages/pi/extensions/tool-renderers.ts +23 -8
  118. package/scripts/train/requirements.txt +5 -0
  119. package/scripts/train/train-policy-head.py +477 -0
  120. package/scripts/train/v2/dataset.py +81 -0
  121. package/scripts/train/v2/domain.json +18 -0
  122. package/scripts/train/v2/eval.py +196 -0
  123. package/scripts/train/v2/generate_data.py +219 -0
  124. package/scripts/train/v2/infer.py +188 -0
  125. package/scripts/train/v2/model.py +112 -0
  126. package/scripts/train/v2/precompute.py +132 -0
  127. package/scripts/train/v2/train.py +302 -0
  128. package/scripts/train/v2/transform_buffer.py +227 -0
  129. package/scripts/train/v2/validate_data.py +115 -0
  130. package/template/.claude/settings.json +2 -15
  131. package/template/scripts/session/session-cleanup.sh +2 -11
  132. package/template/scripts/session/session-end-hub.sh +72 -0
  133. package/template/scripts/session/session-start-hub.sh +105 -0
  134. package/dist/dashboard-static/assets/index-B6b867Pv.js +0 -121
  135. package/dist/dashboard-static/assets/index-Y4BrqxV-.css +0 -1
@@ -0,0 +1,310 @@
1
+ /**
2
+ * @purpose Generate TLA+ specifications from project analysis
3
+ * Scans codebase structure, journal entries, and service configs
4
+ * to produce a formal model that TLC/Apalache can verify.
5
+ */
6
+ import { existsSync, readFileSync, readdirSync, writeFileSync, mkdirSync } from "fs";
7
+ import { join, basename } from "path";
8
+ /**
9
+ * Scan project structure and journals to extract a system model
10
+ */
11
+ export function extractSystemModel(projectRoot) {
12
+ const model = {
13
+ services: [],
14
+ stateVariables: [],
15
+ actions: [],
16
+ invariants: [],
17
+ concurrencyPatterns: [],
18
+ };
19
+ // 1. Extract services from services.json
20
+ const servicesPath = join(projectRoot, ".jfl", "services.json");
21
+ if (existsSync(servicesPath)) {
22
+ const services = JSON.parse(readFileSync(servicesPath, "utf-8"));
23
+ for (const [id, svc] of Object.entries(services)) {
24
+ model.services.push({
25
+ name: id,
26
+ type: svc.type || "process",
27
+ port: svc.port,
28
+ dependencies: [], // filled in below
29
+ });
30
+ // Each service has a status variable
31
+ model.stateVariables.push({
32
+ name: `${id}_status`,
33
+ type: "status",
34
+ domain: ["up", "down", "deploying"],
35
+ source: "services.json",
36
+ });
37
+ }
38
+ }
39
+ // 2. Extract agent configs
40
+ const agentsDir = join(projectRoot, ".jfl", "agents");
41
+ if (existsSync(agentsDir)) {
42
+ for (const file of readdirSync(agentsDir).filter(f => f.endsWith(".toml"))) {
43
+ const content = readFileSync(join(agentsDir, file), "utf-8");
44
+ const name = basename(file, ".toml");
45
+ const targetRepo = extractTomlValue(content, "target_repo") || projectRoot;
46
+ const scope = extractTomlValue(content, "scope") || "unknown";
47
+ // Agent status variable
48
+ model.stateVariables.push({
49
+ name: `agent_${name}_status`,
50
+ type: "status",
51
+ domain: ["idle", "scheduled", "running", "eval", "done"],
52
+ source: `agents/${file}`,
53
+ });
54
+ // Agent actions
55
+ model.actions.push({
56
+ name: `Schedule_${name}`,
57
+ preconditions: [`agent_${name}_status = "idle"`, `hub_status = "up"`],
58
+ effects: [`agent_${name}_status`],
59
+ source: `agents/${file}`,
60
+ });
61
+ model.actions.push({
62
+ name: `Run_${name}`,
63
+ preconditions: [`agent_${name}_status = "scheduled"`, `repo_lock_available(${targetRepo})`],
64
+ effects: [`agent_${name}_status`, `repo_locks`],
65
+ source: `agents/${file}`,
66
+ });
67
+ }
68
+ }
69
+ // 3. Analyze journals for concurrency patterns
70
+ const journalDir = join(projectRoot, ".jfl", "journal");
71
+ if (existsSync(journalDir)) {
72
+ const sessionFiles = readdirSync(journalDir).filter(f => f.endsWith(".jsonl"));
73
+ const sessions = [];
74
+ for (const file of sessionFiles) {
75
+ const entries = [];
76
+ const content = readFileSync(join(journalDir, file), "utf-8");
77
+ for (const line of content.split("\n").filter(l => l.trim())) {
78
+ try {
79
+ const entry = JSON.parse(line);
80
+ entries.push({
81
+ timestamp: entry.timestamp || 0,
82
+ files: entry.files || [],
83
+ type: entry.type || "unknown",
84
+ });
85
+ }
86
+ catch { /* skip */ }
87
+ }
88
+ if (entries.length > 0)
89
+ sessions.push(entries);
90
+ }
91
+ // Find overlapping sessions (parallel edits)
92
+ for (let i = 0; i < sessions.length; i++) {
93
+ for (let j = i + 1; j < sessions.length; j++) {
94
+ const overlap = findFileOverlap(sessions[i], sessions[j]);
95
+ if (overlap.length > 0) {
96
+ model.concurrencyPatterns.push({
97
+ type: "parallel_edit",
98
+ description: `Sessions ${i} and ${j} edited ${overlap.length} common files`,
99
+ actors: [`session_${i}`, `session_${j}`],
100
+ resource: overlap[0],
101
+ });
102
+ }
103
+ }
104
+ }
105
+ }
106
+ // 4. Infer invariants from patterns
107
+ if (model.concurrencyPatterns.some(p => p.type === "parallel_edit")) {
108
+ model.invariants.push({
109
+ name: "NoParallelEdits",
110
+ description: "No two agents should edit the same file scope simultaneously",
111
+ formula: `\\A r \\in Repos : Cardinality(repoLocks[r]) <= 1`,
112
+ severity: "critical",
113
+ source: "journal_analysis",
114
+ });
115
+ }
116
+ // Always add basic invariants
117
+ model.invariants.push({
118
+ name: "HubRequiredForScheduling",
119
+ description: "Agents cannot be scheduled when hub is down",
120
+ formula: `serviceStatus["hub"] = "down" => \\A a \\in Agents : agentStatus[a] \\notin {"running", "eval"}`,
121
+ severity: "critical",
122
+ source: "system_design",
123
+ });
124
+ model.invariants.push({
125
+ name: "LockIntegrity",
126
+ description: "Running agents must hold their repo lock",
127
+ formula: `\\A a \\in Agents : agentStatus[a] \\in {"running", "eval"} => a \\in repoLocks[agentRepo[a]]`,
128
+ severity: "critical",
129
+ source: "system_design",
130
+ });
131
+ return model;
132
+ }
133
+ /**
134
+ * Generate a TLA+ specification from a system model
135
+ */
136
+ export function generateTLASpec(model, specName) {
137
+ const services = model.services.map(s => `"${s.name}"`).join(", ");
138
+ const agents = model.stateVariables
139
+ .filter(v => v.name.startsWith("agent_") && v.type === "status")
140
+ .map(v => `"${v.name.replace("agent_", "").replace("_status", "")}"`)
141
+ .join(", ");
142
+ let spec = `---- MODULE ${specName} ----
143
+ \\* Auto-generated by jfl setup — ${new Date().toISOString()}
144
+ \\* System model extracted from project analysis
145
+
146
+ EXTENDS Integers, Sequences, FiniteSets
147
+
148
+ CONSTANTS
149
+ Agents,
150
+ Services,
151
+ Repos,
152
+ MaxRounds,
153
+ MaxBufferLen
154
+
155
+ VARIABLES
156
+ serviceStatus,
157
+ agentStatus,
158
+ agentRepo,
159
+ agentRound,
160
+ repoLocks,
161
+ trainingBuffer
162
+
163
+ vars == <<serviceStatus, agentStatus, agentRepo, agentRound, repoLocks, trainingBuffer>>
164
+
165
+ Init ==
166
+ /\\ serviceStatus = [s \\in Services |-> "up"]
167
+ /\\ agentStatus = [a \\in Agents |-> "idle"]
168
+ /\\ agentRepo = [a \\in Agents |-> CHOOSE r \\in Repos : TRUE]
169
+ /\\ agentRound = [a \\in Agents |-> 0]
170
+ /\\ repoLocks = [r \\in Repos |-> {}]
171
+ /\\ trainingBuffer = <<>>
172
+
173
+ \\* --- Service Actions ---
174
+ ServiceCrash(s) ==
175
+ /\\ serviceStatus[s] = "up"
176
+ /\\ serviceStatus' = [serviceStatus EXCEPT ![s] = "down"]
177
+ /\\ UNCHANGED <<agentStatus, agentRepo, agentRound, repoLocks, trainingBuffer>>
178
+
179
+ ServiceRestart(s) ==
180
+ /\\ serviceStatus[s] = "down"
181
+ /\\ serviceStatus' = [serviceStatus EXCEPT ![s] = "up"]
182
+ /\\ UNCHANGED <<agentStatus, agentRepo, agentRound, repoLocks, trainingBuffer>>
183
+
184
+ \\* --- Agent Actions ---
185
+ ScheduleAgent(a) ==
186
+ /\\ agentStatus[a] = "idle"
187
+ /\\ agentRound[a] < MaxRounds
188
+ /\\ serviceStatus["hub"] = "up"
189
+ /\\ agentStatus' = [agentStatus EXCEPT ![a] = "scheduled"]
190
+ /\\ UNCHANGED <<serviceStatus, agentRepo, agentRound, repoLocks, trainingBuffer>>
191
+
192
+ AgentStart(a) ==
193
+ /\\ agentStatus[a] = "scheduled"
194
+ /\\ LET repo == agentRepo[a] IN
195
+ /\\ Cardinality(repoLocks[repo]) < 2
196
+ /\\ repoLocks' = [repoLocks EXCEPT ![repo] = repoLocks[repo] \\cup {a}]
197
+ /\\ agentStatus' = [agentStatus EXCEPT ![a] = "running"]
198
+ /\\ UNCHANGED <<serviceStatus, agentRepo, agentRound, trainingBuffer>>
199
+
200
+ AgentEval(a) ==
201
+ /\\ agentStatus[a] = "running"
202
+ /\\ serviceStatus["hub"] = "up"
203
+ /\\ agentStatus' = [agentStatus EXCEPT ![a] = "eval"]
204
+ /\\ UNCHANGED <<serviceStatus, agentRepo, agentRound, repoLocks, trainingBuffer>>
205
+
206
+ AgentComplete(a) ==
207
+ /\\ agentStatus[a] = "eval"
208
+ /\\ Len(trainingBuffer) < MaxBufferLen
209
+ /\\ LET repo == agentRepo[a] IN
210
+ /\\ repoLocks' = [repoLocks EXCEPT ![repo] = repoLocks[repo] \\ {a}]
211
+ /\\ agentStatus' = [agentStatus EXCEPT ![a] = "done"]
212
+ /\\ agentRound' = [agentRound EXCEPT ![a] = agentRound[a] + 1]
213
+ /\\ \\E score \\in {0, 50, 100} :
214
+ trainingBuffer' = Append(trainingBuffer, [agent |-> a, repo |-> repo, score |-> score])
215
+ /\\ UNCHANGED <<serviceStatus, agentRepo>>
216
+
217
+ AgentReset(a) ==
218
+ /\\ agentStatus[a] = "done"
219
+ /\\ agentRound[a] < MaxRounds
220
+ /\\ agentStatus' = [agentStatus EXCEPT ![a] = "idle"]
221
+ /\\ UNCHANGED <<serviceStatus, agentRepo, agentRound, repoLocks, trainingBuffer>>
222
+
223
+ AgentRecover(a) ==
224
+ /\\ agentStatus[a] \\in {"scheduled", "running", "eval"}
225
+ /\\ serviceStatus["hub"] = "down"
226
+ /\\ LET repo == agentRepo[a] IN
227
+ /\\ repoLocks' = [repoLocks EXCEPT ![repo] = repoLocks[repo] \\ {a}]
228
+ /\\ agentStatus' = [agentStatus EXCEPT ![a] = "idle"]
229
+ /\\ UNCHANGED <<serviceStatus, agentRepo, agentRound, trainingBuffer>>
230
+
231
+ Next ==
232
+ \\/ \\E s \\in Services : ServiceCrash(s)
233
+ \\/ \\E s \\in Services : ServiceRestart(s)
234
+ \\/ \\E a \\in Agents : ScheduleAgent(a)
235
+ \\/ \\E a \\in Agents : AgentStart(a)
236
+ \\/ \\E a \\in Agents : AgentEval(a)
237
+ \\/ \\E a \\in Agents : AgentComplete(a)
238
+ \\/ \\E a \\in Agents : AgentReset(a)
239
+ \\/ \\E a \\in Agents : AgentRecover(a)
240
+
241
+ \\* --- Invariants ---
242
+ `;
243
+ // Add invariants from model
244
+ for (const inv of model.invariants) {
245
+ spec += `\n${inv.name} ==\n ${inv.formula}\n`;
246
+ }
247
+ spec += `
248
+ BoundedConcurrency ==
249
+ \\A r \\in Repos : Cardinality(repoLocks[r]) <= 2
250
+
251
+ BufferBounded ==
252
+ Len(trainingBuffer) <= MaxBufferLen
253
+
254
+ Spec == Init /\\ [][Next]_vars
255
+
256
+ ====
257
+ `;
258
+ return spec;
259
+ }
260
+ /**
261
+ * Generate TLC config file
262
+ */
263
+ export function generateTLCConfig(model, specName) {
264
+ const agents = model.stateVariables
265
+ .filter(v => v.name.startsWith("agent_") && v.type === "status")
266
+ .map(v => `"${v.name.replace("agent_", "").replace("_status", "")}"`);
267
+ const services = model.services.map(s => `"${s.name}"`);
268
+ // Infer repos from agent target_repos
269
+ const repos = [`"default"`]; // always have at least one
270
+ let cfg = `SPECIFICATION Spec\n\n`;
271
+ cfg += `CONSTANTS\n`;
272
+ cfg += ` Agents = {${agents.join(", ")}}\n`;
273
+ cfg += ` Services = {${services.join(", ")}, "hub"}\n`;
274
+ cfg += ` Repos = {${repos.join(", ")}}\n`;
275
+ cfg += ` MaxRounds = 1\n`;
276
+ cfg += ` MaxBufferLen = ${agents.length}\n`;
277
+ cfg += `\n`;
278
+ cfg += `INVARIANTS\n`;
279
+ for (const inv of model.invariants) {
280
+ cfg += ` ${inv.name}\n`;
281
+ }
282
+ cfg += ` BoundedConcurrency\n`;
283
+ cfg += ` BufferBounded\n`;
284
+ return cfg;
285
+ }
286
+ /**
287
+ * Write spec and config to disk, return paths
288
+ */
289
+ export function writeSpec(projectRoot, model, specName = "SystemSpec") {
290
+ const specDir = join(projectRoot, ".jfl", "specs");
291
+ mkdirSync(specDir, { recursive: true });
292
+ const spec = generateTLASpec(model, specName);
293
+ const cfg = generateTLCConfig(model, specName);
294
+ const specPath = join(specDir, `${specName}.tla`);
295
+ const cfgPath = join(specDir, `${specName}.cfg`);
296
+ writeFileSync(specPath, spec);
297
+ writeFileSync(cfgPath, cfg);
298
+ return { specPath, cfgPath };
299
+ }
300
+ // --- Helpers ---
301
+ function extractTomlValue(content, key) {
302
+ const match = content.match(new RegExp(`${key}\\s*=\\s*"([^"]+)"`));
303
+ return match ? match[1] : null;
304
+ }
305
+ function findFileOverlap(session1, session2) {
306
+ const files1 = session1.flatMap(e => e.files);
307
+ const files2Set = new Set(session2.flatMap(e => e.files));
308
+ return files1.filter(f => files2Set.has(f));
309
+ }
310
+ //# sourceMappingURL=spec-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-generator.js","sourceRoot":"","sources":["../../../src/lib/setup/spec-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @purpose Generate agent configs from TLC invariant violations
3
+ * Each violation becomes an agent whose eval script checks the invariant
4
+ */
5
+ interface Violation {
6
+ invariant: string;
7
+ trace: {
8
+ step: number;
9
+ action: string;
10
+ state: Record<string, string>;
11
+ }[];
12
+ }
13
+ interface ViolationAgent {
14
+ name: string;
15
+ metric: string;
16
+ direction: "maximize" | "minimize";
17
+ scope: string;
18
+ evalScript: string;
19
+ evalContent: string;
20
+ tomlContent: string;
21
+ description: string;
22
+ }
23
+ /**
24
+ * Map a TLC invariant violation to an agent config + eval script
25
+ */
26
+ export declare function violationToAgent(violation: Violation): ViolationAgent;
27
+ /**
28
+ * Write agent configs and eval scripts from violations
29
+ */
30
+ export declare function writeViolationAgents(projectRoot: string, violations: Violation[]): string[];
31
+ export {};
32
+ //# sourceMappingURL=violation-agent-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"violation-agent-generator.d.ts","sourceRoot":"","sources":["../../../src/lib/setup/violation-agent-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,UAAU,SAAS;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,EAAE,CAAA;CACzE;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,UAAU,GAAG,UAAU,CAAA;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,cAAc,CAkFrE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,SAAS,EAAE,GACtB,MAAM,EAAE,CAmCV"}
@@ -0,0 +1,255 @@
1
+ /**
2
+ * @purpose Generate agent configs from TLC invariant violations
3
+ * Each violation becomes an agent whose eval script checks the invariant
4
+ */
5
+ import { mkdirSync, writeFileSync } from "fs";
6
+ import { join } from "path";
7
+ import { generateSmartEval } from "./smart-eval-generator.js";
8
+ /**
9
+ * Map a TLC invariant violation to an agent config + eval script
10
+ */
11
+ export function violationToAgent(violation) {
12
+ const inv = violation.invariant;
13
+ const trace = violation.trace;
14
+ // Infer what went wrong from the trace
15
+ const lastStep = trace[trace.length - 1];
16
+ const actions = trace.map(t => t.action).filter(a => a !== "Initial");
17
+ switch (inv) {
18
+ case "HumanAgentIsolation":
19
+ return {
20
+ name: "repo-guard",
21
+ metric: "isolation_violations",
22
+ direction: "minimize",
23
+ scope: "coordination",
24
+ evalScript: "eval/repo-guard.sh",
25
+ description: "Prevents human-agent conflicts on shared repos",
26
+ evalContent: generateRepoGuardEval(),
27
+ tomlContent: generateToml("repo-guard", "isolation_violations", "minimize", "coordination", "eval/repo-guard.sh", "Detects and prevents concurrent human+agent edits on the same repo. Generated from TLC invariant violation."),
28
+ };
29
+ case "ScopeIsolation":
30
+ case "NoParallelEdits":
31
+ return {
32
+ name: "scope-lock",
33
+ metric: "lock_violations",
34
+ direction: "minimize",
35
+ scope: "concurrency",
36
+ evalScript: "eval/scope-lock.sh",
37
+ description: "Enforces file scope locking between agents",
38
+ evalContent: generateScopeLockEval(),
39
+ tomlContent: generateToml("scope-lock", "lock_violations", "minimize", "concurrency", "eval/scope-lock.sh", "Enforces mutual exclusion on file scopes. Generated from TLC invariant violation."),
40
+ };
41
+ case "HubRequiredForScheduling":
42
+ case "NoOrphanedAgents":
43
+ return {
44
+ name: "hub-sentinel",
45
+ metric: "stranded_agents",
46
+ direction: "minimize",
47
+ scope: "reliability",
48
+ evalScript: "eval/hub-sentinel.sh",
49
+ description: "Detects and recovers stranded agents when hub crashes",
50
+ evalContent: generateHubSentinelEval(),
51
+ tomlContent: generateToml("hub-sentinel", "stranded_agents", "minimize", "reliability", "eval/hub-sentinel.sh", "Monitors hub health and recovers agents stranded by hub crashes. Generated from TLC invariant violation."),
52
+ };
53
+ case "BoundedConcurrency":
54
+ return {
55
+ name: "concurrency-limiter",
56
+ metric: "over_concurrent_count",
57
+ direction: "minimize",
58
+ scope: "scheduling",
59
+ evalScript: "eval/concurrency-limiter.sh",
60
+ description: "Limits concurrent agents per repo",
61
+ evalContent: generateConcurrencyLimiterEval(),
62
+ tomlContent: generateToml("concurrency-limiter", "over_concurrent_count", "minimize", "scheduling", "eval/concurrency-limiter.sh", "Enforces max concurrent agents per repo. Generated from TLC invariant violation."),
63
+ };
64
+ default:
65
+ return {
66
+ name: `fix-${inv.toLowerCase().replace(/[^a-z0-9]/g, "-")}`,
67
+ metric: `${inv.toLowerCase()}_violations`,
68
+ direction: "minimize",
69
+ scope: "system",
70
+ evalScript: `eval/fix-${inv.toLowerCase()}.sh`,
71
+ description: `Fixes ${inv} invariant violation`,
72
+ evalContent: generateGenericEval(inv),
73
+ tomlContent: generateToml(`fix-${inv.toLowerCase().replace(/[^a-z0-9]/g, "-")}`, `${inv.toLowerCase()}_violations`, "minimize", "system", `eval/fix-${inv.toLowerCase()}.sh`, `Fixes ${inv} invariant violation found by TLC model checker.`),
74
+ };
75
+ }
76
+ }
77
+ /**
78
+ * Write agent configs and eval scripts from violations
79
+ */
80
+ export function writeViolationAgents(projectRoot, violations) {
81
+ const agentsDir = join(projectRoot, ".jfl", "agents");
82
+ const evalDir = join(projectRoot, "eval");
83
+ mkdirSync(agentsDir, { recursive: true });
84
+ mkdirSync(evalDir, { recursive: true });
85
+ const written = [];
86
+ for (const violation of violations) {
87
+ const agent = violationToAgent(violation);
88
+ // Write TOML config
89
+ const tomlPath = join(agentsDir, `${agent.name}.toml`);
90
+ writeFileSync(tomlPath, agent.tomlContent);
91
+ // Write eval script — use smart generator for real system checks
92
+ const evalPath = join(projectRoot, agent.evalScript);
93
+ const violationCtx = {
94
+ invariant: violation.invariant,
95
+ trace: violation.trace.map((s) => ({
96
+ step: s.step,
97
+ action: s.action,
98
+ state: s.state || {},
99
+ })),
100
+ stateVars: [],
101
+ services: [],
102
+ concurrencyPatterns: [],
103
+ };
104
+ const smartEval = generateSmartEval(projectRoot, violationCtx);
105
+ writeFileSync(evalPath, smartEval, { mode: 0o755 });
106
+ written.push(agent.name);
107
+ }
108
+ return written;
109
+ }
110
+ // --- Template generators ---
111
+ function generateToml(name, metric, direction, scope, evalScript, description) {
112
+ return `# ${name} — Generated from TLC invariant violation
113
+ # ${description}
114
+
115
+ [agent]
116
+ name = "${name}"
117
+ scope = "${scope}"
118
+ metric = "${metric}"
119
+ direction = "${direction}"
120
+ time_budget_seconds = 180
121
+ rounds = 10
122
+
123
+ [eval]
124
+ script = "${evalScript}"
125
+
126
+ [meta]
127
+ source = "tlc_violation"
128
+ generated_at = "${new Date().toISOString()}"
129
+ `;
130
+ }
131
+ function generateRepoGuardEval() {
132
+ return `#!/bin/bash
133
+ # Eval: repo-guard — checks for human-agent isolation violations
134
+ # Generated from TLC HumanAgentIsolation invariant
135
+
136
+ set -euo pipefail
137
+
138
+ VIOLATIONS=0
139
+
140
+ # Check if any agent worktrees overlap with human edit sessions
141
+ for lock_file in .jfl/locks/*.lock 2>/dev/null; do
142
+ [ -f "$lock_file" ] || continue
143
+ REPO=$(cat "$lock_file" | jq -r '.repo // empty')
144
+ AGENT=$(cat "$lock_file" | jq -r '.agent // empty')
145
+
146
+ # Check if human has uncommitted changes in same repo
147
+ if [ -n "$REPO" ] && [ -d "$REPO" ]; then
148
+ HUMAN_CHANGES=$(cd "$REPO" && git diff --name-only 2>/dev/null | wc -l | tr -d ' ')
149
+ if [ "$HUMAN_CHANGES" -gt 0 ] && [ -n "$AGENT" ]; then
150
+ echo "VIOLATION: Agent $AGENT active on $REPO while human has $HUMAN_CHANGES uncommitted changes"
151
+ VIOLATIONS=$((VIOLATIONS + 1))
152
+ fi
153
+ fi
154
+ done
155
+
156
+ echo '{"metric": "isolation_violations", "value": '$VIOLATIONS'}'
157
+ `;
158
+ }
159
+ function generateScopeLockEval() {
160
+ return `#!/bin/bash
161
+ # Eval: scope-lock — checks for concurrent scope access violations
162
+ # Generated from TLC ScopeIsolation invariant
163
+
164
+ set -euo pipefail
165
+
166
+ VIOLATIONS=0
167
+
168
+ # Check agent lock files for overlapping scopes
169
+ declare -A SCOPE_OWNERS
170
+ for lock_file in .jfl/locks/*.lock 2>/dev/null; do
171
+ [ -f "$lock_file" ] || continue
172
+ SCOPE=$(cat "$lock_file" | jq -r '.scope // empty')
173
+ AGENT=$(cat "$lock_file" | jq -r '.agent // empty')
174
+
175
+ if [ -n "$SCOPE" ] && [ -n "\${SCOPE_OWNERS[$SCOPE]+x}" ]; then
176
+ echo "VIOLATION: Scope $SCOPE held by both \${SCOPE_OWNERS[$SCOPE]} and $AGENT"
177
+ VIOLATIONS=$((VIOLATIONS + 1))
178
+ fi
179
+ SCOPE_OWNERS[$SCOPE]=$AGENT
180
+ done
181
+
182
+ echo '{"metric": "lock_violations", "value": '$VIOLATIONS'}'
183
+ `;
184
+ }
185
+ function generateHubSentinelEval() {
186
+ return `#!/bin/bash
187
+ # Eval: hub-sentinel — checks for stranded agents when hub is down
188
+ # Generated from TLC NoOrphanedAgents invariant
189
+
190
+ set -euo pipefail
191
+
192
+ STRANDED=0
193
+
194
+ # Check if hub is responsive
195
+ HUB_PORT=\${JFL_HUB_PORT:-4360}
196
+ if ! curl -s "http://localhost:$HUB_PORT/health" > /dev/null 2>&1; then
197
+ # Hub is down — check for running agents
198
+ for pid_file in .jfl/agents/pids/*.pid 2>/dev/null; do
199
+ [ -f "$pid_file" ] || continue
200
+ PID=$(cat "$pid_file")
201
+ if kill -0 "$PID" 2>/dev/null; then
202
+ AGENT=$(basename "$pid_file" .pid)
203
+ echo "STRANDED: Agent $AGENT (pid $PID) running while hub is down"
204
+ STRANDED=$((STRANDED + 1))
205
+ fi
206
+ done
207
+ fi
208
+
209
+ echo '{"metric": "stranded_agents", "value": '$STRANDED'}'
210
+ `;
211
+ }
212
+ function generateConcurrencyLimiterEval() {
213
+ return `#!/bin/bash
214
+ # Eval: concurrency-limiter — checks for over-concurrent repo access
215
+ # Generated from TLC BoundedConcurrency invariant
216
+
217
+ set -euo pipefail
218
+
219
+ MAX_CONCURRENT=\${JFL_MAX_CONCURRENT:-2}
220
+ OVER_COUNT=0
221
+
222
+ declare -A REPO_COUNTS
223
+ for lock_file in .jfl/locks/*.lock 2>/dev/null; do
224
+ [ -f "$lock_file" ] || continue
225
+ REPO=$(cat "$lock_file" | jq -r '.repo // empty')
226
+ if [ -n "$REPO" ]; then
227
+ REPO_COUNTS[$REPO]=$(( \${REPO_COUNTS[$REPO]:-0} + 1 ))
228
+ if [ "\${REPO_COUNTS[$REPO]}" -gt "$MAX_CONCURRENT" ]; then
229
+ echo "OVER: $REPO has \${REPO_COUNTS[$REPO]} concurrent agents (max $MAX_CONCURRENT)"
230
+ OVER_COUNT=$((OVER_COUNT + 1))
231
+ fi
232
+ fi
233
+ done
234
+
235
+ echo '{"metric": "over_concurrent_count", "value": '$OVER_COUNT'}'
236
+ `;
237
+ }
238
+ function generateGenericEval(invariant) {
239
+ return `#!/bin/bash
240
+ # Eval: fix-${invariant.toLowerCase()} — checks ${invariant} invariant
241
+ # Generated from TLC model checker violation
242
+
243
+ set -euo pipefail
244
+
245
+ # TODO: Implement specific check for ${invariant}
246
+ # The TLC model checker found that this invariant can be violated.
247
+ # This eval script should check the runtime system for the same condition.
248
+
249
+ VIOLATIONS=0
250
+
251
+ # Placeholder check
252
+ echo '{"metric": "${invariant.toLowerCase()}_violations", "value": '$VIOLATIONS'}'
253
+ `;
254
+ }
255
+ //# sourceMappingURL=violation-agent-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"violation-agent-generator.js","sourceRoot":"","sources":["../../../src/lib/setup/violation-agent-generator.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jfl",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "description": "Just Fucking Launch - CLI for AI-powered GTM and development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",