igel-qe-core 1.0.3 → 1.0.7

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 (628) hide show
  1. package/dist/cli/index.js +638 -54
  2. package/dist/cli/platform.js +115 -72
  3. package/dist/mcp/server.js +258 -17
  4. package/package.json +4 -4
  5. package/src/__pycache__/__init__.cpython-311.pyc +0 -0
  6. package/src/__pycache__/__init__.cpython-313.pyc +0 -0
  7. package/src/__pycache__/__init__.cpython-314.pyc +0 -0
  8. package/src/agents/__init__.py +3 -0
  9. package/src/agents/__pycache__/__init__.cpython-311.pyc +0 -0
  10. package/src/agents/__pycache__/__init__.cpython-313.pyc +0 -0
  11. package/src/agents/__pycache__/__init__.cpython-314.pyc +0 -0
  12. package/src/agents/__pycache__/automation_design_agent.cpython-311.pyc +0 -0
  13. package/src/agents/__pycache__/automation_design_agent.cpython-313.pyc +0 -0
  14. package/src/agents/__pycache__/automation_design_agent.cpython-314.pyc +0 -0
  15. package/src/agents/__pycache__/code_intelligence_agent.cpython-311.pyc +0 -0
  16. package/src/agents/__pycache__/code_intelligence_agent.cpython-313.pyc +0 -0
  17. package/src/agents/__pycache__/confidence_agent.cpython-311.pyc +0 -0
  18. package/src/agents/__pycache__/confidence_agent.cpython-313.pyc +0 -0
  19. package/src/agents/__pycache__/confidence_agent.cpython-314.pyc +0 -0
  20. package/src/agents/__pycache__/execution_validation_agent.cpython-311.pyc +0 -0
  21. package/src/agents/__pycache__/execution_validation_agent.cpython-313.pyc +0 -0
  22. package/src/agents/__pycache__/execution_validation_agent.cpython-314.pyc +0 -0
  23. package/src/agents/__pycache__/framework_analyzer_agent.cpython-311.pyc +0 -0
  24. package/src/agents/__pycache__/framework_analyzer_agent.cpython-313.pyc +0 -0
  25. package/src/agents/__pycache__/fusion_agent.cpython-314.pyc +0 -0
  26. package/src/agents/__pycache__/graph.cpython-314.pyc +0 -0
  27. package/src/agents/__pycache__/intent_agent.cpython-313.pyc +0 -0
  28. package/src/agents/__pycache__/intent_agent.cpython-314.pyc +0 -0
  29. package/src/agents/__pycache__/kg_agent.cpython-314.pyc +0 -0
  30. package/src/agents/__pycache__/memory_agent.cpython-314.pyc +0 -0
  31. package/src/agents/__pycache__/reflection_agent.cpython-314.pyc +0 -0
  32. package/src/agents/__pycache__/regression_agent.cpython-311.pyc +0 -0
  33. package/src/agents/__pycache__/regression_agent.cpython-313.pyc +0 -0
  34. package/src/agents/__pycache__/requirement_agent.cpython-311.pyc +0 -0
  35. package/src/agents/__pycache__/requirement_agent.cpython-313.pyc +0 -0
  36. package/src/agents/__pycache__/requirement_agent.cpython-314.pyc +0 -0
  37. package/src/agents/__pycache__/retrieval_agent.cpython-314.pyc +0 -0
  38. package/src/agents/__pycache__/scenario_agent.cpython-311.pyc +0 -0
  39. package/src/agents/__pycache__/scenario_agent.cpython-313.pyc +0 -0
  40. package/src/agents/__pycache__/scenario_agent.cpython-314.pyc +0 -0
  41. package/src/agents/__pycache__/script_agent.cpython-314.pyc +0 -0
  42. package/src/agents/__pycache__/script_generator_agent.cpython-311.pyc +0 -0
  43. package/src/agents/__pycache__/script_generator_agent.cpython-313.pyc +0 -0
  44. package/src/agents/__pycache__/script_generator_agent.cpython-314.pyc +0 -0
  45. package/src/agents/__pycache__/state.cpython-314.pyc +0 -0
  46. package/src/agents/__pycache__/temporal_agent.cpython-314.pyc +0 -0
  47. package/src/agents/__pycache__/testcase_agent.cpython-311.pyc +0 -0
  48. package/src/agents/__pycache__/testcase_agent.cpython-313.pyc +0 -0
  49. package/src/agents/__pycache__/testcase_agent.cpython-314.pyc +0 -0
  50. package/src/agents/__pycache__/validation_agent.cpython-311.pyc +0 -0
  51. package/src/agents/__pycache__/validation_agent.cpython-313.pyc +0 -0
  52. package/src/agents/__pycache__/validation_agent.cpython-314.pyc +0 -0
  53. package/src/agents/__pycache__/workflow_engine.cpython-311.pyc +0 -0
  54. package/src/agents/__pycache__/workflow_engine.cpython-313.pyc +0 -0
  55. package/src/agents/__pycache__/workflow_engine.cpython-314.pyc +0 -0
  56. package/{knowledge_base → src}/agents/automation_design_agent.py +14 -17
  57. package/{knowledge_base → src}/agents/code_intelligence_agent.py +2 -2
  58. package/src/agents/confidence_agent.py +114 -0
  59. package/{knowledge_base → src}/agents/execution_validation_agent.py +1 -1
  60. package/src/agents/feedback_agent.py +89 -0
  61. package/src/agents/framework_analyzer_agent.py +43 -0
  62. package/{knowledge_base → src}/agents/fusion_agent.py +3 -3
  63. package/{knowledge_base → src}/agents/graph.py +10 -10
  64. package/{knowledge_base → src}/agents/healing_agent.py +4 -4
  65. package/src/agents/intent_agent.py +30 -0
  66. package/src/agents/internal/__init__.py +3 -0
  67. package/src/agents/internal/__pycache__/__init__.cpython-313.pyc +0 -0
  68. package/src/agents/internal/__pycache__/approval_manager.cpython-313.pyc +0 -0
  69. package/src/agents/internal/__pycache__/question_engine.cpython-313.pyc +0 -0
  70. package/src/agents/internal/approval_manager.py +111 -0
  71. package/src/agents/internal/question_engine.py +111 -0
  72. package/src/agents/internal/workflow_engine.py +28 -0
  73. package/{knowledge_base → src}/agents/kg_agent.py +3 -3
  74. package/{knowledge_base → src}/agents/memory_agent.py +4 -4
  75. package/src/agents/orchestrator/__init__.py +3 -0
  76. package/src/agents/orchestrator/__pycache__/__init__.cpython-313.pyc +0 -0
  77. package/src/agents/orchestrator/__pycache__/orchestrator.cpython-313.pyc +0 -0
  78. package/src/agents/orchestrator/orchestrator.py +63 -0
  79. package/{knowledge_base → src}/agents/rca_agent.py +4 -4
  80. package/{knowledge_base → src}/agents/reflection_agent.py +1 -1
  81. package/{knowledge_base → src}/agents/regression_agent.py +2 -2
  82. package/src/agents/requirement_agent.py +97 -0
  83. package/{knowledge_base → src}/agents/retrieval_agent.py +2 -2
  84. package/{knowledge_base → src}/agents/scenario_agent.py +11 -17
  85. package/{knowledge_base → src}/agents/script_agent.py +6 -6
  86. package/{knowledge_base → src}/agents/script_generator_agent.py +12 -10
  87. package/{knowledge_base → src}/agents/temporal_agent.py +3 -3
  88. package/src/agents/testcase_agent.py +163 -0
  89. package/{knowledge_base → src}/agents/validation_agent.py +1 -1
  90. package/src/agents/workflow_engine.py +109 -0
  91. package/{knowledge_base → src}/alembic/README.md +4 -4
  92. package/{knowledge_base → src}/alembic/env.py +1 -1
  93. package/{knowledge_base → src}/alembic/script.py.mako +1 -1
  94. package/{knowledge_base → src}/api/middleware.py +3 -3
  95. package/{knowledge_base → src}/api/server.py +28 -28
  96. package/{knowledge_base → src}/chunking/chunker.py +3 -3
  97. package/src/cli/__pycache__/__init__.cpython-311.pyc +0 -0
  98. package/src/cli/__pycache__/__init__.cpython-313.pyc +0 -0
  99. package/src/cli/__pycache__/__init__.cpython-314.pyc +0 -0
  100. package/src/cli/__pycache__/workflow_cli.cpython-311.pyc +0 -0
  101. package/src/cli/__pycache__/workflow_cli.cpython-313.pyc +0 -0
  102. package/src/cli/__pycache__/workflow_cli.cpython-314.pyc +0 -0
  103. package/{knowledge_base → src}/cli/feedback_cli.py +10 -10
  104. package/{knowledge_base → src}/cli/generate.py +11 -11
  105. package/src/cli/index.ts +704 -0
  106. package/src/cli/platform.ts +147 -0
  107. package/src/cli/workflow_cli.py +930 -0
  108. package/{knowledge_base → src}/config/__init__.py +1 -1
  109. package/src/config/__pycache__/__init__.cpython-311.pyc +0 -0
  110. package/src/config/__pycache__/__init__.cpython-313.pyc +0 -0
  111. package/src/config/__pycache__/__init__.cpython-314.pyc +0 -0
  112. package/src/config/__pycache__/policy_config.cpython-311.pyc +0 -0
  113. package/src/config/__pycache__/policy_config.cpython-313.pyc +0 -0
  114. package/src/config/__pycache__/settings.cpython-311.pyc +0 -0
  115. package/src/config/__pycache__/settings.cpython-313.pyc +0 -0
  116. package/src/config/__pycache__/settings.cpython-314.pyc +0 -0
  117. package/src/config/policy_config.py +85 -0
  118. package/src/config/policy_rules.yaml +50 -0
  119. package/{knowledge_base → src}/config/settings.py +51 -6
  120. package/{knowledge_base → src}/connectors/__init__.py +1 -1
  121. package/src/connectors/__pycache__/__init__.cpython-311.pyc +0 -0
  122. package/src/connectors/__pycache__/__init__.cpython-313.pyc +0 -0
  123. package/src/connectors/__pycache__/__init__.cpython-314.pyc +0 -0
  124. package/src/connectors/__pycache__/base.cpython-311.pyc +0 -0
  125. package/src/connectors/__pycache__/base.cpython-313.pyc +0 -0
  126. package/src/connectors/__pycache__/base.cpython-314.pyc +0 -0
  127. package/src/connectors/__pycache__/jira_connector.cpython-311.pyc +0 -0
  128. package/src/connectors/__pycache__/jira_connector.cpython-313.pyc +0 -0
  129. package/src/connectors/__pycache__/jira_connector.cpython-314.pyc +0 -0
  130. package/src/connectors/__pycache__/query_bridge.cpython-313.pyc +0 -0
  131. package/src/connectors/__pycache__/query_bridge.cpython-314.pyc +0 -0
  132. package/src/connectors/bitbucket_connector.py +334 -0
  133. package/{knowledge_base → src}/connectors/community_connector.py +6 -6
  134. package/{knowledge_base → src}/connectors/confluence_connector.py +4 -4
  135. package/{knowledge_base → src}/connectors/jira_connector.py +7 -11
  136. package/{knowledge_base → src}/connectors/kb_igel_connector.py +6 -6
  137. package/{knowledge_base → src}/connectors/query_bridge.py +11 -11
  138. package/{knowledge_base → src}/connectors/search_backends.py +1 -1
  139. package/{knowledge_base → src}/connectors/serviceNow_connector.py +2 -2
  140. package/{knowledge_base → src}/connectors/sync_scheduler.py +12 -10
  141. package/{knowledge_base → src}/connectors/teamcity_connector.py +2 -2
  142. package/{knowledge_base → src}/connectors/testRail_connector.py +2 -2
  143. package/{knowledge_base → src}/connectors/web_fetcher.py +1 -1
  144. package/src/connectors/xray_connector.py +337 -0
  145. package/{knowledge_base → src}/core/__init__.py +1 -1
  146. package/src/core/__pycache__/__init__.cpython-311.pyc +0 -0
  147. package/src/core/__pycache__/__init__.cpython-313.pyc +0 -0
  148. package/src/core/__pycache__/__init__.cpython-314.pyc +0 -0
  149. package/src/core/__pycache__/circuit_breaker.cpython-313.pyc +0 -0
  150. package/src/core/__pycache__/circuit_breaker.cpython-314.pyc +0 -0
  151. package/src/core/__pycache__/confidence.cpython-311.pyc +0 -0
  152. package/src/core/__pycache__/confidence.cpython-313.pyc +0 -0
  153. package/src/core/__pycache__/confidence.cpython-314.pyc +0 -0
  154. package/src/core/__pycache__/context_engine.cpython-311.pyc +0 -0
  155. package/src/core/__pycache__/context_engine.cpython-313.pyc +0 -0
  156. package/src/core/__pycache__/evidence_resolver.cpython-311.pyc +0 -0
  157. package/src/core/__pycache__/evidence_resolver.cpython-313.pyc +0 -0
  158. package/src/core/__pycache__/guardrails.cpython-311.pyc +0 -0
  159. package/src/core/__pycache__/guardrails.cpython-313.pyc +0 -0
  160. package/src/core/__pycache__/hooks.cpython-311.pyc +0 -0
  161. package/src/core/__pycache__/hooks.cpython-313.pyc +0 -0
  162. package/src/core/__pycache__/intent_service.cpython-313.pyc +0 -0
  163. package/src/core/__pycache__/llm_executor.cpython-311.pyc +0 -0
  164. package/src/core/__pycache__/llm_executor.cpython-313.pyc +0 -0
  165. package/src/core/__pycache__/model_router.cpython-311.pyc +0 -0
  166. package/src/core/__pycache__/model_router.cpython-313.pyc +0 -0
  167. package/src/core/__pycache__/orchestration_contracts.cpython-311.pyc +0 -0
  168. package/src/core/__pycache__/orchestration_contracts.cpython-313.pyc +0 -0
  169. package/src/core/__pycache__/precedence.cpython-311.pyc +0 -0
  170. package/src/core/__pycache__/precedence.cpython-313.pyc +0 -0
  171. package/src/core/__pycache__/prompt_builder.cpython-311.pyc +0 -0
  172. package/src/core/__pycache__/prompt_builder.cpython-313.pyc +0 -0
  173. package/src/core/__pycache__/prompt_policy_engine.cpython-311.pyc +0 -0
  174. package/src/core/__pycache__/prompt_policy_engine.cpython-313.pyc +0 -0
  175. package/{knowledge_base → src}/core/cache.py +2 -2
  176. package/{knowledge_base → src}/core/confidence.py +2 -2
  177. package/src/core/context_engine.py +138 -0
  178. package/src/core/evidence_resolver.py +72 -0
  179. package/src/core/guardrails.py +22 -0
  180. package/src/core/hooks.py +57 -0
  181. package/src/core/intent_service.py +74 -0
  182. package/src/core/llm_executor.py +138 -0
  183. package/{knowledge_base → src}/core/logging_setup.py +1 -1
  184. package/src/core/model_router.py +246 -0
  185. package/src/core/orchestration_contracts.py +66 -0
  186. package/src/core/persistence_engine.py +159 -0
  187. package/src/core/prompt_builder.py +49 -0
  188. package/src/core/prompt_policy_engine.py +35 -0
  189. package/src/core/traceability_engine.py +56 -0
  190. package/src/db/__pycache__/__init__.cpython-311.pyc +0 -0
  191. package/src/db/__pycache__/__init__.cpython-313.pyc +0 -0
  192. package/src/db/__pycache__/__init__.cpython-314.pyc +0 -0
  193. package/src/db/__pycache__/client.cpython-311.pyc +0 -0
  194. package/src/db/__pycache__/client.cpython-313.pyc +0 -0
  195. package/src/db/__pycache__/client.cpython-314.pyc +0 -0
  196. package/src/db/__pycache__/igel_schema.cpython-311.pyc +0 -0
  197. package/src/db/__pycache__/igel_schema.cpython-313.pyc +0 -0
  198. package/src/db/__pycache__/igel_schema.cpython-314.pyc +0 -0
  199. package/src/db/__pycache__/kg_introspect.cpython-311.pyc +0 -0
  200. package/src/db/__pycache__/kg_introspect.cpython-313.pyc +0 -0
  201. package/{knowledge_base → src}/db/__pycache__/kg_introspect.cpython-314.pyc +0 -0
  202. package/{knowledge_base → src}/db/client.py +1 -1
  203. package/{knowledge_base → src}/db/connector_sync.py +1 -1
  204. package/{knowledge_base → src}/db/feedback_schema.py +2 -2
  205. package/{knowledge_base → src}/db/igel_schema.py +29 -4
  206. package/{knowledge_base → src}/db/kg_introspect.py +1 -1
  207. package/src/db/migrations.py +237 -0
  208. package/{knowledge_base → src}/db/schema.py +6 -6
  209. package/{knowledge_base → src}/deploy/Dockerfile +3 -3
  210. package/{knowledge_base → src}/deploy/feedback_automation.sh +3 -3
  211. package/{knowledge_base → src}/deploy/firecrawl-docker.sh +4 -4
  212. package/{knowledge_base → src}/deploy/igel-testgen.service +2 -2
  213. package/{knowledge_base → src}/deploy/install_reranker.sh +1 -1
  214. package/{knowledge_base → src}/deploy/requirements.txt +1 -2
  215. package/{knowledge_base → src}/deploy/run_server.sh +1 -1
  216. package/{knowledge_base → src}/docs/TEST_GENERATION_GUIDE.md +15 -15
  217. package/src/embeddings/__pycache__/__init__.cpython-311.pyc +0 -0
  218. package/src/embeddings/__pycache__/__init__.cpython-313.pyc +0 -0
  219. package/src/embeddings/__pycache__/__init__.cpython-314.pyc +0 -0
  220. package/src/embeddings/__pycache__/azure_embedder.cpython-311.pyc +0 -0
  221. package/src/embeddings/__pycache__/azure_embedder.cpython-313.pyc +0 -0
  222. package/{knowledge_base → src}/embeddings/__pycache__/azure_embedder.cpython-314.pyc +0 -0
  223. package/{knowledge_base → src}/embeddings/azure_embedder.py +10 -1
  224. package/{knowledge_base → src}/eval/__init__.py +3 -3
  225. package/{knowledge_base → src}/eval/__main__.py +7 -7
  226. package/src/eval/__pycache__/__init__.cpython-311.pyc +0 -0
  227. package/src/eval/__pycache__/__init__.cpython-313.pyc +0 -0
  228. package/src/eval/__pycache__/__init__.cpython-314.pyc +0 -0
  229. package/src/eval/__pycache__/baseline.cpython-311.pyc +0 -0
  230. package/src/eval/__pycache__/baseline.cpython-313.pyc +0 -0
  231. package/src/eval/__pycache__/baseline.cpython-314.pyc +0 -0
  232. package/src/eval/__pycache__/harness.cpython-311.pyc +0 -0
  233. package/src/eval/__pycache__/harness.cpython-313.pyc +0 -0
  234. package/src/eval/__pycache__/harness.cpython-314.pyc +0 -0
  235. package/src/eval/__pycache__/scorers.cpython-311.pyc +0 -0
  236. package/src/eval/__pycache__/scorers.cpython-313.pyc +0 -0
  237. package/src/eval/__pycache__/scorers.cpython-314.pyc +0 -0
  238. package/{knowledge_base → src}/eval/harness.py +6 -6
  239. package/{knowledge_base → src}/feedback/__init__.py +1 -1
  240. package/{knowledge_base → src}/feedback/analytics.py +1 -1
  241. package/{knowledge_base → src}/feedback/applier.py +4 -4
  242. package/{knowledge_base → src}/feedback/curator.py +2 -2
  243. package/{knowledge_base → src}/feedback/handler.py +1 -1
  244. package/src/generation/__pycache__/__init__.cpython-313.pyc +0 -0
  245. package/src/generation/__pycache__/__init__.cpython-314.pyc +0 -0
  246. package/src/generation/__pycache__/input_classifier.cpython-313.pyc +0 -0
  247. package/src/generation/__pycache__/manual_tc_parser.cpython-313.pyc +0 -0
  248. package/src/generation/__pycache__/prompts.cpython-313.pyc +0 -0
  249. package/src/generation/__pycache__/prompts.cpython-314.pyc +0 -0
  250. package/src/generation/__pycache__/test_generator.cpython-313.pyc +0 -0
  251. package/src/generation/__pycache__/test_generator.cpython-314.pyc +0 -0
  252. package/{knowledge_base → src}/generation/input_classifier.py +1 -1
  253. package/{knowledge_base → src}/generation/prompts.py +1 -1
  254. package/{knowledge_base → src}/generation/tc_transformer.py +10 -10
  255. package/{knowledge_base → src}/generation/test_generator.py +56 -10
  256. package/{knowledge_base → src}/graph_db/__init__.py +1 -1
  257. package/{knowledge_base → src}/graph_db/graphiti_client.py +2 -2
  258. package/{knowledge_base → src}/graph_db/kg_traversal.py +3 -3
  259. package/{knowledge_base → src}/graph_db/migrate_kg.py +4 -4
  260. package/{knowledge_base → src}/graph_db/neo4j_client.py +1 -1
  261. package/{knowledge_base → src}/graph_db/temporal_ingest.py +1 -1
  262. package/{knowledge_base → src}/ingestion/kg_extractor.py +6 -6
  263. package/{knowledge_base → src}/ingestion/web_ingest.py +6 -6
  264. package/src/intelligence/__pycache__/__init__.cpython-311.pyc +0 -0
  265. package/src/intelligence/__pycache__/__init__.cpython-313.pyc +0 -0
  266. package/src/intelligence/__pycache__/diff_analyzer.cpython-311.pyc +0 -0
  267. package/src/intelligence/__pycache__/diff_analyzer.cpython-313.pyc +0 -0
  268. package/src/intelligence/__pycache__/routing_engine.cpython-311.pyc +0 -0
  269. package/src/intelligence/__pycache__/routing_engine.cpython-313.pyc +0 -0
  270. package/src/intelligence/diff_analyzer.py +109 -0
  271. package/{knowledge_base → src}/intelligence/execution_ingest.py +3 -3
  272. package/src/intelligence/routing_engine.py +74 -0
  273. package/src/mcp/server.ts +384 -0
  274. package/src/memory/__init__.py +6 -0
  275. package/src/memory/__pycache__/__init__.cpython-314.pyc +0 -0
  276. package/src/memory/__pycache__/cognee_client.cpython-314.pyc +0 -0
  277. package/src/memory/__pycache__/memory_types.cpython-314.pyc +0 -0
  278. package/{knowledge_base → src}/memory/cognee_client.py +3 -3
  279. package/src/models/__pycache__/test_requirement.cpython-311.pyc +0 -0
  280. package/src/models/__pycache__/test_requirement.cpython-313.pyc +0 -0
  281. package/src/models/__pycache__/test_requirement.cpython-314.pyc +0 -0
  282. package/{knowledge_base → src}/models/test_requirement.py +12 -7
  283. package/{knowledge_base → src}/parsers/csv_parser.py +1 -1
  284. package/{knowledge_base → src}/parsers/doc_parser.py +1 -1
  285. package/{knowledge_base → src}/parsers/html_parser.py +1 -1
  286. package/{knowledge_base → src}/parsers/pdf_parser.py +1 -1
  287. package/src/project/__pycache__/__init__.cpython-311.pyc +0 -0
  288. package/src/project/__pycache__/__init__.cpython-313.pyc +0 -0
  289. package/src/project/__pycache__/ai_folder.cpython-311.pyc +0 -0
  290. package/src/project/__pycache__/ai_folder.cpython-313.pyc +0 -0
  291. package/src/project/__pycache__/context_enricher.cpython-313.pyc +0 -0
  292. package/src/project/__pycache__/context_projection_builder.cpython-311.pyc +0 -0
  293. package/src/project/__pycache__/context_projection_builder.cpython-313.pyc +0 -0
  294. package/src/project/__pycache__/context_requirement_sync.cpython-311.pyc +0 -0
  295. package/src/project/__pycache__/context_requirement_sync.cpython-313.pyc +0 -0
  296. package/src/project/ai_folder.py +602 -0
  297. package/src/project/context_enricher.py +333 -0
  298. package/src/project/context_projection_builder.py +167 -0
  299. package/src/project/context_requirement_sync.py +205 -0
  300. package/src/project/init_check.py +214 -0
  301. package/src/prompts/__pycache__/prompt_loader.cpython-313.pyc +0 -0
  302. package/src/prompts/automation_design.md +12 -0
  303. package/src/prompts/policies/automation_generation_policy.md +11 -0
  304. package/src/prompts/policies/generation_instructions.md +24 -0
  305. package/src/prompts/policies/guardrails.md +6 -0
  306. package/src/prompts/policies/traceability_policy.md +9 -0
  307. package/src/prompts/prompt_loader.py +56 -0
  308. package/src/prompts/requirement_understanding.md +17 -0
  309. package/src/prompts/scenario_generator.md +17 -0
  310. package/src/prompts/script_generator.md +13 -0
  311. package/src/prompts/test_case_generator.md +23 -0
  312. package/src/retrieval/__pycache__/__init__.cpython-311.pyc +0 -0
  313. package/src/retrieval/__pycache__/__init__.cpython-313.pyc +0 -0
  314. package/src/retrieval/__pycache__/__init__.cpython-314.pyc +0 -0
  315. package/src/retrieval/__pycache__/knowledge_graph.cpython-311.pyc +0 -0
  316. package/src/retrieval/__pycache__/knowledge_graph.cpython-313.pyc +0 -0
  317. package/src/retrieval/__pycache__/knowledge_graph.cpython-314.pyc +0 -0
  318. package/src/retrieval/__pycache__/retriever.cpython-311.pyc +0 -0
  319. package/src/retrieval/__pycache__/retriever.cpython-313.pyc +0 -0
  320. package/src/retrieval/__pycache__/retriever.cpython-314.pyc +0 -0
  321. package/src/retrieval/__pycache__/unified_query.cpython-313.pyc +0 -0
  322. package/src/retrieval/__pycache__/unified_query.cpython-314.pyc +0 -0
  323. package/{knowledge_base → src}/retrieval/context_fusion.py +3 -3
  324. package/{knowledge_base → src}/retrieval/knowledge_graph.py +4 -4
  325. package/{knowledge_base → src}/retrieval/reranker.py +2 -2
  326. package/{knowledge_base → src}/retrieval/retriever.py +11 -11
  327. package/{knowledge_base → src}/retrieval/unified_query.py +7 -7
  328. package/{knowledge_base → src}/retrieval/web_retriever.py +6 -6
  329. package/{knowledge_base → src}/validators/step_fidelity.py +1 -1
  330. package/src/vision/__init__.py +0 -0
  331. package/{knowledge_base → src}/vision/image_describer.py +1 -1
  332. package/knowledge_base/__pycache__/__init__.cpython-314.pyc +0 -0
  333. package/knowledge_base/agents/__init__.py +0 -6
  334. package/knowledge_base/agents/confidence_agent.py +0 -94
  335. package/knowledge_base/agents/feedback_agent.py +0 -56
  336. package/knowledge_base/agents/intent_agent.py +0 -76
  337. package/knowledge_base/agents/requirement_agent.py +0 -71
  338. package/knowledge_base/agents/testcase_agent.py +0 -111
  339. package/knowledge_base/agents/workflow_engine.py +0 -87
  340. package/knowledge_base/cli/generate_qcapps134.py +0 -391
  341. package/knowledge_base/cli/workflow_cli.py +0 -93
  342. package/knowledge_base/config/.env +0 -100
  343. package/knowledge_base/config/.env.example +0 -75
  344. package/knowledge_base/connectors/bitbucket_connector.py +0 -25
  345. package/knowledge_base/db/__pycache__/__init__.cpython-314.pyc +0 -0
  346. package/knowledge_base/db/__pycache__/client.cpython-314.pyc +0 -0
  347. package/knowledge_base/db/migrations.py +0 -22
  348. package/knowledge_base/embeddings/__pycache__/__init__.cpython-314.pyc +0 -0
  349. package/knowledge_base/ingestion/ingest.py +0 -346
  350. package/knowledge_base/ingestion/ingest_images.py +0 -330
  351. package/knowledge_base/memory/__init__.py +0 -6
  352. package/knowledge_base/memory/ingest_memory.py +0 -60
  353. /package/{knowledge_base → src}/__init__.py +0 -0
  354. /package/{knowledge_base → src}/__pycache__/__init__.cpython-37.pyc +0 -0
  355. /package/{knowledge_base → src}/__pycache__/__init__.cpython-38.pyc +0 -0
  356. /package/{knowledge_base → src}/__pycache__/confidence.cpython-37.pyc +0 -0
  357. /package/{knowledge_base → src}/__pycache__/config.cpython-314.pyc +0 -0
  358. /package/{knowledge_base → src}/__pycache__/config.cpython-37.pyc +0 -0
  359. /package/{knowledge_base → src}/__pycache__/config.cpython-38.pyc +0 -0
  360. /package/{knowledge_base → src}/__pycache__/context_fusion.cpython-314.pyc +0 -0
  361. /package/{knowledge_base → src}/__pycache__/context_fusion.cpython-37.pyc +0 -0
  362. /package/{knowledge_base → src}/__pycache__/feedback_analytics.cpython-37.pyc +0 -0
  363. /package/{knowledge_base → src}/__pycache__/feedback_applier.cpython-37.pyc +0 -0
  364. /package/{knowledge_base → src}/__pycache__/feedback_cli.cpython-37.pyc +0 -0
  365. /package/{knowledge_base → src}/__pycache__/feedback_curator.cpython-37.pyc +0 -0
  366. /package/{knowledge_base → src}/__pycache__/feedback_handler.cpython-37.pyc +0 -0
  367. /package/{knowledge_base → src}/__pycache__/generate.cpython-37.pyc +0 -0
  368. /package/{knowledge_base → src}/__pycache__/generate_qcapps134.cpython-37.pyc +0 -0
  369. /package/{knowledge_base → src}/__pycache__/input_classifier.cpython-314.pyc +0 -0
  370. /package/{knowledge_base → src}/__pycache__/input_classifier.cpython-37.pyc +0 -0
  371. /package/{knowledge_base → src}/__pycache__/kg_extractor.cpython-37.pyc +0 -0
  372. /package/{knowledge_base → src}/__pycache__/knowledge_graph.cpython-314.pyc +0 -0
  373. /package/{knowledge_base → src}/__pycache__/knowledge_graph.cpython-37.pyc +0 -0
  374. /package/{knowledge_base → src}/__pycache__/manual_tc_parser.cpython-314.pyc +0 -0
  375. /package/{knowledge_base → src}/__pycache__/manual_tc_parser.cpython-37.pyc +0 -0
  376. /package/{knowledge_base → src}/__pycache__/precedence.cpython-37.pyc +0 -0
  377. /package/{knowledge_base → src}/__pycache__/prompts.cpython-314.pyc +0 -0
  378. /package/{knowledge_base → src}/__pycache__/prompts.cpython-37.pyc +0 -0
  379. /package/{knowledge_base → src}/__pycache__/reranker.cpython-314.pyc +0 -0
  380. /package/{knowledge_base → src}/__pycache__/reranker.cpython-37.pyc +0 -0
  381. /package/{knowledge_base → src}/__pycache__/retrieval_debug.cpython-314.pyc +0 -0
  382. /package/{knowledge_base → src}/__pycache__/retrieval_debug.cpython-37.pyc +0 -0
  383. /package/{knowledge_base → src}/__pycache__/retriever.cpython-314.pyc +0 -0
  384. /package/{knowledge_base → src}/__pycache__/retriever.cpython-37.pyc +0 -0
  385. /package/{knowledge_base → src}/__pycache__/server.cpython-37.pyc +0 -0
  386. /package/{knowledge_base → src}/__pycache__/tc_transformer.cpython-314.pyc +0 -0
  387. /package/{knowledge_base → src}/__pycache__/tc_transformer.cpython-37.pyc +0 -0
  388. /package/{knowledge_base → src}/__pycache__/test_generator.cpython-314.pyc +0 -0
  389. /package/{knowledge_base → src}/__pycache__/test_generator.cpython-37.pyc +0 -0
  390. /package/{knowledge_base → src}/agents/__pycache__/__init__.cpython-37.pyc +0 -0
  391. /package/{knowledge_base → src}/agents/__pycache__/__init__.cpython-38.pyc +0 -0
  392. /package/{knowledge_base → src}/agents/__pycache__/fusion_agent.cpython-37.pyc +0 -0
  393. /package/{knowledge_base → src}/agents/__pycache__/fusion_agent.cpython-38.pyc +0 -0
  394. /package/{knowledge_base → src}/agents/__pycache__/graph.cpython-37.pyc +0 -0
  395. /package/{knowledge_base → src}/agents/__pycache__/graph.cpython-38.pyc +0 -0
  396. /package/{knowledge_base → src}/agents/__pycache__/healing_agent.cpython-37.pyc +0 -0
  397. /package/{knowledge_base → src}/agents/__pycache__/intent_agent.cpython-37.pyc +0 -0
  398. /package/{knowledge_base → src}/agents/__pycache__/intent_agent.cpython-38.pyc +0 -0
  399. /package/{knowledge_base → src}/agents/__pycache__/kg_agent.cpython-37.pyc +0 -0
  400. /package/{knowledge_base → src}/agents/__pycache__/kg_agent.cpython-38.pyc +0 -0
  401. /package/{knowledge_base → src}/agents/__pycache__/memory_agent.cpython-37.pyc +0 -0
  402. /package/{knowledge_base → src}/agents/__pycache__/memory_agent.cpython-38.pyc +0 -0
  403. /package/{knowledge_base → src}/agents/__pycache__/rca_agent.cpython-37.pyc +0 -0
  404. /package/{knowledge_base → src}/agents/__pycache__/reflection_agent.cpython-37.pyc +0 -0
  405. /package/{knowledge_base → src}/agents/__pycache__/reflection_agent.cpython-38.pyc +0 -0
  406. /package/{knowledge_base → src}/agents/__pycache__/regression_agent.cpython-37.pyc +0 -0
  407. /package/{knowledge_base → src}/agents/__pycache__/retrieval_agent.cpython-37.pyc +0 -0
  408. /package/{knowledge_base → src}/agents/__pycache__/retrieval_agent.cpython-38.pyc +0 -0
  409. /package/{knowledge_base → src}/agents/__pycache__/script_agent.cpython-37.pyc +0 -0
  410. /package/{knowledge_base → src}/agents/__pycache__/script_agent.cpython-38.pyc +0 -0
  411. /package/{knowledge_base → src}/agents/__pycache__/state.cpython-37.pyc +0 -0
  412. /package/{knowledge_base → src}/agents/__pycache__/state.cpython-38.pyc +0 -0
  413. /package/{knowledge_base → src}/agents/__pycache__/temporal_agent.cpython-37.pyc +0 -0
  414. /package/{knowledge_base → src}/agents/__pycache__/temporal_agent.cpython-38.pyc +0 -0
  415. /package/{knowledge_base → src}/agents/__pycache__/validation_agent.cpython-37.pyc +0 -0
  416. /package/{knowledge_base → src}/agents/__pycache__/validation_agent.cpython-38.pyc +0 -0
  417. /package/{knowledge_base → src}/agents/state.py +0 -0
  418. /package/{knowledge_base → src}/alembic/__pycache__/env.cpython-37.pyc +0 -0
  419. /package/{knowledge_base → src}/alembic/__pycache__/env.cpython-38.pyc +0 -0
  420. /package/{knowledge_base → src}/alembic/versions/.gitkeep +0 -0
  421. /package/{knowledge_base → src}/alembic/versions/001_phase0_feedback.py +0 -0
  422. /package/{knowledge_base → src}/alembic/versions/002_feedback_promotions.py +0 -0
  423. /package/{knowledge_base → src}/alembic/versions/003_enterprise_hardening.py +0 -0
  424. /package/{knowledge_base → src}/alembic/versions/__pycache__/001_phase0_feedback.cpython-37.pyc +0 -0
  425. /package/{knowledge_base → src}/alembic/versions/__pycache__/001_phase0_feedback.cpython-38.pyc +0 -0
  426. /package/{knowledge_base → src}/alembic/versions/__pycache__/002_feedback_promotions.cpython-37.pyc +0 -0
  427. /package/{knowledge_base → src}/alembic/versions/__pycache__/002_feedback_promotions.cpython-38.pyc +0 -0
  428. /package/{knowledge_base → src}/api/__init__.py +0 -0
  429. /package/{knowledge_base → src}/api/__pycache__/__init__.cpython-37.pyc +0 -0
  430. /package/{knowledge_base → src}/api/__pycache__/__init__.cpython-38.pyc +0 -0
  431. /package/{knowledge_base → src}/api/__pycache__/middleware.cpython-38.pyc +0 -0
  432. /package/{knowledge_base → src}/api/__pycache__/server.cpython-37.pyc +0 -0
  433. /package/{knowledge_base → src}/api/__pycache__/server.cpython-38.pyc +0 -0
  434. /package/{knowledge_base → src}/chunking/__init__.py +0 -0
  435. /package/{knowledge_base → src}/chunking/__pycache__/__init__.cpython-37.pyc +0 -0
  436. /package/{knowledge_base → src}/chunking/__pycache__/__init__.cpython-38.pyc +0 -0
  437. /package/{knowledge_base → src}/chunking/__pycache__/chunker.cpython-37.pyc +0 -0
  438. /package/{knowledge_base → src}/chunking/__pycache__/chunker.cpython-38.pyc +0 -0
  439. /package/{knowledge_base → src}/chunking/__pycache__/validators.cpython-37.pyc +0 -0
  440. /package/{knowledge_base → src}/chunking/__pycache__/validators.cpython-38.pyc +0 -0
  441. /package/{knowledge_base → src}/chunking/validators.py +0 -0
  442. /package/{knowledge_base → src}/cli/__init__.py +0 -0
  443. /package/{knowledge_base → src}/cli/__pycache__/__init__.cpython-37.pyc +0 -0
  444. /package/{knowledge_base → src}/cli/__pycache__/__init__.cpython-38.pyc +0 -0
  445. /package/{knowledge_base → src}/cli/__pycache__/feedback_cli.cpython-37.pyc +0 -0
  446. /package/{knowledge_base → src}/cli/__pycache__/feedback_cli.cpython-38.pyc +0 -0
  447. /package/{knowledge_base → src}/cli/__pycache__/generate.cpython-37.pyc +0 -0
  448. /package/{knowledge_base → src}/cli/__pycache__/generate.cpython-38.pyc +0 -0
  449. /package/{knowledge_base → src}/cli/__pycache__/generate_qcapps134.cpython-37.pyc +0 -0
  450. /package/{knowledge_base → src}/config/__pycache__/__init__.cpython-37.pyc +0 -0
  451. /package/{knowledge_base → src}/config/__pycache__/__init__.cpython-38.pyc +0 -0
  452. /package/{knowledge_base → src}/config/__pycache__/settings.cpython-37.pyc +0 -0
  453. /package/{knowledge_base → src}/config/__pycache__/settings.cpython-38.pyc +0 -0
  454. /package/{knowledge_base → src}/connectors/__pycache__/__init__.cpython-37.pyc +0 -0
  455. /package/{knowledge_base → src}/connectors/__pycache__/__init__.cpython-38.pyc +0 -0
  456. /package/{knowledge_base → src}/connectors/__pycache__/base.cpython-37.pyc +0 -0
  457. /package/{knowledge_base → src}/connectors/__pycache__/base.cpython-38.pyc +0 -0
  458. /package/{knowledge_base → src}/connectors/__pycache__/bitbucket_connector.cpython-37.pyc +0 -0
  459. /package/{knowledge_base → src}/connectors/__pycache__/bitbucket_connector.cpython-38.pyc +0 -0
  460. /package/{knowledge_base → src}/connectors/__pycache__/community_connector.cpython-38.pyc +0 -0
  461. /package/{knowledge_base → src}/connectors/__pycache__/confluence_connector.cpython-37.pyc +0 -0
  462. /package/{knowledge_base → src}/connectors/__pycache__/confluence_connector.cpython-38.pyc +0 -0
  463. /package/{knowledge_base → src}/connectors/__pycache__/jira_connector.cpython-37.pyc +0 -0
  464. /package/{knowledge_base → src}/connectors/__pycache__/jira_connector.cpython-38.pyc +0 -0
  465. /package/{knowledge_base → src}/connectors/__pycache__/kb_igel_connector.cpython-38.pyc +0 -0
  466. /package/{knowledge_base → src}/connectors/__pycache__/playwright_fetcher.cpython-38.pyc +0 -0
  467. /package/{knowledge_base → src}/connectors/__pycache__/query_bridge.cpython-38.pyc +0 -0
  468. /package/{knowledge_base → src}/connectors/__pycache__/search_backends.cpython-38.pyc +0 -0
  469. /package/{knowledge_base → src}/connectors/__pycache__/serviceNow_connector.cpython-37.pyc +0 -0
  470. /package/{knowledge_base → src}/connectors/__pycache__/serviceNow_connector.cpython-38.pyc +0 -0
  471. /package/{knowledge_base → src}/connectors/__pycache__/sync_scheduler.cpython-37.pyc +0 -0
  472. /package/{knowledge_base → src}/connectors/__pycache__/sync_scheduler.cpython-38.pyc +0 -0
  473. /package/{knowledge_base → src}/connectors/__pycache__/teamcity_connector.cpython-37.pyc +0 -0
  474. /package/{knowledge_base → src}/connectors/__pycache__/teamcity_connector.cpython-38.pyc +0 -0
  475. /package/{knowledge_base → src}/connectors/__pycache__/testRail_connector.cpython-37.pyc +0 -0
  476. /package/{knowledge_base → src}/connectors/__pycache__/testRail_connector.cpython-38.pyc +0 -0
  477. /package/{knowledge_base → src}/connectors/__pycache__/web_fetcher.cpython-38.pyc +0 -0
  478. /package/{knowledge_base → src}/connectors/base.py +0 -0
  479. /package/{knowledge_base → src}/connectors/playwright_fetcher.py +0 -0
  480. /package/{knowledge_base → src}/core/__pycache__/__init__.cpython-37.pyc +0 -0
  481. /package/{knowledge_base → src}/core/__pycache__/__init__.cpython-38.pyc +0 -0
  482. /package/{knowledge_base → src}/core/__pycache__/cache.cpython-38.pyc +0 -0
  483. /package/{knowledge_base → src}/core/__pycache__/circuit_breaker.cpython-38.pyc +0 -0
  484. /package/{knowledge_base → src}/core/__pycache__/confidence.cpython-37.pyc +0 -0
  485. /package/{knowledge_base → src}/core/__pycache__/confidence.cpython-38.pyc +0 -0
  486. /package/{knowledge_base → src}/core/__pycache__/logging_setup.cpython-38.pyc +0 -0
  487. /package/{knowledge_base → src}/core/__pycache__/metrics.cpython-38.pyc +0 -0
  488. /package/{knowledge_base → src}/core/__pycache__/precedence.cpython-37.pyc +0 -0
  489. /package/{knowledge_base → src}/core/__pycache__/precedence.cpython-38.pyc +0 -0
  490. /package/{knowledge_base → src}/core/__pycache__/request_context.cpython-38.pyc +0 -0
  491. /package/{knowledge_base → src}/core/circuit_breaker.py +0 -0
  492. /package/{knowledge_base → src}/core/metrics.py +0 -0
  493. /package/{knowledge_base → src}/core/precedence.py +0 -0
  494. /package/{knowledge_base → src}/core/request_context.py +0 -0
  495. /package/{knowledge_base → src}/db/__init__.py +0 -0
  496. /package/{knowledge_base → src}/db/__pycache__/__init__.cpython-37.pyc +0 -0
  497. /package/{knowledge_base → src}/db/__pycache__/__init__.cpython-38.pyc +0 -0
  498. /package/{knowledge_base → src}/db/__pycache__/client.cpython-37.pyc +0 -0
  499. /package/{knowledge_base → src}/db/__pycache__/client.cpython-38.pyc +0 -0
  500. /package/{knowledge_base → src}/db/__pycache__/connector_sync.cpython-38.pyc +0 -0
  501. /package/{knowledge_base → src}/db/__pycache__/feedback_schema.cpython-37.pyc +0 -0
  502. /package/{knowledge_base → src}/db/__pycache__/feedback_schema.cpython-38.pyc +0 -0
  503. /package/{knowledge_base → src}/db/__pycache__/kg_introspect.cpython-37.pyc +0 -0
  504. /package/{knowledge_base → src}/db/__pycache__/kg_introspect.cpython-38.pyc +0 -0
  505. /package/{knowledge_base → src}/db/__pycache__/schema.cpython-37.pyc +0 -0
  506. /package/{knowledge_base → src}/db/__pycache__/schema.cpython-38.pyc +0 -0
  507. /package/{knowledge_base → src}/embeddings/__init__.py +0 -0
  508. /package/{knowledge_base → src}/embeddings/__pycache__/__init__.cpython-37.pyc +0 -0
  509. /package/{knowledge_base → src}/embeddings/__pycache__/__init__.cpython-38.pyc +0 -0
  510. /package/{knowledge_base → src}/embeddings/__pycache__/azure_embedder.cpython-37.pyc +0 -0
  511. /package/{knowledge_base → src}/embeddings/__pycache__/azure_embedder.cpython-38.pyc +0 -0
  512. /package/{knowledge_base → src}/eval/__pycache__/__init__.cpython-37.pyc +0 -0
  513. /package/{knowledge_base → src}/eval/__pycache__/__init__.cpython-38.pyc +0 -0
  514. /package/{knowledge_base → src}/eval/__pycache__/__main__.cpython-37.pyc +0 -0
  515. /package/{knowledge_base → src}/eval/__pycache__/baseline.cpython-37.pyc +0 -0
  516. /package/{knowledge_base → src}/eval/__pycache__/baseline.cpython-38.pyc +0 -0
  517. /package/{knowledge_base → src}/eval/__pycache__/harness.cpython-37.pyc +0 -0
  518. /package/{knowledge_base → src}/eval/__pycache__/harness.cpython-38.pyc +0 -0
  519. /package/{knowledge_base → src}/eval/__pycache__/scorers.cpython-37.pyc +0 -0
  520. /package/{knowledge_base → src}/eval/__pycache__/scorers.cpython-38.pyc +0 -0
  521. /package/{knowledge_base → src}/eval/baseline.py +0 -0
  522. /package/{knowledge_base → src}/eval/queries_50.json +0 -0
  523. /package/{knowledge_base → src}/eval/scorers.py +0 -0
  524. /package/{knowledge_base → src}/exemplars/README.md +0 -0
  525. /package/{knowledge_base → src}/exemplars/__pycache__/pytest_reference_snippet.cpython-37.pyc +0 -0
  526. /package/{knowledge_base → src}/exemplars/gold_manual_concise_snippet.md +0 -0
  527. /package/{knowledge_base → src}/exemplars/gold_manual_detailed_snippet.md +0 -0
  528. /package/{knowledge_base → src}/exemplars/pytest_reference_snippet.py +0 -0
  529. /package/{knowledge_base → src}/feedback/__pycache__/__init__.cpython-37.pyc +0 -0
  530. /package/{knowledge_base → src}/feedback/__pycache__/__init__.cpython-38.pyc +0 -0
  531. /package/{knowledge_base → src}/feedback/__pycache__/analytics.cpython-37.pyc +0 -0
  532. /package/{knowledge_base → src}/feedback/__pycache__/analytics.cpython-38.pyc +0 -0
  533. /package/{knowledge_base → src}/feedback/__pycache__/applier.cpython-37.pyc +0 -0
  534. /package/{knowledge_base → src}/feedback/__pycache__/applier.cpython-38.pyc +0 -0
  535. /package/{knowledge_base → src}/feedback/__pycache__/curator.cpython-37.pyc +0 -0
  536. /package/{knowledge_base → src}/feedback/__pycache__/curator.cpython-38.pyc +0 -0
  537. /package/{knowledge_base → src}/feedback/__pycache__/handler.cpython-37.pyc +0 -0
  538. /package/{knowledge_base → src}/feedback/__pycache__/handler.cpython-38.pyc +0 -0
  539. /package/{knowledge_base → src}/generation/__init__.py +0 -0
  540. /package/{knowledge_base → src}/generation/__pycache__/__init__.cpython-37.pyc +0 -0
  541. /package/{knowledge_base → src}/generation/__pycache__/__init__.cpython-38.pyc +0 -0
  542. /package/{knowledge_base → src}/generation/__pycache__/input_classifier.cpython-37.pyc +0 -0
  543. /package/{knowledge_base → src}/generation/__pycache__/input_classifier.cpython-38.pyc +0 -0
  544. /package/{knowledge_base → src}/generation/__pycache__/manual_tc_parser.cpython-37.pyc +0 -0
  545. /package/{knowledge_base → src}/generation/__pycache__/manual_tc_parser.cpython-38.pyc +0 -0
  546. /package/{knowledge_base → src}/generation/__pycache__/prompts.cpython-37.pyc +0 -0
  547. /package/{knowledge_base → src}/generation/__pycache__/prompts.cpython-38.pyc +0 -0
  548. /package/{knowledge_base → src}/generation/__pycache__/tc_transformer.cpython-37.pyc +0 -0
  549. /package/{knowledge_base → src}/generation/__pycache__/test_generator.cpython-37.pyc +0 -0
  550. /package/{knowledge_base → src}/generation/__pycache__/test_generator.cpython-38.pyc +0 -0
  551. /package/{knowledge_base → src}/generation/manual_tc_parser.py +0 -0
  552. /package/{knowledge_base → src}/graph_db/__pycache__/__init__.cpython-37.pyc +0 -0
  553. /package/{knowledge_base → src}/graph_db/__pycache__/__init__.cpython-38.pyc +0 -0
  554. /package/{knowledge_base → src}/graph_db/__pycache__/graphiti_client.cpython-37.pyc +0 -0
  555. /package/{knowledge_base → src}/graph_db/__pycache__/kg_traversal.cpython-37.pyc +0 -0
  556. /package/{knowledge_base → src}/graph_db/__pycache__/migrate_kg.cpython-37.pyc +0 -0
  557. /package/{knowledge_base → src}/graph_db/__pycache__/neo4j_client.cpython-37.pyc +0 -0
  558. /package/{knowledge_base → src}/graph_db/__pycache__/neo4j_client.cpython-38.pyc +0 -0
  559. /package/{knowledge_base → src}/graph_db/__pycache__/schema.cpython-37.pyc +0 -0
  560. /package/{knowledge_base → src}/graph_db/__pycache__/temporal_ingest.cpython-37.pyc +0 -0
  561. /package/{knowledge_base → src}/graph_db/schema.py +0 -0
  562. /package/{knowledge_base → src}/ingestion/__init__.py +0 -0
  563. /package/{knowledge_base → src}/ingestion/__pycache__/__init__.cpython-37.pyc +0 -0
  564. /package/{knowledge_base → src}/ingestion/__pycache__/__init__.cpython-38.pyc +0 -0
  565. /package/{knowledge_base → src}/ingestion/__pycache__/ingest.cpython-37.pyc +0 -0
  566. /package/{knowledge_base → src}/ingestion/__pycache__/ingest.cpython-38.pyc +0 -0
  567. /package/{knowledge_base → src}/ingestion/__pycache__/ingest_images.cpython-37.pyc +0 -0
  568. /package/{knowledge_base → src}/ingestion/__pycache__/ingest_images.cpython-38.pyc +0 -0
  569. /package/{knowledge_base → src}/ingestion/__pycache__/kg_extractor.cpython-37.pyc +0 -0
  570. /package/{knowledge_base → src}/ingestion/__pycache__/kg_extractor.cpython-38.pyc +0 -0
  571. /package/{knowledge_base → src}/ingestion/__pycache__/web_ingest.cpython-38.pyc +0 -0
  572. /package/{knowledge_base → src}/intelligence/__init__.py +0 -0
  573. /package/{knowledge_base → src}/intelligence/__pycache__/__init__.cpython-37.pyc +0 -0
  574. /package/{knowledge_base → src}/intelligence/__pycache__/execution_ingest.cpython-37.pyc +0 -0
  575. /package/{knowledge_base → src}/intelligence/__pycache__/predictive_engine.cpython-37.pyc +0 -0
  576. /package/{knowledge_base → src}/intelligence/__pycache__/risk_scorer.cpython-37.pyc +0 -0
  577. /package/{knowledge_base → src}/intelligence/predictive_engine.py +0 -0
  578. /package/{knowledge_base → src}/intelligence/risk_scorer.py +0 -0
  579. /package/{knowledge_base → src}/memory/__pycache__/__init__.cpython-37.pyc +0 -0
  580. /package/{knowledge_base → src}/memory/__pycache__/__init__.cpython-38.pyc +0 -0
  581. /package/{knowledge_base → src}/memory/__pycache__/cognee_client.cpython-37.pyc +0 -0
  582. /package/{knowledge_base → src}/memory/__pycache__/cognee_client.cpython-38.pyc +0 -0
  583. /package/{knowledge_base → src}/memory/__pycache__/ingest_memory.cpython-37.pyc +0 -0
  584. /package/{knowledge_base → src}/memory/__pycache__/memory_types.cpython-37.pyc +0 -0
  585. /package/{knowledge_base → src}/memory/__pycache__/memory_types.cpython-38.pyc +0 -0
  586. /package/{knowledge_base → src}/memory/memory_types.py +0 -0
  587. /package/{knowledge_base → src}/parsers/__init__.py +0 -0
  588. /package/{knowledge_base → src}/parsers/__pycache__/__init__.cpython-37.pyc +0 -0
  589. /package/{knowledge_base → src}/parsers/__pycache__/__init__.cpython-38.pyc +0 -0
  590. /package/{knowledge_base → src}/parsers/__pycache__/csv_parser.cpython-37.pyc +0 -0
  591. /package/{knowledge_base → src}/parsers/__pycache__/csv_parser.cpython-38.pyc +0 -0
  592. /package/{knowledge_base → src}/parsers/__pycache__/doc_parser.cpython-37.pyc +0 -0
  593. /package/{knowledge_base → src}/parsers/__pycache__/doc_parser.cpython-38.pyc +0 -0
  594. /package/{knowledge_base → src}/parsers/__pycache__/html_parser.cpython-38.pyc +0 -0
  595. /package/{knowledge_base → src}/parsers/__pycache__/image_extractor.cpython-37.pyc +0 -0
  596. /package/{knowledge_base → src}/parsers/__pycache__/image_extractor.cpython-38.pyc +0 -0
  597. /package/{knowledge_base → src}/parsers/__pycache__/markdown_parser.cpython-37.pyc +0 -0
  598. /package/{knowledge_base → src}/parsers/__pycache__/markdown_parser.cpython-38.pyc +0 -0
  599. /package/{knowledge_base → src}/parsers/__pycache__/pdf_parser.cpython-37.pyc +0 -0
  600. /package/{knowledge_base → src}/parsers/__pycache__/pdf_parser.cpython-38.pyc +0 -0
  601. /package/{knowledge_base → src}/parsers/image_extractor.py +0 -0
  602. /package/{knowledge_base → src}/parsers/markdown_parser.py +0 -0
  603. /package/{knowledge_base/vision → src/project}/__init__.py +0 -0
  604. /package/{knowledge_base → src}/retrieval/__init__.py +0 -0
  605. /package/{knowledge_base → src}/retrieval/__pycache__/__init__.cpython-37.pyc +0 -0
  606. /package/{knowledge_base → src}/retrieval/__pycache__/__init__.cpython-38.pyc +0 -0
  607. /package/{knowledge_base → src}/retrieval/__pycache__/context_fusion.cpython-37.pyc +0 -0
  608. /package/{knowledge_base → src}/retrieval/__pycache__/context_fusion.cpython-38.pyc +0 -0
  609. /package/{knowledge_base → src}/retrieval/__pycache__/knowledge_graph.cpython-37.pyc +0 -0
  610. /package/{knowledge_base → src}/retrieval/__pycache__/knowledge_graph.cpython-38.pyc +0 -0
  611. /package/{knowledge_base → src}/retrieval/__pycache__/reranker.cpython-37.pyc +0 -0
  612. /package/{knowledge_base → src}/retrieval/__pycache__/reranker.cpython-38.pyc +0 -0
  613. /package/{knowledge_base → src}/retrieval/__pycache__/retrieval_debug.cpython-37.pyc +0 -0
  614. /package/{knowledge_base → src}/retrieval/__pycache__/retrieval_debug.cpython-38.pyc +0 -0
  615. /package/{knowledge_base → src}/retrieval/__pycache__/retriever.cpython-37.pyc +0 -0
  616. /package/{knowledge_base → src}/retrieval/__pycache__/retriever.cpython-38.pyc +0 -0
  617. /package/{knowledge_base → src}/retrieval/__pycache__/unified_query.cpython-38.pyc +0 -0
  618. /package/{knowledge_base → src}/retrieval/__pycache__/web_retriever.cpython-38.pyc +0 -0
  619. /package/{knowledge_base → src}/retrieval/retrieval_debug.py +0 -0
  620. /package/{knowledge_base → src}/validators/__init__.py +0 -0
  621. /package/{knowledge_base → src}/validators/__pycache__/__init__.cpython-314.pyc +0 -0
  622. /package/{knowledge_base → src}/validators/__pycache__/__init__.cpython-37.pyc +0 -0
  623. /package/{knowledge_base → src}/validators/__pycache__/step_fidelity.cpython-314.pyc +0 -0
  624. /package/{knowledge_base → src}/validators/__pycache__/step_fidelity.cpython-37.pyc +0 -0
  625. /package/{knowledge_base → src}/vision/__pycache__/__init__.cpython-37.pyc +0 -0
  626. /package/{knowledge_base → src}/vision/__pycache__/__init__.cpython-38.pyc +0 -0
  627. /package/{knowledge_base → src}/vision/__pycache__/image_describer.cpython-37.pyc +0 -0
  628. /package/{knowledge_base → src}/vision/__pycache__/image_describer.cpython-38.pyc +0 -0
@@ -0,0 +1,333 @@
1
+ """Framework context enrichment with AST + dependency graph persistence.
2
+
3
+ This module enriches scaffolded context.md files by:
4
+ 1) Inspecting folder-local code/doc assets
5
+ 2) Building a lightweight dependency graph from Python AST imports
6
+ 3) Writing human and LLM-friendly markdown content to context.md
7
+ 4) Persisting/updating context metadata in PostgreSQL
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import ast
12
+ import hashlib
13
+ import json
14
+ from dataclasses import dataclass
15
+ from pathlib import Path
16
+
17
+ from src.db.client import get_transaction
18
+
19
+
20
+ EXCLUDED_DIRS = {
21
+ "node_modules",
22
+ ".git",
23
+ ".github",
24
+ ".vscode",
25
+ ".venv",
26
+ "__pycache__",
27
+ "dist",
28
+ "build",
29
+ ".idea",
30
+ ".pytest_cache",
31
+ ".mypy_cache",
32
+ ".ai",
33
+ }
34
+
35
+
36
+ @dataclass
37
+ class ContextEnrichResult:
38
+ path: str
39
+ folder: str
40
+ files_scanned: int
41
+ python_files: int
42
+ dependency_edges: int
43
+ key_assets: list[str]
44
+
45
+
46
+ def _norm_rel(repo_root: Path, path: Path) -> str:
47
+ return str(path.resolve().relative_to(repo_root.resolve()).as_posix())
48
+
49
+
50
+ def _folder_label(repo_root: Path, folder: Path) -> str:
51
+ rel = _norm_rel(repo_root, folder)
52
+ return "." if rel == "." else rel
53
+
54
+
55
+ def _iter_context_files(repo_root: Path, context_paths: list[str] | None) -> list[Path]:
56
+ if context_paths:
57
+ files: list[Path] = []
58
+ for p in context_paths:
59
+ c = Path(p)
60
+ full = c if c.is_absolute() else (repo_root / c)
61
+ if full.exists() and full.is_file() and full.name == "context.md":
62
+ files.append(full.resolve())
63
+ return sorted(set(files))
64
+
65
+ found: list[Path] = []
66
+ for p in repo_root.rglob("context.md"):
67
+ rel_parts = p.relative_to(repo_root).parts
68
+ if any(part in EXCLUDED_DIRS or part.startswith(".") for part in rel_parts[:-1]):
69
+ continue
70
+ found.append(p.resolve())
71
+ return sorted(set(found))
72
+
73
+
74
+ def _iter_folder_files(folder: Path) -> list[Path]:
75
+ files: list[Path] = []
76
+ for child in folder.iterdir():
77
+ if child.is_file() and child.name != "context.md":
78
+ files.append(child)
79
+ return sorted(files)
80
+
81
+
82
+ def _extract_imports(py_file: Path) -> set[str]:
83
+ try:
84
+ text = py_file.read_text(encoding="utf-8", errors="ignore")
85
+ tree = ast.parse(text)
86
+ except Exception:
87
+ return set()
88
+
89
+ imports: set[str] = set()
90
+ for node in ast.walk(tree):
91
+ if isinstance(node, ast.Import):
92
+ for alias in node.names:
93
+ imports.add(alias.name)
94
+ elif isinstance(node, ast.ImportFrom):
95
+ if node.module:
96
+ imports.add(node.module)
97
+ return imports
98
+
99
+
100
+ def _extract_assets(py_file: Path) -> list[str]:
101
+ assets: list[str] = []
102
+ try:
103
+ text = py_file.read_text(encoding="utf-8", errors="ignore")
104
+ tree = ast.parse(text)
105
+ except Exception:
106
+ return assets
107
+
108
+ for node in ast.walk(tree):
109
+ if isinstance(node, ast.ClassDef):
110
+ assets.append(f"class {node.name}")
111
+ elif isinstance(node, ast.FunctionDef):
112
+ assets.append(f"function {node.name}")
113
+ return assets
114
+
115
+
116
+ def _local_module_map(repo_root: Path, files: list[Path]) -> dict[str, str]:
117
+ module_map: dict[str, str] = {}
118
+ for f in files:
119
+ if f.suffix != ".py":
120
+ continue
121
+ rel = _norm_rel(repo_root, f)
122
+ mod = rel[:-3].replace("/", ".")
123
+ module_map[mod] = rel
124
+ return module_map
125
+
126
+
127
+ def _build_dependency_graph(repo_root: Path, files: list[Path]) -> tuple[list[dict], int]:
128
+ module_map = _local_module_map(repo_root, files)
129
+ edges: list[dict] = []
130
+
131
+ for f in files:
132
+ if f.suffix != ".py":
133
+ continue
134
+ src = _norm_rel(repo_root, f)
135
+ for imp in sorted(_extract_imports(f)):
136
+ target = module_map.get(imp)
137
+ if target is None:
138
+ # Match nested imports: package.mod.sub -> package.mod
139
+ parts = imp.split(".")
140
+ while len(parts) > 1 and target is None:
141
+ parts = parts[:-1]
142
+ target = module_map.get(".".join(parts))
143
+ edges.append(
144
+ {
145
+ "source": src,
146
+ "import": imp,
147
+ "target": target,
148
+ "local": bool(target),
149
+ }
150
+ )
151
+
152
+ return edges, sum(1 for e in edges if e["local"])
153
+
154
+
155
+ def _render_context_markdown(
156
+ *,
157
+ repo_root: Path,
158
+ folder: Path,
159
+ files: list[Path],
160
+ python_files: list[Path],
161
+ assets: list[str],
162
+ dependency_edges: list[dict],
163
+ ) -> str:
164
+ folder_label = _folder_label(repo_root, folder)
165
+ rel_files = [_norm_rel(repo_root, f) for f in files]
166
+
167
+ key_assets = assets[:12]
168
+ file_preview = rel_files[:15]
169
+ local_edges = [e for e in dependency_edges if e["local"]][:15]
170
+
171
+ lines: list[str] = []
172
+ lines.append(f"# Context - {folder_label}")
173
+ lines.append("")
174
+ lines.append("## Purpose")
175
+ lines.append(
176
+ f"This folder owns automation assets for `{folder_label}` and is used by IGEL QE orchestration for both human review and LLM grounding."
177
+ )
178
+ lines.append("")
179
+ lines.append("## Folder Snapshot")
180
+ lines.append(f"- Total files (excluding context): {len(files)}")
181
+ lines.append(f"- Python files parsed with AST: {len(python_files)}")
182
+ lines.append(f"- Candidate key assets discovered: {len(assets)}")
183
+ lines.append("")
184
+ lines.append("## Key Assets")
185
+ if key_assets:
186
+ for item in key_assets:
187
+ lines.append(f"- {item}")
188
+ else:
189
+ lines.append("- No Python class/function assets detected in this folder yet.")
190
+ lines.append("")
191
+ lines.append("## Dependency Graph")
192
+ if local_edges:
193
+ for edge in local_edges:
194
+ lines.append(f"- {edge['source']} imports {edge['target']} (via `{edge['import']}`)")
195
+ else:
196
+ lines.append("- No local Python import edges detected from AST analysis.")
197
+ lines.append("")
198
+ lines.append("## File Inventory")
199
+ if file_preview:
200
+ for p in file_preview:
201
+ lines.append(f"- {p}")
202
+ else:
203
+ lines.append("- Folder currently has no files besides context.md.")
204
+ lines.append("")
205
+ lines.append("## Risks and Dependencies")
206
+ lines.append("- Keep import boundaries stable; changing module names can break downstream scripts.")
207
+ lines.append("- Update this context after adding new fixtures/page objects/utilities.")
208
+ lines.append("")
209
+
210
+ return "\n".join(lines)
211
+
212
+
213
+ def _table_exists(cur, table: str) -> bool:
214
+ cur.execute(
215
+ "SELECT 1 FROM information_schema.tables WHERE table_name = %s",
216
+ (table,),
217
+ )
218
+ return cur.fetchone() is not None
219
+
220
+
221
+ def _upsert_context_registry(
222
+ *,
223
+ repo_root: Path,
224
+ context_file: Path,
225
+ markdown: str,
226
+ files: list[Path],
227
+ python_files: list[Path],
228
+ assets: list[str],
229
+ dependency_edges: list[dict],
230
+ ) -> None:
231
+ with get_transaction() as conn:
232
+ with conn.cursor() as cur:
233
+ if not _table_exists(cur, "igel_context_registry"):
234
+ return
235
+
236
+ context_path = _norm_rel(repo_root, context_file)
237
+ folder_path = _norm_rel(repo_root, context_file.parent)
238
+ content_hash = hashlib.sha256(markdown.encode("utf-8")).hexdigest()
239
+
240
+ metadata = {
241
+ "files_scanned": len(files),
242
+ "python_files": len(python_files),
243
+ "dependency_edges": len(dependency_edges),
244
+ "local_dependency_edges": sum(1 for e in dependency_edges if e.get("local")),
245
+ }
246
+
247
+ cur.execute(
248
+ """
249
+ INSERT INTO igel_context_registry (
250
+ context_path,
251
+ folder_path,
252
+ content,
253
+ key_assets,
254
+ dependency_graph,
255
+ metadata,
256
+ source_hash,
257
+ updated_at
258
+ ) VALUES (%s, %s, %s, %s::jsonb, %s::jsonb, %s::jsonb, %s, NOW())
259
+ ON CONFLICT (context_path)
260
+ DO UPDATE SET
261
+ folder_path = EXCLUDED.folder_path,
262
+ content = EXCLUDED.content,
263
+ key_assets = EXCLUDED.key_assets,
264
+ dependency_graph = EXCLUDED.dependency_graph,
265
+ metadata = EXCLUDED.metadata,
266
+ source_hash = EXCLUDED.source_hash,
267
+ updated_at = NOW()
268
+ """,
269
+ (
270
+ context_path,
271
+ folder_path,
272
+ markdown,
273
+ json.dumps(assets[:30]),
274
+ json.dumps(dependency_edges[:200]),
275
+ json.dumps(metadata),
276
+ content_hash,
277
+ ),
278
+ )
279
+
280
+
281
+ def enrich_context_files(
282
+ repo_root: Path,
283
+ *,
284
+ context_paths: list[str] | None = None,
285
+ rewrite_files: bool = True,
286
+ ) -> list[ContextEnrichResult]:
287
+ """Enrich context.md files and persist context intelligence in Postgres."""
288
+ repo_root = repo_root.resolve()
289
+ results: list[ContextEnrichResult] = []
290
+
291
+ for context_file in _iter_context_files(repo_root, context_paths):
292
+ folder = context_file.parent
293
+ files = _iter_folder_files(folder)
294
+ python_files = [f for f in files if f.suffix == ".py"]
295
+ assets: list[str] = []
296
+ for py_file in python_files:
297
+ assets.extend(_extract_assets(py_file))
298
+
299
+ dependency_edges, local_edges_count = _build_dependency_graph(repo_root, python_files)
300
+
301
+ markdown = _render_context_markdown(
302
+ repo_root=repo_root,
303
+ folder=folder,
304
+ files=files,
305
+ python_files=python_files,
306
+ assets=assets,
307
+ dependency_edges=dependency_edges,
308
+ )
309
+ if rewrite_files:
310
+ context_file.write_text(markdown + "\n", encoding="utf-8")
311
+
312
+ _upsert_context_registry(
313
+ repo_root=repo_root,
314
+ context_file=context_file,
315
+ markdown=markdown,
316
+ files=files,
317
+ python_files=python_files,
318
+ assets=assets,
319
+ dependency_edges=dependency_edges,
320
+ )
321
+
322
+ results.append(
323
+ ContextEnrichResult(
324
+ path=_norm_rel(repo_root, context_file),
325
+ folder=_norm_rel(repo_root, folder),
326
+ files_scanned=len(files),
327
+ python_files=len(python_files),
328
+ dependency_edges=local_edges_count,
329
+ key_assets=assets[:10],
330
+ )
331
+ )
332
+
333
+ return results
@@ -0,0 +1,167 @@
1
+ """Build .ai/context.md as a registry-backed projection.
2
+
3
+ V2 intent: context.md is a human-readable cache generated from registries,
4
+ not a source of truth.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from dataclasses import dataclass
9
+ from pathlib import Path
10
+
11
+ from src.db.client import get_conn
12
+
13
+
14
+ @dataclass
15
+ class ProjectionStats:
16
+ requirements: int = 0
17
+ scenarios: int = 0
18
+ business_rules: int = 0
19
+ testcases: int = 0
20
+ scripts: int = 0
21
+ assets: int = 0
22
+
23
+
24
+ def _table_exists(cur, table: str) -> bool:
25
+ cur.execute(
26
+ "SELECT 1 FROM information_schema.tables WHERE table_name=%s",
27
+ (table,),
28
+ )
29
+ return cur.fetchone() is not None
30
+
31
+
32
+ def _count(cur, table: str) -> int:
33
+ cur.execute(f"SELECT COUNT(*) FROM {table}")
34
+ row = cur.fetchone()
35
+ return int(row[0]) if row else 0
36
+
37
+
38
+ class ContextProjectionBuilder:
39
+ def __init__(self, repo_root: Path):
40
+ self.repo_root = repo_root
41
+
42
+ def build(self) -> dict:
43
+ stats = ProjectionStats()
44
+ top_assets: list[tuple[str, int]] = []
45
+ top_rules: list[str] = []
46
+ recent_runs: list[tuple[str, str, float | None]] = []
47
+
48
+ with get_conn() as conn:
49
+ with conn.cursor() as cur:
50
+ if _table_exists(cur, "igel_requirements"):
51
+ stats.requirements = _count(cur, "igel_requirements")
52
+ if _table_exists(cur, "igel_scenarios"):
53
+ stats.scenarios = _count(cur, "igel_scenarios")
54
+ if _table_exists(cur, "igel_generated_testcases"):
55
+ stats.testcases = _count(cur, "igel_generated_testcases")
56
+ if _table_exists(cur, "igel_automation_scripts"):
57
+ stats.scripts = _count(cur, "igel_automation_scripts")
58
+ if _table_exists(cur, "igel_asset_registry"):
59
+ stats.assets = _count(cur, "igel_asset_registry")
60
+ cur.execute(
61
+ """
62
+ SELECT asset_type, COUNT(*) AS c
63
+ FROM igel_asset_registry
64
+ GROUP BY asset_type
65
+ ORDER BY c DESC
66
+ LIMIT 8
67
+ """
68
+ )
69
+ top_assets = [(str(r[0]), int(r[1])) for r in cur.fetchall()]
70
+
71
+ if _table_exists(cur, "igel_business_rule_registry"):
72
+ stats.business_rules = _count(cur, "igel_business_rule_registry")
73
+ cur.execute(
74
+ """
75
+ SELECT COALESCE(rule_key, id::text) AS key, rule_text
76
+ FROM igel_business_rule_registry
77
+ ORDER BY updated_at DESC NULLS LAST, created_at DESC
78
+ LIMIT 6
79
+ """
80
+ )
81
+ top_rules = [f"{r[0]}: {r[1][:140]}" for r in cur.fetchall()]
82
+ elif _table_exists(cur, "igel_business_rules"):
83
+ stats.business_rules = _count(cur, "igel_business_rules")
84
+ cur.execute(
85
+ "SELECT description FROM igel_business_rules ORDER BY created_at DESC LIMIT 6"
86
+ )
87
+ top_rules = [str(r[0])[:160] for r in cur.fetchall()]
88
+
89
+ if _table_exists(cur, "igel_generation_history"):
90
+ cur.execute(
91
+ """
92
+ SELECT COALESCE(jira_key, '-'), action, quality_score
93
+ FROM igel_generation_history
94
+ ORDER BY created_at DESC
95
+ LIMIT 10
96
+ """
97
+ )
98
+ recent_runs = [
99
+ (str(r[0]), str(r[1]), float(r[2]) if r[2] is not None else None)
100
+ for r in cur.fetchall()
101
+ ]
102
+
103
+ content = self._render(stats, top_assets, top_rules, recent_runs)
104
+ context_path = self.repo_root / ".ai" / "context.md"
105
+ context_path.parent.mkdir(parents=True, exist_ok=True)
106
+ context_path.write_text(content, encoding="utf-8")
107
+
108
+ return {
109
+ "context_path": str(context_path),
110
+ "stats": {
111
+ "requirements": stats.requirements,
112
+ "scenarios": stats.scenarios,
113
+ "business_rules": stats.business_rules,
114
+ "testcases": stats.testcases,
115
+ "scripts": stats.scripts,
116
+ "assets": stats.assets,
117
+ },
118
+ }
119
+
120
+ def _render(
121
+ self,
122
+ stats: ProjectionStats,
123
+ top_assets: list[tuple[str, int]],
124
+ top_rules: list[str],
125
+ recent_runs: list[tuple[str, str, float | None]],
126
+ ) -> str:
127
+ lines: list[str] = []
128
+ lines.append("# Project Context (Generated Projection)")
129
+ lines.append("")
130
+ lines.append("This file is generated from registries and execution memory.")
131
+ lines.append("Do not use it as source of truth for workflow decisions.")
132
+ lines.append("")
133
+ lines.append("## Registry Snapshot")
134
+ lines.append(f"- Requirements: {stats.requirements}")
135
+ lines.append(f"- Scenarios: {stats.scenarios}")
136
+ lines.append(f"- Business Rules: {stats.business_rules}")
137
+ lines.append(f"- Test Cases: {stats.testcases}")
138
+ lines.append(f"- Scripts: {stats.scripts}")
139
+ lines.append(f"- Assets: {stats.assets}")
140
+ lines.append("")
141
+
142
+ lines.append("## Asset Mix")
143
+ if top_assets:
144
+ for asset_type, count in top_assets:
145
+ lines.append(f"- {asset_type}: {count}")
146
+ else:
147
+ lines.append("- No asset data available")
148
+ lines.append("")
149
+
150
+ lines.append("## Recent Business Rules")
151
+ if top_rules:
152
+ for rule in top_rules:
153
+ lines.append(f"- {rule}")
154
+ else:
155
+ lines.append("- No business rules available")
156
+ lines.append("")
157
+
158
+ lines.append("## Recent Generation Runs")
159
+ if recent_runs:
160
+ for jira_key, action, quality in recent_runs:
161
+ q = "n/a" if quality is None else f"{quality:.3f}"
162
+ lines.append(f"- {jira_key} | {action} | quality={q}")
163
+ else:
164
+ lines.append("- No generation history available")
165
+ lines.append("")
166
+
167
+ return "\n".join(lines)
@@ -0,0 +1,205 @@
1
+ """Requirement context enrichment + registry synchronization.
2
+
3
+ This module implements a single orchestrated flow that:
4
+ 1) Persists requirement-scoped context markdown in .ai/context/requirements/<JIRA>/context.md
5
+ 2) Finds affected files for the requirement (explicit + registry + repo scan)
6
+ 3) Updates PostgreSQL requirement and mapping tables in one transaction
7
+ 4) Regenerates .ai/context.md projection cache from registries
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ from dataclasses import dataclass
13
+ from pathlib import Path
14
+
15
+ from src.db.client import get_transaction
16
+ from src.project.context_projection_builder import ContextProjectionBuilder
17
+
18
+
19
+ @dataclass
20
+ class RequirementSyncResult:
21
+ jira_key: str
22
+ requirement_id: str | None
23
+ affected_files: list[str]
24
+ mapped_assets: int
25
+ requirement_context_path: str
26
+ projection: dict
27
+
28
+
29
+ def _norm_key(jira_key: str) -> str:
30
+ return jira_key.strip().upper()
31
+
32
+
33
+ def _table_exists(cur, table: str) -> bool:
34
+ cur.execute(
35
+ "SELECT 1 FROM information_schema.tables WHERE table_name = %s",
36
+ (table,),
37
+ )
38
+ return cur.fetchone() is not None
39
+
40
+
41
+ def _write_requirement_context(repo_root: Path, jira_key: str, context_text: str) -> Path:
42
+ key = _norm_key(jira_key)
43
+ path = repo_root / ".ai" / "context" / "requirements" / key / "context.md"
44
+ path.parent.mkdir(parents=True, exist_ok=True)
45
+ path.write_text(context_text.strip() + "\n", encoding="utf-8")
46
+ return path
47
+
48
+
49
+ def _repo_scan_for_requirement_files(repo_root: Path, jira_key: str, *, limit: int = 100) -> list[str]:
50
+ key = _norm_key(jira_key)
51
+ matches: list[str] = []
52
+
53
+ roots = [
54
+ repo_root / "tests",
55
+ repo_root / "test",
56
+ repo_root / "docs",
57
+ repo_root / ".ai",
58
+ ]
59
+ allowed_ext = {".py", ".md", ".yaml", ".yml", ".json", ".feature", ".txt"}
60
+
61
+ for root in roots:
62
+ if not root.exists() or not root.is_dir():
63
+ continue
64
+ for fp in root.rglob("*"):
65
+ if len(matches) >= limit:
66
+ return sorted(set(matches))
67
+ if not fp.is_file() or fp.suffix.lower() not in allowed_ext:
68
+ continue
69
+
70
+ rel = str(fp.relative_to(repo_root))
71
+ if key in rel.upper():
72
+ matches.append(rel)
73
+ continue
74
+
75
+ try:
76
+ text = fp.read_text(encoding="utf-8", errors="ignore")
77
+ except Exception:
78
+ continue
79
+
80
+ if key in text.upper():
81
+ matches.append(rel)
82
+
83
+ return sorted(set(matches))
84
+
85
+
86
+ def _registry_files_for_requirement(cur, jira_key: str) -> list[str]:
87
+ if not (_table_exists(cur, "igel_requirements") and _table_exists(cur, "igel_asset_mappings") and _table_exists(cur, "igel_asset_registry")):
88
+ return []
89
+
90
+ cur.execute(
91
+ """
92
+ SELECT DISTINCT a.file_path
93
+ FROM igel_asset_registry a
94
+ JOIN igel_asset_mappings m ON m.asset_id = a.id
95
+ JOIN igel_requirements r ON r.id = m.requirement_id
96
+ WHERE r.jira_key = %s
97
+ """,
98
+ (_norm_key(jira_key),),
99
+ )
100
+ rows = cur.fetchall()
101
+ return sorted({str(r[0]) for r in rows if r and r[0]})
102
+
103
+
104
+ def sync_requirement_context(
105
+ repo_root: Path,
106
+ jira_key: str,
107
+ context_text: str,
108
+ *,
109
+ changed_files: list[str] | None = None,
110
+ ) -> RequirementSyncResult:
111
+ key = _norm_key(jira_key)
112
+
113
+ requirement_context_path = _write_requirement_context(repo_root, key, context_text)
114
+
115
+ changed_files = [str(Path(p).as_posix()) for p in (changed_files or []) if str(p).strip()]
116
+
117
+ with get_transaction() as conn:
118
+ with conn.cursor() as cur:
119
+ requirement_id: str | None = None
120
+ mapped_assets = 0
121
+
122
+ if _table_exists(cur, "igel_requirements"):
123
+ # Upsert requirement row and keep latest context text in description.
124
+ cur.execute(
125
+ """
126
+ INSERT INTO igel_requirements (jira_key, summary, description)
127
+ VALUES (%s, %s, %s)
128
+ ON CONFLICT (jira_key)
129
+ DO UPDATE SET
130
+ summary = EXCLUDED.summary,
131
+ description = EXCLUDED.description
132
+ RETURNING id::text
133
+ """,
134
+ (key, f"Context enrichment for {key}", context_text),
135
+ )
136
+ row = cur.fetchone()
137
+ requirement_id = str(row[0]) if row else None
138
+
139
+ db_files = _registry_files_for_requirement(cur, key)
140
+ repo_files = _repo_scan_for_requirement_files(repo_root, key)
141
+
142
+ all_files = sorted({*changed_files, *db_files, *repo_files})
143
+
144
+ if (
145
+ requirement_id
146
+ and all_files
147
+ and _table_exists(cur, "igel_asset_registry")
148
+ and _table_exists(cur, "igel_asset_mappings")
149
+ ):
150
+ # Find assets in affected files and ensure requirement mappings exist.
151
+ for rel_path in all_files:
152
+ cur.execute(
153
+ """
154
+ SELECT id::text
155
+ FROM igel_asset_registry
156
+ WHERE file_path = %s
157
+ OR file_path LIKE %s
158
+ """,
159
+ (rel_path, f"%/{rel_path}"),
160
+ )
161
+ asset_rows = cur.fetchall()
162
+ for asset_row in asset_rows:
163
+ asset_id = str(asset_row[0])
164
+ cur.execute(
165
+ """
166
+ INSERT INTO igel_asset_mappings (requirement_id, asset_id, mapping_type)
167
+ SELECT %s::uuid, %s::uuid, %s
168
+ WHERE NOT EXISTS (
169
+ SELECT 1 FROM igel_asset_mappings
170
+ WHERE requirement_id = %s::uuid
171
+ AND asset_id = %s::uuid
172
+ AND mapping_type = %s
173
+ )
174
+ """,
175
+ (
176
+ requirement_id,
177
+ asset_id,
178
+ "required_for_test",
179
+ requirement_id,
180
+ asset_id,
181
+ "required_for_test",
182
+ ),
183
+ )
184
+ mapped_assets += 1
185
+
186
+ # Persist discovered requirement dependencies (file references) when table exists.
187
+ if requirement_id and _table_exists(cur, "igel_requirement_understanding"):
188
+ cur.execute(
189
+ """
190
+ INSERT INTO igel_requirement_understanding (requirement_id, dependencies)
191
+ VALUES (%s::uuid, %s::jsonb)
192
+ """,
193
+ (requirement_id, json.dumps(all_files)),
194
+ )
195
+
196
+ projection = ContextProjectionBuilder(repo_root).build()
197
+
198
+ return RequirementSyncResult(
199
+ jira_key=key,
200
+ requirement_id=requirement_id,
201
+ affected_files=all_files,
202
+ mapped_assets=mapped_assets,
203
+ requirement_context_path=str(requirement_context_path),
204
+ projection=projection,
205
+ )