@tienne/gestalt 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.
Files changed (288) hide show
  1. package/CLAUDE.md +203 -0
  2. package/README.md +60 -0
  3. package/agents/closure-completer/AGENT.md +32 -0
  4. package/agents/continuity-judge/AGENT.md +40 -0
  5. package/agents/ground-mapper/AGENT.md +31 -0
  6. package/agents/proximity-worker/AGENT.md +33 -0
  7. package/agents/similarity-crystallizer/AGENT.md +34 -0
  8. package/dist/agents/closure-completer/AGENT.md +32 -0
  9. package/dist/agents/continuity-judge/AGENT.md +40 -0
  10. package/dist/agents/ground-mapper/AGENT.md +31 -0
  11. package/dist/agents/proximity-worker/AGENT.md +33 -0
  12. package/dist/agents/similarity-crystallizer/AGENT.md +34 -0
  13. package/dist/bin/gestalt.d.ts +3 -0
  14. package/dist/bin/gestalt.d.ts.map +1 -0
  15. package/dist/bin/gestalt.js +5 -0
  16. package/dist/bin/gestalt.js.map +1 -0
  17. package/dist/skills/execute/SKILL.md +84 -0
  18. package/dist/skills/interview/SKILL.md +82 -0
  19. package/dist/skills/seed/SKILL.md +92 -0
  20. package/dist/skills/spec/SKILL.md +92 -0
  21. package/dist/src/agent/figural-router.d.ts +48 -0
  22. package/dist/src/agent/figural-router.d.ts.map +1 -0
  23. package/dist/src/agent/figural-router.js +55 -0
  24. package/dist/src/agent/figural-router.js.map +1 -0
  25. package/dist/src/agent/parser.d.ts +3 -0
  26. package/dist/src/agent/parser.d.ts.map +1 -0
  27. package/dist/src/agent/parser.js +32 -0
  28. package/dist/src/agent/parser.js.map +1 -0
  29. package/dist/src/agent/prompt-resolver.d.ts +17 -0
  30. package/dist/src/agent/prompt-resolver.d.ts.map +1 -0
  31. package/dist/src/agent/prompt-resolver.js +31 -0
  32. package/dist/src/agent/prompt-resolver.js.map +1 -0
  33. package/dist/src/agent/registry.d.ts +9 -0
  34. package/dist/src/agent/registry.d.ts.map +1 -0
  35. package/dist/src/agent/registry.js +22 -0
  36. package/dist/src/agent/registry.js.map +1 -0
  37. package/dist/src/cli/commands/interview.d.ts +2 -0
  38. package/dist/src/cli/commands/interview.d.ts.map +1 -0
  39. package/dist/src/cli/commands/interview.js +67 -0
  40. package/dist/src/cli/commands/interview.js.map +1 -0
  41. package/dist/src/cli/commands/seed.d.ts +4 -0
  42. package/dist/src/cli/commands/seed.d.ts.map +1 -0
  43. package/dist/src/cli/commands/seed.js +34 -0
  44. package/dist/src/cli/commands/seed.js.map +1 -0
  45. package/dist/src/cli/commands/serve.d.ts +2 -0
  46. package/dist/src/cli/commands/serve.d.ts.map +1 -0
  47. package/dist/src/cli/commands/serve.js +5 -0
  48. package/dist/src/cli/commands/serve.js.map +1 -0
  49. package/dist/src/cli/commands/spec.d.ts +4 -0
  50. package/dist/src/cli/commands/spec.d.ts.map +1 -0
  51. package/dist/src/cli/commands/spec.js +34 -0
  52. package/dist/src/cli/commands/spec.js.map +1 -0
  53. package/dist/src/cli/commands/status.d.ts +2 -0
  54. package/dist/src/cli/commands/status.d.ts.map +1 -0
  55. package/dist/src/cli/commands/status.js +66 -0
  56. package/dist/src/cli/commands/status.js.map +1 -0
  57. package/dist/src/cli/index.d.ts +3 -0
  58. package/dist/src/cli/index.d.ts.map +1 -0
  59. package/dist/src/cli/index.js +39 -0
  60. package/dist/src/cli/index.js.map +1 -0
  61. package/dist/src/core/config.d.ts +36 -0
  62. package/dist/src/core/config.d.ts.map +1 -0
  63. package/dist/src/core/config.js +65 -0
  64. package/dist/src/core/config.js.map +1 -0
  65. package/dist/src/core/constants.d.ts +34 -0
  66. package/dist/src/core/constants.d.ts.map +1 -0
  67. package/dist/src/core/constants.js +68 -0
  68. package/dist/src/core/constants.js.map +1 -0
  69. package/dist/src/core/errors.d.ts +50 -0
  70. package/dist/src/core/errors.d.ts.map +1 -0
  71. package/dist/src/core/errors.js +99 -0
  72. package/dist/src/core/errors.js.map +1 -0
  73. package/dist/src/core/log.d.ts +5 -0
  74. package/dist/src/core/log.d.ts.map +1 -0
  75. package/dist/src/core/log.js +7 -0
  76. package/dist/src/core/log.js.map +1 -0
  77. package/dist/src/core/result.d.ts +20 -0
  78. package/dist/src/core/result.d.ts.map +1 -0
  79. package/dist/src/core/result.js +43 -0
  80. package/dist/src/core/result.js.map +1 -0
  81. package/dist/src/core/types.d.ts +289 -0
  82. package/dist/src/core/types.d.ts.map +1 -0
  83. package/dist/src/core/types.js +15 -0
  84. package/dist/src/core/types.js.map +1 -0
  85. package/dist/src/events/store.d.ts +22 -0
  86. package/dist/src/events/store.d.ts.map +1 -0
  87. package/dist/src/events/store.js +130 -0
  88. package/dist/src/events/store.js.map +1 -0
  89. package/dist/src/events/types.d.ts +33 -0
  90. package/dist/src/events/types.d.ts.map +1 -0
  91. package/dist/src/events/types.js +35 -0
  92. package/dist/src/events/types.js.map +1 -0
  93. package/dist/src/execute/dag-validator.d.ts +7 -0
  94. package/dist/src/execute/dag-validator.d.ts.map +1 -0
  95. package/dist/src/execute/dag-validator.js +141 -0
  96. package/dist/src/execute/dag-validator.js.map +1 -0
  97. package/dist/src/execute/drift-detector.d.ts +11 -0
  98. package/dist/src/execute/drift-detector.d.ts.map +1 -0
  99. package/dist/src/execute/drift-detector.js +111 -0
  100. package/dist/src/execute/drift-detector.js.map +1 -0
  101. package/dist/src/execute/impact-identifier.d.ts +12 -0
  102. package/dist/src/execute/impact-identifier.d.ts.map +1 -0
  103. package/dist/src/execute/impact-identifier.js +60 -0
  104. package/dist/src/execute/impact-identifier.js.map +1 -0
  105. package/dist/src/execute/passthrough-engine.d.ts +181 -0
  106. package/dist/src/execute/passthrough-engine.d.ts.map +1 -0
  107. package/dist/src/execute/passthrough-engine.js +795 -0
  108. package/dist/src/execute/passthrough-engine.js.map +1 -0
  109. package/dist/src/execute/prompts.d.ts +19 -0
  110. package/dist/src/execute/prompts.d.ts.map +1 -0
  111. package/dist/src/execute/prompts.js +505 -0
  112. package/dist/src/execute/prompts.js.map +1 -0
  113. package/dist/src/execute/repository.d.ts +30 -0
  114. package/dist/src/execute/repository.d.ts.map +1 -0
  115. package/dist/src/execute/repository.js +248 -0
  116. package/dist/src/execute/repository.js.map +1 -0
  117. package/dist/src/execute/session.d.ts +34 -0
  118. package/dist/src/execute/session.d.ts.map +1 -0
  119. package/dist/src/execute/session.js +273 -0
  120. package/dist/src/execute/session.js.map +1 -0
  121. package/dist/src/execute/spec-patch-applier.d.ts +13 -0
  122. package/dist/src/execute/spec-patch-applier.d.ts.map +1 -0
  123. package/dist/src/execute/spec-patch-applier.js +83 -0
  124. package/dist/src/execute/spec-patch-applier.js.map +1 -0
  125. package/dist/src/execute/spec-patch-validator.d.ts +20 -0
  126. package/dist/src/execute/spec-patch-validator.d.ts.map +1 -0
  127. package/dist/src/execute/spec-patch-validator.js +60 -0
  128. package/dist/src/execute/spec-patch-validator.js.map +1 -0
  129. package/dist/src/execute/termination-detector.d.ts +20 -0
  130. package/dist/src/execute/termination-detector.d.ts.map +1 -0
  131. package/dist/src/execute/termination-detector.js +77 -0
  132. package/dist/src/execute/termination-detector.js.map +1 -0
  133. package/dist/src/gestalt/analyzer.d.ts +18 -0
  134. package/dist/src/gestalt/analyzer.d.ts.map +1 -0
  135. package/dist/src/gestalt/analyzer.js +59 -0
  136. package/dist/src/gestalt/analyzer.js.map +1 -0
  137. package/dist/src/gestalt/principles.d.ts +21 -0
  138. package/dist/src/gestalt/principles.d.ts.map +1 -0
  139. package/dist/src/gestalt/principles.js +66 -0
  140. package/dist/src/gestalt/principles.js.map +1 -0
  141. package/dist/src/index.d.ts +22 -0
  142. package/dist/src/index.d.ts.map +1 -0
  143. package/dist/src/index.js +22 -0
  144. package/dist/src/index.js.map +1 -0
  145. package/dist/src/interview/ambiguity.d.ts +8 -0
  146. package/dist/src/interview/ambiguity.d.ts.map +1 -0
  147. package/dist/src/interview/ambiguity.js +69 -0
  148. package/dist/src/interview/ambiguity.js.map +1 -0
  149. package/dist/src/interview/brownfield.d.ts +7 -0
  150. package/dist/src/interview/brownfield.d.ts.map +1 -0
  151. package/dist/src/interview/brownfield.js +28 -0
  152. package/dist/src/interview/brownfield.js.map +1 -0
  153. package/dist/src/interview/engine.d.ts +31 -0
  154. package/dist/src/interview/engine.d.ts.map +1 -0
  155. package/dist/src/interview/engine.js +110 -0
  156. package/dist/src/interview/engine.js.map +1 -0
  157. package/dist/src/interview/passthrough-engine.d.ts +52 -0
  158. package/dist/src/interview/passthrough-engine.d.ts.map +1 -0
  159. package/dist/src/interview/passthrough-engine.js +174 -0
  160. package/dist/src/interview/passthrough-engine.js.map +1 -0
  161. package/dist/src/interview/questions.d.ts +12 -0
  162. package/dist/src/interview/questions.d.ts.map +1 -0
  163. package/dist/src/interview/questions.js +54 -0
  164. package/dist/src/interview/questions.js.map +1 -0
  165. package/dist/src/interview/repository.d.ts +25 -0
  166. package/dist/src/interview/repository.d.ts.map +1 -0
  167. package/dist/src/interview/repository.js +102 -0
  168. package/dist/src/interview/repository.js.map +1 -0
  169. package/dist/src/interview/session.d.ts +22 -0
  170. package/dist/src/interview/session.d.ts.map +1 -0
  171. package/dist/src/interview/session.js +120 -0
  172. package/dist/src/interview/session.js.map +1 -0
  173. package/dist/src/llm/adapter.d.ts +8 -0
  174. package/dist/src/llm/adapter.d.ts.map +1 -0
  175. package/dist/src/llm/adapter.js +42 -0
  176. package/dist/src/llm/adapter.js.map +1 -0
  177. package/dist/src/llm/openai-adapter.d.ts +8 -0
  178. package/dist/src/llm/openai-adapter.d.ts.map +1 -0
  179. package/dist/src/llm/openai-adapter.js +45 -0
  180. package/dist/src/llm/openai-adapter.js.map +1 -0
  181. package/dist/src/llm/prompts.d.ts +15 -0
  182. package/dist/src/llm/prompts.d.ts.map +1 -0
  183. package/dist/src/llm/prompts.js +83 -0
  184. package/dist/src/llm/prompts.js.map +1 -0
  185. package/dist/src/llm/types.d.ts +21 -0
  186. package/dist/src/llm/types.d.ts.map +1 -0
  187. package/dist/src/llm/types.js +2 -0
  188. package/dist/src/llm/types.js.map +1 -0
  189. package/dist/src/mcp/schemas.d.ts +799 -0
  190. package/dist/src/mcp/schemas.d.ts.map +1 -0
  191. package/dist/src/mcp/schemas.js +151 -0
  192. package/dist/src/mcp/schemas.js.map +1 -0
  193. package/dist/src/mcp/server.d.ts +13 -0
  194. package/dist/src/mcp/server.d.ts.map +1 -0
  195. package/dist/src/mcp/server.js +255 -0
  196. package/dist/src/mcp/server.js.map +1 -0
  197. package/dist/src/mcp/tools/execute-passthrough.d.ts +4 -0
  198. package/dist/src/mcp/tools/execute-passthrough.d.ts.map +1 -0
  199. package/dist/src/mcp/tools/execute-passthrough.js +349 -0
  200. package/dist/src/mcp/tools/execute-passthrough.js.map +1 -0
  201. package/dist/src/mcp/tools/index.d.ts +4 -0
  202. package/dist/src/mcp/tools/index.d.ts.map +1 -0
  203. package/dist/src/mcp/tools/index.js +4 -0
  204. package/dist/src/mcp/tools/index.js.map +1 -0
  205. package/dist/src/mcp/tools/interview-passthrough.d.ts +4 -0
  206. package/dist/src/mcp/tools/interview-passthrough.d.ts.map +1 -0
  207. package/dist/src/mcp/tools/interview-passthrough.js +96 -0
  208. package/dist/src/mcp/tools/interview-passthrough.js.map +1 -0
  209. package/dist/src/mcp/tools/interview.d.ts +4 -0
  210. package/dist/src/mcp/tools/interview.d.ts.map +1 -0
  211. package/dist/src/mcp/tools/interview.js +85 -0
  212. package/dist/src/mcp/tools/interview.js.map +1 -0
  213. package/dist/src/mcp/tools/seed-passthrough.d.ts +5 -0
  214. package/dist/src/mcp/tools/seed-passthrough.d.ts.map +1 -0
  215. package/dist/src/mcp/tools/seed-passthrough.js +29 -0
  216. package/dist/src/mcp/tools/seed-passthrough.js.map +1 -0
  217. package/dist/src/mcp/tools/seed.d.ts +5 -0
  218. package/dist/src/mcp/tools/seed.d.ts.map +1 -0
  219. package/dist/src/mcp/tools/seed.js +19 -0
  220. package/dist/src/mcp/tools/seed.js.map +1 -0
  221. package/dist/src/mcp/tools/spec-passthrough.d.ts +5 -0
  222. package/dist/src/mcp/tools/spec-passthrough.d.ts.map +1 -0
  223. package/dist/src/mcp/tools/spec-passthrough.js +29 -0
  224. package/dist/src/mcp/tools/spec-passthrough.js.map +1 -0
  225. package/dist/src/mcp/tools/spec.d.ts +5 -0
  226. package/dist/src/mcp/tools/spec.d.ts.map +1 -0
  227. package/dist/src/mcp/tools/spec.js +19 -0
  228. package/dist/src/mcp/tools/spec.js.map +1 -0
  229. package/dist/src/mcp/tools/status.d.ts +4 -0
  230. package/dist/src/mcp/tools/status.d.ts.map +1 -0
  231. package/dist/src/mcp/tools/status.js +45 -0
  232. package/dist/src/mcp/tools/status.js.map +1 -0
  233. package/dist/src/registry/base-registry.d.ts +26 -0
  234. package/dist/src/registry/base-registry.d.ts.map +1 -0
  235. package/dist/src/registry/base-registry.js +82 -0
  236. package/dist/src/registry/base-registry.js.map +1 -0
  237. package/dist/src/seed/extractor.d.ts +15 -0
  238. package/dist/src/seed/extractor.d.ts.map +1 -0
  239. package/dist/src/seed/extractor.js +88 -0
  240. package/dist/src/seed/extractor.js.map +1 -0
  241. package/dist/src/seed/generator.d.ts +12 -0
  242. package/dist/src/seed/generator.d.ts.map +1 -0
  243. package/dist/src/seed/generator.js +66 -0
  244. package/dist/src/seed/generator.js.map +1 -0
  245. package/dist/src/seed/passthrough-generator.d.ts +31 -0
  246. package/dist/src/seed/passthrough-generator.d.ts.map +1 -0
  247. package/dist/src/seed/passthrough-generator.js +80 -0
  248. package/dist/src/seed/passthrough-generator.js.map +1 -0
  249. package/dist/src/seed/schema.d.ts +145 -0
  250. package/dist/src/seed/schema.d.ts.map +1 -0
  251. package/dist/src/seed/schema.js +37 -0
  252. package/dist/src/seed/schema.js.map +1 -0
  253. package/dist/src/skills/executor.d.ts +14 -0
  254. package/dist/src/skills/executor.d.ts.map +1 -0
  255. package/dist/src/skills/executor.js +17 -0
  256. package/dist/src/skills/executor.js.map +1 -0
  257. package/dist/src/skills/parser.d.ts +3 -0
  258. package/dist/src/skills/parser.d.ts.map +1 -0
  259. package/dist/src/skills/parser.js +37 -0
  260. package/dist/src/skills/parser.js.map +1 -0
  261. package/dist/src/skills/registry.d.ts +8 -0
  262. package/dist/src/skills/registry.d.ts.map +1 -0
  263. package/dist/src/skills/registry.js +19 -0
  264. package/dist/src/skills/registry.js.map +1 -0
  265. package/dist/src/skills/types.d.ts +19 -0
  266. package/dist/src/skills/types.d.ts.map +1 -0
  267. package/dist/src/skills/types.js +2 -0
  268. package/dist/src/skills/types.js.map +1 -0
  269. package/dist/src/spec/extractor.d.ts +15 -0
  270. package/dist/src/spec/extractor.d.ts.map +1 -0
  271. package/dist/src/spec/extractor.js +88 -0
  272. package/dist/src/spec/extractor.js.map +1 -0
  273. package/dist/src/spec/generator.d.ts +12 -0
  274. package/dist/src/spec/generator.d.ts.map +1 -0
  275. package/dist/src/spec/generator.js +66 -0
  276. package/dist/src/spec/generator.js.map +1 -0
  277. package/dist/src/spec/passthrough-generator.d.ts +34 -0
  278. package/dist/src/spec/passthrough-generator.d.ts.map +1 -0
  279. package/dist/src/spec/passthrough-generator.js +86 -0
  280. package/dist/src/spec/passthrough-generator.js.map +1 -0
  281. package/dist/src/spec/schema.d.ts +145 -0
  282. package/dist/src/spec/schema.d.ts.map +1 -0
  283. package/dist/src/spec/schema.js +37 -0
  284. package/dist/src/spec/schema.js.map +1 -0
  285. package/package.json +53 -0
  286. package/skills/execute/SKILL.md +84 -0
  287. package/skills/interview/SKILL.md +82 -0
  288. package/skills/spec/SKILL.md +92 -0
@@ -0,0 +1,130 @@
1
+ import Database from 'better-sqlite3';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { mkdirSync, existsSync } from 'node:fs';
4
+ import { dirname } from 'node:path';
5
+ import { EventStoreError } from '../core/errors.js';
6
+ export class EventStore {
7
+ db;
8
+ constructor(dbPath) {
9
+ const dir = dirname(dbPath);
10
+ if (!existsSync(dir)) {
11
+ mkdirSync(dir, { recursive: true });
12
+ }
13
+ this.db = new Database(dbPath);
14
+ this.db.pragma('journal_mode = WAL');
15
+ this.db.pragma('foreign_keys = ON');
16
+ this.initialize();
17
+ }
18
+ initialize() {
19
+ this.db.exec(`
20
+ CREATE TABLE IF NOT EXISTS events (
21
+ id TEXT PRIMARY KEY,
22
+ aggregate_type TEXT NOT NULL,
23
+ aggregate_id TEXT NOT NULL,
24
+ event_type TEXT NOT NULL,
25
+ payload TEXT NOT NULL DEFAULT '{}',
26
+ timestamp TEXT NOT NULL,
27
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
28
+ );
29
+ CREATE INDEX IF NOT EXISTS idx_events_aggregate
30
+ ON events(aggregate_type, aggregate_id);
31
+ CREATE INDEX IF NOT EXISTS idx_events_type
32
+ ON events(event_type);
33
+ CREATE INDEX IF NOT EXISTS idx_events_timestamp
34
+ ON events(timestamp);
35
+ `);
36
+ }
37
+ append(aggregateType, aggregateId, eventType, payload) {
38
+ const event = {
39
+ id: randomUUID(),
40
+ aggregateType,
41
+ aggregateId,
42
+ eventType,
43
+ payload,
44
+ timestamp: new Date().toISOString(),
45
+ createdAt: new Date().toISOString(),
46
+ };
47
+ try {
48
+ const stmt = this.db.prepare(`
49
+ INSERT INTO events (id, aggregate_type, aggregate_id, event_type, payload, timestamp)
50
+ VALUES (?, ?, ?, ?, ?, ?)
51
+ `);
52
+ stmt.run(event.id, event.aggregateType, event.aggregateId, event.eventType, JSON.stringify(event.payload), event.timestamp);
53
+ }
54
+ catch (e) {
55
+ throw new EventStoreError(`Failed to append event: ${e instanceof Error ? e.message : String(e)}`);
56
+ }
57
+ return event;
58
+ }
59
+ getByAggregate(aggregateType, aggregateId) {
60
+ const stmt = this.db.prepare(`
61
+ SELECT * FROM events
62
+ WHERE aggregate_type = ? AND aggregate_id = ?
63
+ ORDER BY timestamp ASC
64
+ `);
65
+ const rows = stmt.all(aggregateType, aggregateId);
66
+ return rows.map(parseRow);
67
+ }
68
+ getByType(eventType, limit = 100) {
69
+ const stmt = this.db.prepare(`
70
+ SELECT * FROM events
71
+ WHERE event_type = ?
72
+ ORDER BY timestamp DESC
73
+ LIMIT ?
74
+ `);
75
+ const rows = stmt.all(eventType, limit);
76
+ return rows.map(parseRow);
77
+ }
78
+ getLatest(aggregateType, aggregateId, eventType) {
79
+ const stmt = this.db.prepare(`
80
+ SELECT * FROM events
81
+ WHERE aggregate_type = ? AND aggregate_id = ? AND event_type = ?
82
+ ORDER BY rowid DESC
83
+ LIMIT 1
84
+ `);
85
+ const row = stmt.get(aggregateType, aggregateId, eventType);
86
+ return row ? parseRow(row) : null;
87
+ }
88
+ /**
89
+ * Replay all events for a specific aggregate in chronological order.
90
+ * Semantic alias for getByAggregate — used by Repository pattern for session reconstruction.
91
+ */
92
+ replay(aggregateType, aggregateId) {
93
+ return this.getByAggregate(aggregateType, aggregateId);
94
+ }
95
+ /**
96
+ * List distinct aggregate IDs for a given type, ordered by earliest event timestamp.
97
+ */
98
+ listAggregates(aggregateType) {
99
+ const stmt = this.db.prepare(`
100
+ SELECT DISTINCT aggregate_id
101
+ FROM events
102
+ WHERE aggregate_type = ?
103
+ ORDER BY MIN(timestamp) OVER (PARTITION BY aggregate_id)
104
+ `);
105
+ const rows = stmt.all(aggregateType);
106
+ return rows.map((r) => r.aggregate_id);
107
+ }
108
+ getAll(limit = 100) {
109
+ const stmt = this.db.prepare(`
110
+ SELECT * FROM events ORDER BY timestamp DESC LIMIT ?
111
+ `);
112
+ const rows = stmt.all(limit);
113
+ return rows.map(parseRow);
114
+ }
115
+ close() {
116
+ this.db.close();
117
+ }
118
+ }
119
+ function parseRow(row) {
120
+ return {
121
+ id: row.id,
122
+ aggregateType: row.aggregate_type,
123
+ aggregateId: row.aggregate_id,
124
+ eventType: row.event_type,
125
+ payload: JSON.parse(row.payload),
126
+ timestamp: row.timestamp,
127
+ createdAt: row.created_at,
128
+ };
129
+ }
130
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/events/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export declare enum EventType {
2
+ INTERVIEW_SESSION_STARTED = "interview.session.started",
3
+ INTERVIEW_QUESTION_ASKED = "interview.question.asked",
4
+ INTERVIEW_RESPONSE_RECORDED = "interview.response.recorded",
5
+ INTERVIEW_AMBIGUITY_SCORED = "interview.ambiguity.scored",
6
+ INTERVIEW_SESSION_COMPLETED = "interview.session.completed",
7
+ GESTALT_PRINCIPLE_APPLIED = "gestalt.principle.applied",
8
+ SPEC_GENERATED = "spec.generated",
9
+ BROWNFIELD_DETECTED = "brownfield.detected",
10
+ EXECUTE_SESSION_STARTED = "execute.session.started",
11
+ EXECUTE_PLANNING_STEP_COMPLETED = "execute.planning.step.completed",
12
+ EXECUTE_PLAN_VALIDATED = "execute.plan.validated",
13
+ EXECUTE_PLAN_COMPLETED = "execute.plan.completed",
14
+ EXECUTE_SESSION_FAILED = "execute.session.failed",
15
+ EXECUTE_EXECUTION_STARTED = "execute.execution.started",
16
+ EXECUTE_TASK_COMPLETED = "execute.task.completed",
17
+ EXECUTE_EVALUATION_COMPLETED = "execute.evaluation.completed",
18
+ EXECUTE_SESSION_COMPLETED = "execute.session.completed",
19
+ EVALUATE_STRUCTURAL_STARTED = "evaluate.structural.started",
20
+ EVALUATE_STRUCTURAL_COMPLETED = "evaluate.structural.completed",
21
+ EVALUATE_CONTEXTUAL_STARTED = "evaluate.contextual.started",
22
+ EVALUATE_CONTEXTUAL_COMPLETED = "evaluate.contextual.completed",
23
+ EVALUATE_SHORT_CIRCUITED = "evaluate.short.circuited",
24
+ EXECUTE_DRIFT_MEASURED = "execute.drift.measured",
25
+ EXECUTE_DRIFT_RETROSPECTIVE = "execute.drift.retrospective",
26
+ EVOLVE_STRUCTURAL_FIX_STARTED = "evolve.structural.fix.started",
27
+ EVOLVE_STRUCTURAL_FIX_COMPLETED = "evolve.structural.fix.completed",
28
+ EVOLVE_SPEC_PATCHED = "evolve.spec.patched",
29
+ EVOLVE_RE_EXECUTION_STARTED = "evolve.re.execution.started",
30
+ EVOLVE_TASK_COMPLETED = "evolve.task.completed",
31
+ EVOLVE_TERMINATED = "evolve.terminated"
32
+ }
33
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/events/types.ts"],"names":[],"mappings":"AAAA,oBAAY,SAAS;IACnB,yBAAyB,8BAA8B;IACvD,wBAAwB,6BAA6B;IACrD,2BAA2B,gCAAgC;IAC3D,0BAA0B,+BAA+B;IACzD,2BAA2B,gCAAgC;IAC3D,yBAAyB,8BAA8B;IACvD,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAC3C,uBAAuB,4BAA4B;IACnD,+BAA+B,oCAAoC;IACnE,sBAAsB,2BAA2B;IACjD,sBAAsB,2BAA2B;IACjD,sBAAsB,2BAA2B;IACjD,yBAAyB,8BAA8B;IACvD,sBAAsB,2BAA2B;IACjD,4BAA4B,iCAAiC;IAC7D,yBAAyB,8BAA8B;IACvD,2BAA2B,gCAAgC;IAC3D,6BAA6B,kCAAkC;IAC/D,2BAA2B,gCAAgC;IAC3D,6BAA6B,kCAAkC;IAC/D,wBAAwB,6BAA6B;IACrD,sBAAsB,2BAA2B;IACjD,2BAA2B,gCAAgC;IAE3D,6BAA6B,kCAAkC;IAC/D,+BAA+B,oCAAoC;IACnE,mBAAmB,wBAAwB;IAC3C,2BAA2B,gCAAgC;IAC3D,qBAAqB,0BAA0B;IAC/C,iBAAiB,sBAAsB;CACxC"}
@@ -0,0 +1,35 @@
1
+ export var EventType;
2
+ (function (EventType) {
3
+ EventType["INTERVIEW_SESSION_STARTED"] = "interview.session.started";
4
+ EventType["INTERVIEW_QUESTION_ASKED"] = "interview.question.asked";
5
+ EventType["INTERVIEW_RESPONSE_RECORDED"] = "interview.response.recorded";
6
+ EventType["INTERVIEW_AMBIGUITY_SCORED"] = "interview.ambiguity.scored";
7
+ EventType["INTERVIEW_SESSION_COMPLETED"] = "interview.session.completed";
8
+ EventType["GESTALT_PRINCIPLE_APPLIED"] = "gestalt.principle.applied";
9
+ EventType["SPEC_GENERATED"] = "spec.generated";
10
+ EventType["BROWNFIELD_DETECTED"] = "brownfield.detected";
11
+ EventType["EXECUTE_SESSION_STARTED"] = "execute.session.started";
12
+ EventType["EXECUTE_PLANNING_STEP_COMPLETED"] = "execute.planning.step.completed";
13
+ EventType["EXECUTE_PLAN_VALIDATED"] = "execute.plan.validated";
14
+ EventType["EXECUTE_PLAN_COMPLETED"] = "execute.plan.completed";
15
+ EventType["EXECUTE_SESSION_FAILED"] = "execute.session.failed";
16
+ EventType["EXECUTE_EXECUTION_STARTED"] = "execute.execution.started";
17
+ EventType["EXECUTE_TASK_COMPLETED"] = "execute.task.completed";
18
+ EventType["EXECUTE_EVALUATION_COMPLETED"] = "execute.evaluation.completed";
19
+ EventType["EXECUTE_SESSION_COMPLETED"] = "execute.session.completed";
20
+ EventType["EVALUATE_STRUCTURAL_STARTED"] = "evaluate.structural.started";
21
+ EventType["EVALUATE_STRUCTURAL_COMPLETED"] = "evaluate.structural.completed";
22
+ EventType["EVALUATE_CONTEXTUAL_STARTED"] = "evaluate.contextual.started";
23
+ EventType["EVALUATE_CONTEXTUAL_COMPLETED"] = "evaluate.contextual.completed";
24
+ EventType["EVALUATE_SHORT_CIRCUITED"] = "evaluate.short.circuited";
25
+ EventType["EXECUTE_DRIFT_MEASURED"] = "execute.drift.measured";
26
+ EventType["EXECUTE_DRIFT_RETROSPECTIVE"] = "execute.drift.retrospective";
27
+ // Evolution Loop
28
+ EventType["EVOLVE_STRUCTURAL_FIX_STARTED"] = "evolve.structural.fix.started";
29
+ EventType["EVOLVE_STRUCTURAL_FIX_COMPLETED"] = "evolve.structural.fix.completed";
30
+ EventType["EVOLVE_SPEC_PATCHED"] = "evolve.spec.patched";
31
+ EventType["EVOLVE_RE_EXECUTION_STARTED"] = "evolve.re.execution.started";
32
+ EventType["EVOLVE_TASK_COMPLETED"] = "evolve.task.completed";
33
+ EventType["EVOLVE_TERMINATED"] = "evolve.terminated";
34
+ })(EventType || (EventType = {}));
35
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/events/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,SAgCX;AAhCD,WAAY,SAAS;IACnB,oEAAuD,CAAA;IACvD,kEAAqD,CAAA;IACrD,wEAA2D,CAAA;IAC3D,sEAAyD,CAAA;IACzD,wEAA2D,CAAA;IAC3D,oEAAuD,CAAA;IACvD,8CAAiC,CAAA;IACjC,wDAA2C,CAAA;IAC3C,gEAAmD,CAAA;IACnD,gFAAmE,CAAA;IACnE,8DAAiD,CAAA;IACjD,8DAAiD,CAAA;IACjD,8DAAiD,CAAA;IACjD,oEAAuD,CAAA;IACvD,8DAAiD,CAAA;IACjD,0EAA6D,CAAA;IAC7D,oEAAuD,CAAA;IACvD,wEAA2D,CAAA;IAC3D,4EAA+D,CAAA;IAC/D,wEAA2D,CAAA;IAC3D,4EAA+D,CAAA;IAC/D,kEAAqD,CAAA;IACrD,8DAAiD,CAAA;IACjD,wEAA2D,CAAA;IAC3D,iBAAiB;IACjB,4EAA+D,CAAA;IAC/D,gFAAmE,CAAA;IACnE,wDAA2C,CAAA;IAC3C,wEAA2D,CAAA;IAC3D,4DAA+C,CAAA;IAC/C,oDAAuC,CAAA;AACzC,CAAC,EAhCW,SAAS,KAAT,SAAS,QAgCpB"}
@@ -0,0 +1,7 @@
1
+ import type { AtomicTask, TaskGroup, DAGValidation } from '../core/types.js';
2
+ /**
3
+ * Validates the dependency DAG using Kahn's algorithm for topological sort,
4
+ * checks for group conflicts, and computes the critical path.
5
+ */
6
+ export declare function validateDAG(tasks: AtomicTask[], groups: TaskGroup[]): DAGValidation;
7
+ //# sourceMappingURL=dag-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dag-validator.d.ts","sourceRoot":"","sources":["../../../src/execute/dag-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE7E;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,aAAa,CA4GnF"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Validates the dependency DAG using Kahn's algorithm for topological sort,
3
+ * checks for group conflicts, and computes the critical path.
4
+ */
5
+ export function validateDAG(tasks, groups) {
6
+ if (tasks.length === 0) {
7
+ return {
8
+ isValid: true,
9
+ hasCycles: false,
10
+ hasConflicts: false,
11
+ topologicalOrder: [],
12
+ criticalPath: [],
13
+ };
14
+ }
15
+ const taskIds = new Set(tasks.map((t) => t.taskId));
16
+ const cycleDetails = [];
17
+ const conflictDetails = [];
18
+ // Check for invalid dependency references
19
+ for (const task of tasks) {
20
+ for (const dep of task.dependsOn) {
21
+ if (!taskIds.has(dep)) {
22
+ conflictDetails.push(`Task "${task.taskId}" depends on non-existent task "${dep}"`);
23
+ }
24
+ if (dep === task.taskId) {
25
+ cycleDetails.push(`Task "${task.taskId}" depends on itself`);
26
+ }
27
+ }
28
+ }
29
+ // Check group conflicts: duplicate task in multiple groups
30
+ const taskToGroup = new Map();
31
+ for (const group of groups) {
32
+ for (const tid of group.taskIds) {
33
+ if (!taskIds.has(tid)) {
34
+ conflictDetails.push(`Group "${group.groupId}" references non-existent task "${tid}"`);
35
+ continue;
36
+ }
37
+ const existing = taskToGroup.get(tid);
38
+ if (existing) {
39
+ conflictDetails.push(`Task "${tid}" belongs to multiple groups: "${existing}" and "${group.groupId}"`);
40
+ }
41
+ taskToGroup.set(tid, group.groupId);
42
+ }
43
+ }
44
+ // Check all tasks are in a group
45
+ for (const tid of taskIds) {
46
+ if (!taskToGroup.has(tid)) {
47
+ conflictDetails.push(`Task "${tid}" is not assigned to any group`);
48
+ }
49
+ }
50
+ // Kahn's algorithm for topological sort + cycle detection
51
+ const adj = new Map();
52
+ const inDegree = new Map();
53
+ for (const task of tasks) {
54
+ adj.set(task.taskId, []);
55
+ inDegree.set(task.taskId, 0);
56
+ }
57
+ for (const task of tasks) {
58
+ for (const dep of task.dependsOn) {
59
+ if (taskIds.has(dep) && dep !== task.taskId) {
60
+ adj.get(dep).push(task.taskId);
61
+ inDegree.set(task.taskId, (inDegree.get(task.taskId) ?? 0) + 1);
62
+ }
63
+ }
64
+ }
65
+ const queue = [];
66
+ for (const [id, deg] of inDegree.entries()) {
67
+ if (deg === 0)
68
+ queue.push(id);
69
+ }
70
+ const topologicalOrder = [];
71
+ while (queue.length > 0) {
72
+ const node = queue.shift();
73
+ topologicalOrder.push(node);
74
+ for (const neighbor of adj.get(node) ?? []) {
75
+ const newDeg = (inDegree.get(neighbor) ?? 1) - 1;
76
+ inDegree.set(neighbor, newDeg);
77
+ if (newDeg === 0)
78
+ queue.push(neighbor);
79
+ }
80
+ }
81
+ const hasCycles = topologicalOrder.length !== tasks.length;
82
+ if (hasCycles) {
83
+ const remainingNodes = tasks
84
+ .filter((t) => !topologicalOrder.includes(t.taskId))
85
+ .map((t) => t.taskId);
86
+ cycleDetails.push(`Cycle detected involving tasks: ${remainingNodes.join(' → ')}`);
87
+ }
88
+ // Compute critical path (longest path in DAG) — skip if any cycles detected
89
+ const anyCycles = hasCycles || cycleDetails.length > 0;
90
+ const criticalPath = anyCycles ? [] : computeCriticalPath(tasks, topologicalOrder);
91
+ const hasConflicts = conflictDetails.length > 0;
92
+ const isValid = !hasCycles && !hasConflicts && cycleDetails.length === 0;
93
+ return {
94
+ isValid,
95
+ hasCycles: hasCycles || cycleDetails.length > 0,
96
+ ...(cycleDetails.length > 0 ? { cycleDetails } : {}),
97
+ hasConflicts,
98
+ ...(conflictDetails.length > 0 ? { conflictDetails } : {}),
99
+ topologicalOrder: anyCycles ? [] : topologicalOrder,
100
+ criticalPath,
101
+ };
102
+ }
103
+ function computeCriticalPath(tasks, topologicalOrder) {
104
+ const dist = new Map();
105
+ const predecessor = new Map();
106
+ for (const id of topologicalOrder) {
107
+ dist.set(id, 0);
108
+ predecessor.set(id, null);
109
+ }
110
+ for (const id of topologicalOrder) {
111
+ const currentDist = dist.get(id);
112
+ // Look at tasks that depend on this one (skip self-references)
113
+ for (const otherTask of tasks) {
114
+ if (otherTask.taskId !== id && otherTask.dependsOn.includes(id)) {
115
+ const newDist = currentDist + 1;
116
+ if (newDist > (dist.get(otherTask.taskId) ?? 0)) {
117
+ dist.set(otherTask.taskId, newDist);
118
+ predecessor.set(otherTask.taskId, id);
119
+ }
120
+ }
121
+ }
122
+ }
123
+ // Find the task with the longest distance
124
+ let maxDist = 0;
125
+ let endNode = topologicalOrder[0] ?? '';
126
+ for (const [id, d] of dist.entries()) {
127
+ if (d >= maxDist) {
128
+ maxDist = d;
129
+ endNode = id;
130
+ }
131
+ }
132
+ // Trace back from endNode
133
+ const path = [];
134
+ let current = endNode;
135
+ while (current !== null) {
136
+ path.unshift(current);
137
+ current = predecessor.get(current) ?? null;
138
+ }
139
+ return path;
140
+ }
141
+ //# sourceMappingURL=dag-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dag-validator.js","sourceRoot":"","sources":["../../../src/execute/dag-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Spec, TaskExecutionResult, DriftScore, AtomicTask } from '../core/types.js';
2
+ /**
3
+ * Drift Detection — 태스크 실행 결과가 원래 Spec에서 얼마나 벗어났는지 측정.
4
+ *
5
+ * 3차원 가중합:
6
+ * Goal Drift (Jaccard, 50%) — 태스크 output이 Spec goal의 핵심 키워드와 얼마나 일치하는지
7
+ * Constraint Drift (violations×0.1, 30%) — 태스크 output이 constraint 위반 가능성
8
+ * Ontology Drift (Jaccard, 20%) — 태스크가 ontology entity/relation을 참조하는지
9
+ */
10
+ export declare function measureDrift(spec: Spec, _task: AtomicTask, taskResult: TaskExecutionResult, driftThreshold: number): DriftScore;
11
+ //# sourceMappingURL=drift-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-detector.d.ts","sourceRoot":"","sources":["../../../src/execute/drift-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,mBAAmB,EACnB,UAAU,EAEV,UAAU,EACX,MAAM,kBAAkB,CAAC;AAG1B;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,mBAAmB,EAC/B,cAAc,EAAE,MAAM,GACrB,UAAU,CAkBZ"}
@@ -0,0 +1,111 @@
1
+ import { DRIFT_WEIGHTS } from '../core/constants.js';
2
+ /**
3
+ * Drift Detection — 태스크 실행 결과가 원래 Spec에서 얼마나 벗어났는지 측정.
4
+ *
5
+ * 3차원 가중합:
6
+ * Goal Drift (Jaccard, 50%) — 태스크 output이 Spec goal의 핵심 키워드와 얼마나 일치하는지
7
+ * Constraint Drift (violations×0.1, 30%) — 태스크 output이 constraint 위반 가능성
8
+ * Ontology Drift (Jaccard, 20%) — 태스크가 ontology entity/relation을 참조하는지
9
+ */
10
+ export function measureDrift(spec, _task, taskResult, driftThreshold) {
11
+ const goalDimension = measureGoalDrift(spec, taskResult);
12
+ const constraintDimension = measureConstraintDrift(spec, taskResult);
13
+ const ontologyDimension = measureOntologyDrift(spec, taskResult);
14
+ const dimensions = [goalDimension, constraintDimension, ontologyDimension];
15
+ const overall = goalDimension.score * DRIFT_WEIGHTS.goal +
16
+ constraintDimension.score * DRIFT_WEIGHTS.constraint +
17
+ ontologyDimension.score * DRIFT_WEIGHTS.ontology;
18
+ return {
19
+ taskId: taskResult.taskId,
20
+ overall: Math.round(overall * 1000) / 1000,
21
+ dimensions,
22
+ thresholdExceeded: overall > driftThreshold,
23
+ };
24
+ }
25
+ /**
26
+ * Goal Drift: 1 - Jaccard(goalTokens, outputTokens)
27
+ * 높은 값 = 더 많은 drift
28
+ */
29
+ function measureGoalDrift(spec, result) {
30
+ const goalTokens = tokenize(spec.goal);
31
+ const outputTokens = tokenize(result.output);
32
+ const jaccard = jaccardSimilarity(goalTokens, outputTokens);
33
+ const score = 1 - jaccard;
34
+ return {
35
+ name: 'goal',
36
+ score: Math.round(score * 1000) / 1000,
37
+ detail: `Goal-output Jaccard similarity: ${jaccard.toFixed(3)}`,
38
+ };
39
+ }
40
+ /**
41
+ * Constraint Drift: violations × 0.1 (capped at 1.0)
42
+ * 각 constraint의 키워드가 output에 전혀 없으면 violation 가능성으로 간주
43
+ */
44
+ function measureConstraintDrift(spec, result) {
45
+ if (spec.constraints.length === 0) {
46
+ return { name: 'constraint', score: 0, detail: 'No constraints defined' };
47
+ }
48
+ const outputTokens = tokenize(result.output);
49
+ let violations = 0;
50
+ for (const constraint of spec.constraints) {
51
+ const constraintTokens = tokenize(constraint);
52
+ const overlap = jaccardSimilarity(constraintTokens, outputTokens);
53
+ if (overlap < 0.1) {
54
+ violations++;
55
+ }
56
+ }
57
+ const score = Math.min(violations * 0.1, 1.0);
58
+ return {
59
+ name: 'constraint',
60
+ score: Math.round(score * 1000) / 1000,
61
+ detail: `${violations}/${spec.constraints.length} constraints with low output overlap`,
62
+ };
63
+ }
64
+ /**
65
+ * Ontology Drift: 1 - Jaccard(ontologyTerms, outputTokens)
66
+ * 태스크가 ontology에 정의된 entity/relation 용어를 얼마나 참조하는지
67
+ */
68
+ function measureOntologyDrift(spec, result) {
69
+ const ontologyTerms = new Set();
70
+ for (const entity of spec.ontologySchema.entities) {
71
+ ontologyTerms.add(entity.name.toLowerCase());
72
+ for (const attr of entity.attributes) {
73
+ ontologyTerms.add(attr.toLowerCase());
74
+ }
75
+ }
76
+ for (const rel of spec.ontologySchema.relations) {
77
+ ontologyTerms.add(rel.type.toLowerCase());
78
+ }
79
+ if (ontologyTerms.size === 0) {
80
+ return { name: 'ontology', score: 0, detail: 'No ontology terms defined' };
81
+ }
82
+ const outputTokens = tokenize(result.output);
83
+ const jaccard = jaccardSimilarity(ontologyTerms, outputTokens);
84
+ const score = 1 - jaccard;
85
+ return {
86
+ name: 'ontology',
87
+ score: Math.round(score * 1000) / 1000,
88
+ detail: `Ontology-output Jaccard similarity: ${jaccard.toFixed(3)}`,
89
+ };
90
+ }
91
+ function tokenize(text) {
92
+ return new Set(text
93
+ .toLowerCase()
94
+ .replace(/[^a-z0-9가-힣\s]/g, ' ')
95
+ .split(/\s+/)
96
+ .filter((t) => t.length > 1));
97
+ }
98
+ function jaccardSimilarity(setA, setB) {
99
+ if (setA.size === 0 && setB.size === 0)
100
+ return 1;
101
+ if (setA.size === 0 || setB.size === 0)
102
+ return 0;
103
+ let intersection = 0;
104
+ for (const item of setA) {
105
+ if (setB.has(item))
106
+ intersection++;
107
+ }
108
+ const union = setA.size + setB.size - intersection;
109
+ return union === 0 ? 0 : intersection / union;
110
+ }
111
+ //# sourceMappingURL=drift-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-detector.js","sourceRoot":"","sources":["../../../src/execute/drift-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { AtomicTask, DriftScore, SpecDelta } from '../core/types.js';
2
+ /**
3
+ * Drift-based Impact Task Identifier
4
+ *
5
+ * Spec 패치 후 어떤 태스크를 재실행해야 하는지 식별한다.
6
+ * 두 가지 기준으로 impacted task를 선별:
7
+ *
8
+ * 1. Drift-based: 기존 실행 시 drift threshold를 초과한 태스크
9
+ * 2. Delta-based: 패치된 필드(AC, constraint 등)와 직접 연관된 태스크
10
+ */
11
+ export declare function identifyImpactedTasks(atomicTasks: AtomicTask[], driftHistory: DriftScore[], delta: SpecDelta, driftThreshold: number): string[];
12
+ //# sourceMappingURL=impact-identifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impact-identifier.d.ts","sourceRoot":"","sources":["../../../src/execute/impact-identifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE1E;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,UAAU,EAAE,EACzB,YAAY,EAAE,UAAU,EAAE,EAC1B,KAAK,EAAE,SAAS,EAChB,cAAc,EAAE,MAAM,GACrB,MAAM,EAAE,CAoCV"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Drift-based Impact Task Identifier
3
+ *
4
+ * Spec 패치 후 어떤 태스크를 재실행해야 하는지 식별한다.
5
+ * 두 가지 기준으로 impacted task를 선별:
6
+ *
7
+ * 1. Drift-based: 기존 실행 시 drift threshold를 초과한 태스크
8
+ * 2. Delta-based: 패치된 필드(AC, constraint 등)와 직접 연관된 태스크
9
+ */
10
+ export function identifyImpactedTasks(atomicTasks, driftHistory, delta, driftThreshold) {
11
+ const impactedSet = new Set();
12
+ // 1. Drift-exceeded tasks: 기존 실행에서 이미 drift가 높았던 태스크
13
+ for (const drift of driftHistory) {
14
+ if (drift.thresholdExceeded || drift.overall > driftThreshold * 0.8) {
15
+ impactedSet.add(drift.taskId);
16
+ }
17
+ }
18
+ // 2. Delta-based: AC가 변경되었으면 해당 AC를 sourceAC로 가진 태스크 재실행
19
+ if (delta.fieldsChanged.includes('acceptanceCriteria')) {
20
+ for (const task of atomicTasks) {
21
+ // AC가 변경되었으므로 AC-linked 태스크는 재실행 대상
22
+ if (task.sourceAC.length > 0) {
23
+ impactedSet.add(task.taskId);
24
+ }
25
+ }
26
+ }
27
+ // 3. Ontology 변경 시 implicit 태스크 (ontology 기반 추론 태스크) 재실행
28
+ if (delta.fieldsChanged.includes('ontologySchema.entities') ||
29
+ delta.fieldsChanged.includes('ontologySchema.relations')) {
30
+ for (const task of atomicTasks) {
31
+ if (task.isImplicit) {
32
+ impactedSet.add(task.taskId);
33
+ }
34
+ }
35
+ }
36
+ // impacted task + 그에 의존하는 downstream 태스크도 포함
37
+ const withDependents = expandDependents(impactedSet, atomicTasks);
38
+ return Array.from(withDependents);
39
+ }
40
+ /**
41
+ * impacted 태스크에 의존하는 downstream 태스크를 재귀적으로 확장한다.
42
+ */
43
+ function expandDependents(impacted, tasks) {
44
+ const result = new Set(impacted);
45
+ let changed = true;
46
+ while (changed) {
47
+ changed = false;
48
+ for (const task of tasks) {
49
+ if (result.has(task.taskId))
50
+ continue;
51
+ // 이 태스크의 dependency 중 하나라도 impacted면 이 태스크도 impacted
52
+ if (task.dependsOn.some((dep) => result.has(dep))) {
53
+ result.add(task.taskId);
54
+ changed = true;
55
+ }
56
+ }
57
+ }
58
+ return result;
59
+ }
60
+ //# sourceMappingURL=impact-identifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impact-identifier.js","sourceRoot":"","sources":["../../../src/execute/impact-identifier.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,WAAyB,EACzB,YAA0B,EAC1B,KAAgB,EAChB,cAAsB;IAEtB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IAEtC,qDAAqD;IACrD,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,OAAO,GAAG,cAAc,GAAG,GAAG,EAAE,CAAC;YACpE,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,IAAI,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;QACvD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,oCAAoC;YACpC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,IACE,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QACvD,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EACxD,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,MAAM,cAAc,GAAG,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAElE,OAAO,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,QAAqB,EAAE,KAAmB;IAClE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,IAAI,OAAO,GAAG,IAAI,CAAC;IAEnB,OAAO,OAAO,EAAE,CAAC;QACf,OAAO,GAAG,KAAK,CAAC;QAChB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,SAAS;YACtC,qDAAqD;YACrD,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAClD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACxB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}