atomadic-forge 0.52.1__tar.gz → 0.53.0__tar.gz

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 (425) hide show
  1. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/CHANGELOG.md +37 -0
  2. {atomadic_forge-0.52.1/src/atomadic_forge.egg-info → atomadic_forge-0.53.0}/PKG-INFO +1 -1
  3. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/pyproject.toml +1 -1
  4. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/agent_context_pack.py +11 -1
  5. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/call_graph.py +110 -0
  6. atomadic_forge-0.53.0/src/atomadic_forge/a1_at_functions/git_churn.py +129 -0
  7. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/mcp_protocol.py +51 -7
  8. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a4_sy_orchestration/cli.py +79 -0
  9. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0/src/atomadic_forge.egg-info}/PKG-INFO +1 -1
  10. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge.egg-info/SOURCES.txt +3 -0
  11. atomadic_forge-0.53.0/tests/test_call_graph_summary.py +65 -0
  12. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_copilots_copilot.py +8 -0
  13. atomadic_forge-0.53.0/tests/test_git_churn.py +80 -0
  14. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_mcp_protocol.py +63 -0
  15. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/FUNDING.yml +0 -0
  16. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  17. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  18. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  19. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/actions/forge-action/README.md +0 -0
  20. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/actions/forge-action/action.yml +0 -0
  21. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/dependabot.yml +0 -0
  22. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/pull_request_template.md +0 -0
  23. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/workflows/ci.yml +0 -0
  24. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/workflows/customer-refactor.yml +0 -0
  25. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/workflows/forge-self-certify.yml +0 -0
  26. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/workflows/mcp-registry-publish.yml +0 -0
  27. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/workflows/metrics-auto-regen.yml +0 -0
  28. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/workflows/metrics-drift.yml +0 -0
  29. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/workflows/publish-on-tag.yml +0 -0
  30. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/workflows/release-readiness.yml +0 -0
  31. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/workflows/release.yml +0 -0
  32. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/workflows/surface-drift.yml +0 -0
  33. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/.github/workflows/uptime.yml +0 -0
  34. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/ARCHITECTURE.md +0 -0
  35. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/CONTRIBUTING.md +0 -0
  36. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/LICENSE +0 -0
  37. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/MANIFEST.in +0 -0
  38. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/README.md +0 -0
  39. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/SECURITY.md +0 -0
  40. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/assets/Atomadic-Forge-01.png +0 -0
  41. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/01-getting-started.md +0 -0
  42. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/02-commands.md +0 -0
  43. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/03-tutorial.md +0 -0
  44. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/04-llm-loops.md +0 -0
  45. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/05-faq.md +0 -0
  46. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/AGENTS_GUIDE.md +0 -0
  47. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/AIR_GAPPED.md +0 -0
  48. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/CI_CD.md +0 -0
  49. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/CODEX_WALKTHROUGH.md +0 -0
  50. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/COMMANDS.md +0 -0
  51. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/FIRST_10_MINUTES.md +0 -0
  52. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/FORMALIZATION.md +0 -0
  53. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/HIVE_PRIMITIVES.md +0 -0
  54. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/HIVE_STATUS.md +0 -0
  55. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/IDE_INTEGRATION.md +0 -0
  56. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/LANDSCAPE.md +0 -0
  57. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/MARKET_POSITIONING.md +0 -0
  58. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/MIGRATION.md +0 -0
  59. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/MULTI_REPO.md +0 -0
  60. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/PROVIDERS.md +0 -0
  61. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/README.md +0 -0
  62. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/RECEIPT.md +0 -0
  63. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/RELAY_PROTOCOL.md +0 -0
  64. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/RELEASE_CHECKLIST.md +0 -0
  65. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/RELEASE_MESSAGING.md +0 -0
  66. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/ROADMAP.md +0 -0
  67. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/SHOWCASE.md +0 -0
  68. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/SIDECAR.md +0 -0
  69. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/STUDIO.md +0 -0
  70. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/TOOL_FACTORY_WALKTHROUGH.md +0 -0
  71. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/V0.46.0_JUSTIFICATION_REPORT.md +0 -0
  72. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/V0.47.0_SELF_TEST_REPORT.md +0 -0
  73. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/WHY_NOW.md +0 -0
  74. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/WORKER_VS_LOCAL_MCP.md +0 -0
  75. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/WORLD_COLLISION.md +0 -0
  76. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/INDEX.md +0 -0
  77. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/absorb.md +0 -0
  78. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/audit.md +0 -0
  79. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/chat.md +0 -0
  80. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/commandsmith.md +0 -0
  81. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/config.md +0 -0
  82. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/create.md +0 -0
  83. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/demo.md +0 -0
  84. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/emergent-swarm.md +0 -0
  85. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/emergent-then-synergy.md +0 -0
  86. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/emergent.md +0 -0
  87. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/enhancement.md +0 -0
  88. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/evolve-then-iterate.md +0 -0
  89. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/evolve.md +0 -0
  90. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/feature-then-emergent.md +0 -0
  91. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/guard-install.md +0 -0
  92. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/handoff.md +0 -0
  93. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/harvest.md +0 -0
  94. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/hive.md +0 -0
  95. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/iterate.md +0 -0
  96. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/materialize.md +0 -0
  97. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/metrics.md +0 -0
  98. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/recon-swarm.md +0 -0
  99. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/relay.md +0 -0
  100. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/surface.md +0 -0
  101. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/synergy-then-emergent.md +0 -0
  102. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/synergy.md +0 -0
  103. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/welcome.md +0 -0
  104. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/commands/wisdom.md +0 -0
  105. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/compliance/CMMC_AI_MAPPING.md +0 -0
  106. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/compliance/CS-1.md +0 -0
  107. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/compliance/EU_AI_ACT_ANNEX_IV.md +0 -0
  108. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/compliance/FDA_PCCP_MAPPING.md +0 -0
  109. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/compliance/SR_11-7_MAPPING.md +0 -0
  110. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/handoffs/WORKER_AUTO_DEPLOY_2026-05-06.md +0 -0
  111. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/tutorials/01-quickstart.md +0 -0
  112. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/tutorials/02-your-first-package.md +0 -0
  113. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/tutorials/03-the-five-tier-law.md +0 -0
  114. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/tutorials/04-plug-in-llms.md +0 -0
  115. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/tutorials/05-multi-repo-absorb.md +0 -0
  116. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/docs/tutorials/06-javascript-quickstart.md +0 -0
  117. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/setup.cfg +0 -0
  118. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/__init__.py +0 -0
  119. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/__main__.py +0 -0
  120. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/__init__.py +0 -0
  121. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/agent_plan_schema.py +0 -0
  122. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/auth_constants.py +0 -0
  123. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/commandsmith_types.py +0 -0
  124. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/config_defaults.py +0 -0
  125. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/emergent_types.py +0 -0
  126. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/enhancement_proposal_constants.py +0 -0
  127. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/error_codes.py +0 -0
  128. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/forge_types.py +0 -0
  129. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/gen_language.py +0 -0
  130. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/handoff_constants.py +0 -0
  131. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/hive_constants.py +0 -0
  132. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/lang_extensions.py +0 -0
  133. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/lifetime_savings_constants.py +0 -0
  134. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/materialize_types.py +0 -0
  135. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/mhed_invariants.py +0 -0
  136. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/nexus_constants.py +0 -0
  137. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/policy_schema.py +0 -0
  138. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/receipt_schema.py +0 -0
  139. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/response_enrichment.py +0 -0
  140. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/roi_constants.py +0 -0
  141. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/schema_version_registry.py +0 -0
  142. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/semantic_types.py +0 -0
  143. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/sidecar_schema.py +0 -0
  144. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/synergy_types.py +0 -0
  145. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/tier_names.py +0 -0
  146. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/welcome_constants.py +0 -0
  147. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a0_qk_constants/wisdom_constants.py +0 -0
  148. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/__init__.py +0 -0
  149. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/agent_memory.py +0 -0
  150. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/agent_plan_emitter.py +0 -0
  151. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/agent_summary.py +0 -0
  152. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/body_extractor.py +0 -0
  153. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/card_renderer.py +0 -0
  154. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/certify_checks.py +0 -0
  155. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/chat_context.py +0 -0
  156. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/cherry_pick.py +0 -0
  157. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/classify_tier.py +0 -0
  158. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/code_signature.py +0 -0
  159. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/commandsmith_discover.py +0 -0
  160. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/commandsmith_render.py +0 -0
  161. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/compiler_feedback.py +0 -0
  162. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/compliance_checker.py +0 -0
  163. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/config_io.py +0 -0
  164. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/cs1_renderer.py +0 -0
  165. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/custom_provider_client.py +0 -0
  166. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/doc_synthesizer.py +0 -0
  167. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/emergent_compose.py +0 -0
  168. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/emergent_rank.py +0 -0
  169. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/emergent_signature_extract.py +0 -0
  170. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/emergent_synthesize.py +0 -0
  171. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/enforce_planner.py +0 -0
  172. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/enhancement_proposal_builder.py +0 -0
  173. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/error_hints.py +0 -0
  174. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/evolution_log.py +0 -0
  175. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/exported_api_check.py +0 -0
  176. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/forge_auth.py +0 -0
  177. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/forge_feedback.py +0 -0
  178. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/forge_locate.py +0 -0
  179. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/forge_metrics.py +0 -0
  180. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/generation_quality.py +0 -0
  181. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/handoff_builder.py +0 -0
  182. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/harvest_absorb.py +0 -0
  183. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/hive_consensus_math.py +0 -0
  184. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/hive_io.py +0 -0
  185. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/import_repair.py +0 -0
  186. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/import_smoke.py +0 -0
  187. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/intent_similarity.py +0 -0
  188. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/js_parser.py +0 -0
  189. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/lifetime_savings.py +0 -0
  190. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/lineage_chain.py +0 -0
  191. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/lineage_reader.py +0 -0
  192. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/llm_client.py +0 -0
  193. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/local_signer.py +0 -0
  194. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/lsp_protocol.py +0 -0
  195. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/manifest_diff.py +0 -0
  196. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/patch_scorer.py +0 -0
  197. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/plan_adapter.py +0 -0
  198. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/policy_loader.py +0 -0
  199. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/polyglot_classify.py +0 -0
  200. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/polyglot_imports.py +0 -0
  201. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/polyglot_surface.py +0 -0
  202. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/preflight_change.py +0 -0
  203. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/progress_reporter.py +0 -0
  204. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/provider_detect.py +0 -0
  205. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/provider_resolver.py +0 -0
  206. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/receipt_emitter.py +0 -0
  207. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/recipes.py +0 -0
  208. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/repo_explainer.py +0 -0
  209. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/research_note_distiller.py +0 -0
  210. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/response_enricher.py +0 -0
  211. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/roi_calculator.py +0 -0
  212. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/rollback_planner.py +0 -0
  213. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/sbom_emitter.py +0 -0
  214. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/scaffold_js.py +0 -0
  215. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/scaffold_polyglot.py +0 -0
  216. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/scaffold_pyproject.py +0 -0
  217. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/scaffold_starter.py +0 -0
  218. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/scout_walk.py +0 -0
  219. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/sidecar_parser.py +0 -0
  220. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/sidecar_validator.py +0 -0
  221. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/smell_scan.py +0 -0
  222. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/stub_detector.py +0 -0
  223. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/synergy_detect.py +0 -0
  224. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/synergy_render.py +0 -0
  225. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/synergy_surface_extract.py +0 -0
  226. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/test_runner.py +0 -0
  227. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/test_selector.py +0 -0
  228. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/tier_init_rebuild.py +0 -0
  229. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/tool_composer.py +0 -0
  230. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/transcript_log.py +0 -0
  231. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/trust_gate_response.py +0 -0
  232. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/validation_commands.py +0 -0
  233. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/welcome_narrator.py +0 -0
  234. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/wire_check.py +0 -0
  235. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/wisdom_capture.py +0 -0
  236. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/wisdom_io.py +0 -0
  237. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/wisdom_promote.py +0 -0
  238. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/wisdom_recall.py +0 -0
  239. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a1_at_functions/worktree_status.py +0 -0
  240. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/__init__.py +0 -0
  241. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/cost_circuit_breaker.py +0 -0
  242. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/cross_agent_intent_deduplicator.py +0 -0
  243. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/evolve_session_store.py +0 -0
  244. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/forge_auth_client.py +0 -0
  245. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/hierarchical_memory.py +0 -0
  246. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/iterate_session_store.py +0 -0
  247. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/lineage_chain_store.py +0 -0
  248. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/manifest_store.py +0 -0
  249. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/nexus_client.py +0 -0
  250. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/plan_store.py +0 -0
  251. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a2_mo_composites/receipt_signer.py +0 -0
  252. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/__init__.py +0 -0
  253. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/absorb_feature.py +0 -0
  254. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/agent_hire_protocol.py +0 -0
  255. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/cherry_hunter.py +0 -0
  256. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/cna_check.py +0 -0
  257. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/commandsmith_feature.py +0 -0
  258. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/commit_compose.py +0 -0
  259. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/create_feature.py +0 -0
  260. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/dedup_engine.py +0 -0
  261. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/__init__.py +0 -0
  262. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/a0_qk_constants/__init__.py +0 -0
  263. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/a1_at_functions/__init__.py +0 -0
  264. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/tests/conftest.py +0 -0
  265. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/tests/test_mixed.py +0 -0
  266. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/demo_runner.py +0 -0
  267. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/emergent_feature.py +0 -0
  268. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/emergent_pipeline_integration.py +0 -0
  269. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/emergent_swarm.py +0 -0
  270. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/enhancement_proposal_feature.py +0 -0
  271. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/forge_enforce.py +0 -0
  272. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/forge_evolve.py +0 -0
  273. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/forge_evolve_session.py +0 -0
  274. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/forge_loop.py +0 -0
  275. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/forge_loop_session.py +0 -0
  276. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/forge_metrics_feature.py +0 -0
  277. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/forge_pipeline.py +0 -0
  278. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/forge_plan_apply.py +0 -0
  279. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/guard_install.py +0 -0
  280. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/handoff_feature.py +0 -0
  281. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/hive_sync.py +0 -0
  282. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/lsp_server.py +0 -0
  283. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/materialize_feature.py +0 -0
  284. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/mcp_server.py +0 -0
  285. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/nexus_bridge.py +0 -0
  286. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/relay_daemon.py +0 -0
  287. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/setup_wizard.py +0 -0
  288. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/surface_export.py +0 -0
  289. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/synergy_feature.py +0 -0
  290. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/tool_factory.py +0 -0
  291. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/verify_umbrella.py +0 -0
  292. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/welcome_feature.py +0 -0
  293. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a3_og_features/wisdom_feature.py +0 -0
  294. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a4_sy_orchestration/__init__.py +0 -0
  295. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a4_sy_orchestration/copilots_cmd.py +0 -0
  296. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a4_sy_orchestration/login_cmd.py +0 -0
  297. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/a4_sy_orchestration/whoami_cmd.py +0 -0
  298. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/__init__.py +0 -0
  299. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/_registry.py +0 -0
  300. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/absorb.py +0 -0
  301. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/audit.py +0 -0
  302. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/chat.py +0 -0
  303. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/commandsmith.py +0 -0
  304. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/config_cmd.py +0 -0
  305. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/create.py +0 -0
  306. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/demo.py +0 -0
  307. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/emergent.py +0 -0
  308. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/emergent_swarm.py +0 -0
  309. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/emergent_then_synergy.py +0 -0
  310. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/enhancement.py +0 -0
  311. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/evolve.py +0 -0
  312. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/evolve_then_iterate.py +0 -0
  313. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/feature_then_emergent.py +0 -0
  314. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/guard_install.py +0 -0
  315. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/handoff.py +0 -0
  316. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/harvest.py +0 -0
  317. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/hive.py +0 -0
  318. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/iterate.py +0 -0
  319. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/materialize.py +0 -0
  320. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/metrics.py +0 -0
  321. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/recon_swarm.py +0 -0
  322. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/relay.py +0 -0
  323. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/surface.py +0 -0
  324. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/synergy.py +0 -0
  325. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/synergy_then_emergent.py +0 -0
  326. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/welcome.py +0 -0
  327. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge/commands/wisdom.py +0 -0
  328. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge.egg-info/dependency_links.txt +0 -0
  329. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge.egg-info/entry_points.txt +0 -0
  330. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge.egg-info/requires.txt +0 -0
  331. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/src/atomadic_forge.egg-info/top_level.txt +0 -0
  332. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_aaaa_nexus_client.py +0 -0
  333. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_agent_hire_protocol.py +0 -0
  334. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_agent_plan.py +0 -0
  335. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_agent_plan_pkg_label.py +0 -0
  336. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_agent_summary.py +0 -0
  337. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_audit_verb.py +0 -0
  338. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_body_extractor_repairs.py +0 -0
  339. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_card_renderer.py +0 -0
  340. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_certify_operational_axis.py +0 -0
  341. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_chat.py +0 -0
  342. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_classify_tier.py +0 -0
  343. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_classify_tier_ast_signals.py +0 -0
  344. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_cli_smoke.py +0 -0
  345. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_cli_swarm_aliases.py +0 -0
  346. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_codex_5_complete.py +0 -0
  347. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_codex_6_enforce_polyglot.py +0 -0
  348. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_commandsmith.py +0 -0
  349. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_compiler_feedback.py +0 -0
  350. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_compliance_checker.py +0 -0
  351. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_config.py +0 -0
  352. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_cost_circuit_breaker.py +0 -0
  353. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_create_feature.py +0 -0
  354. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_cs1_renderer.py +0 -0
  355. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_custom_provider.py +0 -0
  356. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_dedup_engine.py +0 -0
  357. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_demo.py +0 -0
  358. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_emergent_compose.py +0 -0
  359. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_emergent_signature_extract.py +0 -0
  360. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_emergent_synthesize_imports.py +0 -0
  361. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_enhancement_proposal.py +0 -0
  362. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_error_codes.py +0 -0
  363. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_error_hints.py +0 -0
  364. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_evolve_js.py +0 -0
  365. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_exported_api_check.py +0 -0
  366. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_forge_action.py +0 -0
  367. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_forge_auth_a1.py +0 -0
  368. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_forge_auth_a2.py +0 -0
  369. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_forge_enforce.py +0 -0
  370. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_generation_quality.py +0 -0
  371. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_handoff.py +0 -0
  372. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_hierarchical_memory.py +0 -0
  373. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_hive_sync.py +0 -0
  374. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_ignore_and_docs.py +0 -0
  375. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_import_smoke.py +0 -0
  376. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_iterate_evolve.py +0 -0
  377. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_js_certify.py +0 -0
  378. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_js_parser.py +0 -0
  379. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_js_recon.py +0 -0
  380. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_js_wire.py +0 -0
  381. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_lineage_chain.py +0 -0
  382. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_ling_provider.py +0 -0
  383. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_local_signer.py +0 -0
  384. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_lsp_protocol.py +0 -0
  385. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_manifest_diff.py +0 -0
  386. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_materialize_feature.py +0 -0
  387. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_mcp_lazy_bootstrap.py +0 -0
  388. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_nexus_bridge.py +0 -0
  389. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_ollama_client.py +0 -0
  390. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_pipeline.py +0 -0
  391. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_plan_apply.py +0 -0
  392. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_polyglot_cli_mcp.py +0 -0
  393. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_polyglot_full_pipeline.py +0 -0
  394. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_polyglot_hardening.py +0 -0
  395. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_polyglot_swift_kotlin_go.py +0 -0
  396. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_polyglot_symbol_parity.py +0 -0
  397. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_pre_audit_smoke.py +0 -0
  398. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_precommit_hooks.py +0 -0
  399. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_progress_reporter.py +0 -0
  400. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_receipt_emitter.py +0 -0
  401. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_receipt_schema.py +0 -0
  402. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_receipt_signer.py +0 -0
  403. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_response_enricher.py +0 -0
  404. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_roi_calculator.py +0 -0
  405. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_sbom_cmd_text_summary.py +0 -0
  406. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_sbom_emitter.py +0 -0
  407. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_scaffold.py +0 -0
  408. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_sidecar.py +0 -0
  409. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_sidecar_validate.py +0 -0
  410. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_smell_score_formula.py +0 -0
  411. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_stagnation.py +0 -0
  412. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_stub_detector.py +0 -0
  413. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_surface_export.py +0 -0
  414. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_synergy.py +0 -0
  415. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_test_runner.py +0 -0
  416. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_tier_init_rebuild.py +0 -0
  417. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_trust_gate_response.py +0 -0
  418. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_verify_suggested_recipe.py +0 -0
  419. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_welcome.py +0 -0
  420. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_welcome_enhancements.py +0 -0
  421. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_whoami_cmd.py +0 -0
  422. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_wire_certify.py +0 -0
  423. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_wire_suggest_repairs.py +0 -0
  424. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_wire_type_checking.py +0 -0
  425. {atomadic_forge-0.52.1 → atomadic_forge-0.53.0}/tests/test_wisdom.py +0 -0
@@ -2,6 +2,43 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## v0.53.0 — 2026-05-07 — Harvest synthesis: call-graph-summary, git churn, token budget
6
+
7
+ ### feat(synthesis): three new a1 capabilities absorbed from harvest pipeline
8
+
9
+ **`call_graph_summary` — whole-package call-graph portfolio** (pyan synthesis)
10
+
11
+ Adds `build_call_graph_summary()` to `a1_at_functions/call_graph.py`.
12
+ Surfaces orphan functions (uncalled callers), hotspot functions by fan-in,
13
+ and maximum call-chain depth for an entire package in one shot — distinct from
14
+ the per-symbol BFS that `call_graph` already provides.
15
+
16
+ - `forge call-graph-summary --project <root> [--package NAME] [--top-n N] [--json]`
17
+ - MCP: `explore(action='call_graph_summary')`
18
+ - Schema: `atomadic-forge.call_graph_summary/v1`
19
+
20
+ **`git_churn` — file-level commit frequency** (Repomix synthesis)
21
+
22
+ New `a1_at_functions/git_churn.py` with `compute_git_churn()`.
23
+ Runs `git log --name-only` to build hotspot/stable file rankings, average and
24
+ median commits per file, first/last commit dates. Returns a minimal error dict
25
+ when git is unavailable so callers degrade gracefully.
26
+
27
+ - `forge churn --project <root> [--since '6 months ago'] [--top-n N] [--all-files] [--json]`
28
+ - MCP: `explore(action='churn')`
29
+ - Schema: `atomadic-forge.git_churn/v1`
30
+
31
+ **`token_estimate` — context-pack payload sizing** (Repomix synthesis)
32
+
33
+ `emit_context_pack()` now includes `token_estimate: int` — a `len(json.dumps(pack)) // 4`
34
+ approximation so agents can budget against context limits before dispatching.
35
+
36
+ ### metrics
37
+
38
+ - CLI verbs: 74 (+2)
39
+ - MCP actions: 66 (+2)
40
+ - Tests: 1423 (+14 over v0.52.1)
41
+
5
42
  ## v0.52.1 — 2026-05-07 — IP scrub: no private identifiers in public repo
6
43
 
7
44
  ### fix(security): remove all private identifiers from public surfaces
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atomadic-forge
3
- Version: 0.52.1
3
+ Version: 0.53.0
4
4
  Summary: Atomadic Forge — absorb, enforce, emerge. Polyglot (Python · JavaScript/TypeScript · Rust · Go · Swift · Kotlin) architecture guardian for AI-generated code.
5
5
  Author: Atomadic
6
6
  License-Expression: BUSL-1.1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "atomadic-forge"
7
- version = "0.52.1"
7
+ version = "0.53.0"
8
8
  description = "Atomadic Forge — absorb, enforce, emerge. Polyglot (Python · JavaScript/TypeScript · Rust · Go · Swift · Kotlin) architecture guardian for AI-generated code."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -13,6 +13,7 @@ single bundle. The orchestration that runs the scans lives in a3.
13
13
  """
14
14
  from __future__ import annotations
15
15
 
16
+ import json
16
17
  import re
17
18
  from collections import Counter
18
19
  from pathlib import Path
@@ -136,6 +137,7 @@ class ContextPack(TypedDict, total=False):
136
137
  selected_tests: dict
137
138
  workflow_recipe: dict # compose_tools plan when intent is provided
138
139
  suggested_next_steps: list[dict]
140
+ token_estimate: int # rough token count (chars // 4); repomix synthesis
139
141
 
140
142
 
141
143
  def _read_repo_purpose(project_root: Path) -> str:
@@ -442,7 +444,7 @@ def emit_context_pack(
442
444
  project_root=project_root,
443
445
  )
444
446
 
445
- return ContextPack(
447
+ pack = ContextPack(
446
448
  schema_version=SCHEMA_VERSION_CONTEXT_PACK_V1,
447
449
  project_root=str(project_root),
448
450
  repo_purpose=_read_repo_purpose(project_root),
@@ -478,4 +480,12 @@ def emit_context_pack(
478
480
  release_gate=release_gate,
479
481
  selected_tests=selected_tests,
480
482
  ),
483
+ token_estimate=0,
481
484
  )
485
+ # Patch token_estimate after build — rough approximation: JSON chars / 4 ≈ tokens.
486
+ # No external tokenizer required; accurate enough for context budget decisions.
487
+ try:
488
+ pack["token_estimate"] = len(json.dumps(pack, default=str)) // 4
489
+ except (TypeError, ValueError):
490
+ pass
491
+ return pack
@@ -419,3 +419,113 @@ def build_call_graph(args: dict[str, Any]) -> dict[str, Any]:
419
419
  "callees_count": len(callees),
420
420
  "target_in_graph": canonical_target in edges,
421
421
  }
422
+
423
+
424
+ # ── Whole-package summary (pyan synthesis) ────────────────────────────
425
+
426
+ SCHEMA_VERSION_CALL_GRAPH_SUMMARY_V1 = "atomadic-forge.call_graph_summary/v1"
427
+
428
+
429
+ def _compute_fan_in(edges: dict[str, set[str]]) -> dict[str, int]:
430
+ fan_in: dict[str, int] = defaultdict(int)
431
+ for callees in edges.values():
432
+ for callee in callees:
433
+ fan_in[callee] += 1
434
+ return dict(fan_in)
435
+
436
+
437
+ def _max_chain_depth(
438
+ edges: dict[str, set[str]],
439
+ starts: list[str],
440
+ *,
441
+ cap: int = 15,
442
+ ) -> int:
443
+ """BFS from each start node; return the longest path found (capped)."""
444
+ best = 0
445
+ for start in starts[:100]:
446
+ visited: set[str] = {start}
447
+ queue: deque[tuple[str, int]] = deque([(start, 0)])
448
+ while queue:
449
+ node, d = queue.popleft()
450
+ if d >= cap:
451
+ continue
452
+ for callee in edges.get(node, ()):
453
+ if callee not in visited:
454
+ visited.add(callee)
455
+ if d + 1 > best:
456
+ best = d + 1
457
+ queue.append((callee, d + 1))
458
+ return best
459
+
460
+
461
+ def build_call_graph_summary(args: dict[str, Any]) -> dict[str, Any]:
462
+ """Whole-package call-graph portfolio: orphans, hotspots, max depth.
463
+
464
+ Synthesized from pyan (David Fraser) whole-graph analysis concepts.
465
+ Unlike ``build_call_graph`` (per-symbol callers/callees), this gives
466
+ a portfolio view of the entire package's call structure — useful for
467
+ dead-code audits, refactor prioritization, and complexity estimation.
468
+
469
+ Args (from the dispatcher):
470
+ * ``project_root`` (default: cwd): repo root.
471
+ * ``package`` (default: derived): top-level package name.
472
+ * ``top_n`` (default 10): number of hotspot/orphan rows to return.
473
+ """
474
+ project_root = Path(args.get("project_root") or ".").resolve()
475
+ top_n = min(int(args.get("top_n", 10)), 50)
476
+
477
+ _raw_package = args.get("package") or _detect_package_name(project_root)
478
+ package = _raw_package.replace("-", "_")
479
+
480
+ package_root = project_root / "src" / package
481
+ if not package_root.exists():
482
+ candidate = project_root / package
483
+ package_root = candidate if candidate.exists() else project_root
484
+
485
+ edges = _walk_package_edges(package_root, package=package)
486
+ aliases = _build_reexport_aliases(package_root, package=package)
487
+
488
+ if aliases:
489
+ canonical_edges: dict[str, set[str]] = defaultdict(set)
490
+ for caller, callees_set in edges.items():
491
+ canonical_caller = _canonicalize(caller, aliases)
492
+ for callee in callees_set:
493
+ canonical_edges[canonical_caller].add(
494
+ _canonicalize(callee, aliases)
495
+ )
496
+ edges = dict(canonical_edges)
497
+
498
+ fan_in = _compute_fan_in(edges)
499
+
500
+ # Defined = every function that appears as a caller (has ≥1 outgoing edge).
501
+ defined: set[str] = {f for f in edges if f.startswith(package)}
502
+ called: set[str] = {f for f in fan_in if f.startswith(package)}
503
+
504
+ # Uncalled callers: defined but never called from within the package.
505
+ # These may be entry-points (CLI/MCP handlers) or dead code.
506
+ uncalled = sorted(defined - called)
507
+
508
+ # Hotspots: package functions with the highest internal fan-in.
509
+ hotspots = sorted(
510
+ [{"qualname": q, "fan_in": c} for q, c in fan_in.items()
511
+ if q.startswith(package)],
512
+ key=lambda x: -x["fan_in"],
513
+ )[:top_n]
514
+
515
+ max_depth = _max_chain_depth(edges, uncalled)
516
+
517
+ total_edges = sum(len(v) for v in edges.values())
518
+
519
+ return {
520
+ "schema_version": SCHEMA_VERSION_CALL_GRAPH_SUMMARY_V1,
521
+ "package": package,
522
+ "package_root": str(package_root),
523
+ "total_callers": len(defined),
524
+ "total_edges": total_edges,
525
+ "uncalled_callers_count": len(uncalled),
526
+ "uncalled_callers": uncalled[:top_n],
527
+ "hotspot_count": len(hotspots),
528
+ "hotspots": hotspots,
529
+ "max_call_depth": max_depth,
530
+ "alias_count": len(aliases),
531
+ }
@@ -0,0 +1,129 @@
1
+ """Tier a1 — git churn analysis: file-level commit frequency from git log.
2
+
3
+ Synthesized from Repomix's ``calculateGitLogMetrics`` concept. Forge's
4
+ recon already captures static structure (symbol counts, complexity).
5
+ Git churn adds a **temporal quality axis**: which files change most
6
+ often, how recently, and how stable the codebase is over time.
7
+
8
+ Pure in the Forge sense: read-only subprocess calls to ``git log``,
9
+ no writes, no state mutation. Returns ``None`` if the repo has no git
10
+ history or git is unavailable — callers degrade gracefully.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import subprocess
15
+ from collections import defaultdict
16
+ from pathlib import Path
17
+ from typing import Any
18
+
19
+ SCHEMA_VERSION_GIT_CHURN_V1 = "atomadic-forge.git_churn/v1"
20
+
21
+ _GIT_TIMEOUT = 10 # seconds
22
+
23
+
24
+ def _run_git(args: list[str], cwd: Path) -> str | None:
25
+ try:
26
+ result = subprocess.run(
27
+ ["git", *args],
28
+ cwd=str(cwd),
29
+ capture_output=True,
30
+ text=True,
31
+ timeout=_GIT_TIMEOUT,
32
+ )
33
+ return result.stdout if result.returncode == 0 else None
34
+ except (FileNotFoundError, subprocess.TimeoutExpired, OSError):
35
+ return None
36
+
37
+
38
+ def _commit_count_per_file(repo_root: Path, *, since: str = "") -> dict[str, int]:
39
+ """Return {relative_path: commit_count} for every tracked file."""
40
+ args = ["log", "--name-only", "--pretty=format:"]
41
+ if since:
42
+ args += ["--since", since]
43
+ out = _run_git(args, repo_root)
44
+ if out is None:
45
+ return {}
46
+ counts: dict[str, int] = defaultdict(int)
47
+ for line in out.splitlines():
48
+ line = line.strip()
49
+ if line:
50
+ counts[line] += 1
51
+ return dict(counts)
52
+
53
+
54
+ def _first_and_last_commit_date(repo_root: Path) -> tuple[str, str]:
55
+ first = _run_git(["log", "--reverse", "--pretty=format:%ci", "--diff-filter=A", "--", "."], repo_root)
56
+ last = _run_git(["log", "-1", "--pretty=format:%ci"], repo_root)
57
+ first_date = (first or "").splitlines()[0][:10] if first else ""
58
+ last_date = (last or "").strip()[:10] if last else ""
59
+ return first_date, last_date
60
+
61
+
62
+ def _total_commits(repo_root: Path) -> int:
63
+ out = _run_git(["rev-list", "--count", "HEAD"], repo_root)
64
+ try:
65
+ return int((out or "0").strip())
66
+ except ValueError:
67
+ return 0
68
+
69
+
70
+ def compute_git_churn(
71
+ project_root: Path,
72
+ *,
73
+ top_n: int = 15,
74
+ since: str = "",
75
+ src_only: bool = True,
76
+ ) -> dict[str, Any]:
77
+ """Compute file-level git churn metrics for a repository.
78
+
79
+ Args:
80
+ project_root: repository root.
81
+ top_n: number of highest-churn files to surface.
82
+ since: optional git date filter (e.g. ``"6 months ago"``).
83
+ src_only: when True, restrict results to files under ``src/``.
84
+
85
+ Returns a structured dict with ``schema_version``, ``hotspot_files``,
86
+ ``stable_files``, ``total_commits``, ``churn_period``, plus aggregate
87
+ stats. Returns a minimal error dict if git is unavailable.
88
+ """
89
+ root = Path(project_root).resolve()
90
+ counts = _commit_count_per_file(root, since=since)
91
+ if not counts:
92
+ return {
93
+ "schema_version": SCHEMA_VERSION_GIT_CHURN_V1,
94
+ "available": False,
95
+ "reason": "no git history or git not available",
96
+ }
97
+
98
+ if src_only:
99
+ counts = {p: c for p, c in counts.items() if p.startswith("src/")}
100
+
101
+ total = _total_commits(root)
102
+ first_date, last_date = _first_and_last_commit_date(root)
103
+
104
+ sorted_files = sorted(counts.items(), key=lambda x: -x[1])
105
+ hotspots = [
106
+ {"path": p, "commits": c} for p, c in sorted_files[:top_n]
107
+ ]
108
+ stable = [
109
+ {"path": p, "commits": c}
110
+ for p, c in sorted_files[::-1][:top_n]
111
+ if c <= 2
112
+ ]
113
+
114
+ avg_churn = sum(counts.values()) / len(counts) if counts else 0.0
115
+ median_churn = sorted(counts.values())[len(counts) // 2] if counts else 0
116
+
117
+ return {
118
+ "schema_version": SCHEMA_VERSION_GIT_CHURN_V1,
119
+ "available": True,
120
+ "total_commits": total,
121
+ "files_tracked": len(counts),
122
+ "churn_period": since or "all time",
123
+ "first_commit_date": first_date,
124
+ "last_commit_date": last_date,
125
+ "avg_commits_per_file": round(avg_churn, 2),
126
+ "median_commits_per_file": median_churn,
127
+ "hotspot_files": hotspots,
128
+ "stable_files": stable[:top_n],
129
+ }
@@ -19,7 +19,7 @@ consume on first connect:
19
19
 
20
20
  Tools (v0.47.0 — 8 tools, 64 actions + create):
21
21
  welcome — first-call handshake (no action param)
22
- explore — codebase analysis + discovery (action=recon|explain|call_graph|smell_scan|lineage|harvest|synergy|scan|swarm)
22
+ explore — codebase analysis + discovery (action=recon|explain|call_graph|call_graph_summary|smell_scan|churn|lineage|harvest|synergy|scan|swarm)
23
23
  audit — quality gates + change safety (action=certify|wire|enforce|validate|guard|composite|gate|health|check|score|tests|cna|rollback|diff)
24
24
  plan — orient + plan + execute (action=context|compose|policy|recipes|generate|apply|locate|commit|iterate|resume|evolve|evolve_step|auto|cherry|finalize|scaffold)
25
25
  hive — multi-agent coordination (action=register|list|deactivate|observe|propose|vote|needs_vote|result|recap|handoff_create|handoff_list|enhance_propose|enhance_list)
@@ -1131,6 +1131,29 @@ def _tool_call_graph(project_root: Path, args: dict[str, Any]) -> dict[str, Any]
1131
1131
  return build_call_graph(merged_args)
1132
1132
 
1133
1133
 
1134
+ def _tool_call_graph_summary(project_root: Path, args: dict[str, Any]) -> dict[str, Any]:
1135
+ """Whole-package call-graph portfolio: orphans, hotspots, max depth.
1136
+ Synthesised from pyan whole-graph analysis concepts."""
1137
+ from .call_graph import build_call_graph_summary
1138
+ merged_args = dict(args)
1139
+ if "project_root" not in merged_args:
1140
+ merged_args["project_root"] = str(project_root)
1141
+ return build_call_graph_summary(merged_args)
1142
+
1143
+
1144
+ def _tool_git_churn(project_root: Path, args: dict[str, Any]) -> dict[str, Any]:
1145
+ """File-level git churn metrics: hotspot files, stable files, commit
1146
+ frequency distribution. Synthesised from Repomix git-log concepts."""
1147
+ from .git_churn import compute_git_churn
1148
+ root = Path(args.get("project_root", project_root)).resolve()
1149
+ return compute_git_churn(
1150
+ root,
1151
+ top_n=int(args.get("top_n", 15)),
1152
+ since=str(args.get("since", "")),
1153
+ src_only=bool(args.get("src_only", True)),
1154
+ )
1155
+
1156
+
1134
1157
  def _tool_smell_scan(project_root: Path, args: dict[str, Any]) -> dict[str, Any]:
1135
1158
  """Run code-smell detection (cyclomatic complexity + long functions
1136
1159
  + duplicated bodies). Pure: composes the a1 ``smell_scan`` walker."""
@@ -2016,14 +2039,17 @@ def _tool_plan_merged(project_root: Path, args: dict[str, Any]) -> dict[str, Any
2016
2039
 
2017
2040
 
2018
2041
  def _tool_code_intel(project_root: Path, args: dict[str, Any]) -> dict[str, Any]:
2019
- """Merged code intelligence: call_graph/smell_scan."""
2042
+ """Merged code intelligence: call_graph/call_graph_summary/smell_scan."""
2020
2043
  action = str(args.get("action", ""))
2021
2044
  inner = {k: v for k, v in args.items() if k != "action"}
2022
2045
  if action == "call_graph":
2023
2046
  return _tool_call_graph(project_root, inner)
2047
+ elif action == "call_graph_summary":
2048
+ return _tool_call_graph_summary(project_root, inner)
2024
2049
  elif action == "smell_scan":
2025
2050
  return _tool_smell_scan(project_root, inner)
2026
- return {"error": f"Unknown action {action!r}", "valid_actions": ["call_graph", "smell_scan"]}
2051
+ return {"error": f"Unknown action {action!r}",
2052
+ "valid_actions": ["call_graph", "call_graph_summary", "smell_scan"]}
2027
2053
 
2028
2054
 
2029
2055
  def _tool_preflight_merged(project_root: Path, args: dict[str, Any]) -> dict[str, Any]:
@@ -2121,7 +2147,7 @@ def _tool_discover(project_root: Path, args: dict[str, Any]) -> dict[str, Any]:
2121
2147
 
2122
2148
  def _tool_explore(project_root: Path, args: dict[str, Any]) -> dict[str, Any]:
2123
2149
  """Merged exploration + discovery:
2124
- recon/explain/call_graph/smell_scan/lineage/harvest/synergy/scan/swarm."""
2150
+ recon/explain/call_graph/call_graph_summary/smell_scan/churn/lineage/harvest/synergy/scan/swarm."""
2125
2151
  action = str(args.get("action", "recon"))
2126
2152
  inner = {k: v for k, v in args.items() if k != "action"}
2127
2153
  if action == "recon":
@@ -2132,8 +2158,12 @@ def _tool_explore(project_root: Path, args: dict[str, Any]) -> dict[str, Any]:
2132
2158
  return _tool_explain_repo(project_root, inner)
2133
2159
  elif action == "call_graph":
2134
2160
  return _tool_call_graph(project_root, inner)
2161
+ elif action == "call_graph_summary":
2162
+ return _tool_call_graph_summary(project_root, inner)
2135
2163
  elif action == "smell_scan":
2136
2164
  return _tool_smell_scan(project_root, inner)
2165
+ elif action == "churn":
2166
+ return _tool_git_churn(project_root, inner)
2137
2167
  elif action == "lineage":
2138
2168
  return _tool_lineage(project_root, inner)
2139
2169
  # discover actions
@@ -2147,7 +2177,8 @@ def _tool_explore(project_root: Path, args: dict[str, Any]) -> dict[str, Any]:
2147
2177
  inner["action"] = action
2148
2178
  return _tool_emergent(project_root, inner)
2149
2179
  return {"error": f"Unknown action {action!r}",
2150
- "valid_actions": ["recon", "explain", "call_graph", "smell_scan", "lineage",
2180
+ "valid_actions": ["recon", "explain", "call_graph", "call_graph_summary",
2181
+ "smell_scan", "churn", "lineage",
2151
2182
  "harvest", "synergy", "scan", "swarm"]}
2152
2183
 
2153
2184
 
@@ -2363,7 +2394,9 @@ TOOLS: dict[str, dict[str, Any]] = {
2363
2394
  "action='recon' (default): maps every public symbol into the 5 monadic tiers. "
2364
2395
  "action='explain': plain-English orientation — one-liner, core flow, do_not_break. "
2365
2396
  "action='call_graph': AST BFS walk — callers/callees of a target symbol. "
2397
+ "action='call_graph_summary': whole-package portfolio — orphans, hotspots, max depth. "
2366
2398
  "action='smell_scan': CC monsters, long functions, dup bodies (smell_score 0-100). "
2399
+ "action='churn': file-level git churn — hotspot/stable files, avg/median commits. "
2367
2400
  "action='lineage': query the .atomadic-forge lineage log (mode=all/by_file/failed_for_area). "
2368
2401
  "action='harvest': cross-repo cherry-hunter — diffs target vs source repos, "
2369
2402
  "ranks graft candidates by trust-gated confidence (max-depth 23, no LLM). "
@@ -2377,12 +2410,14 @@ TOOLS: dict[str, dict[str, Any]] = {
2377
2410
  "properties": {
2378
2411
  "action": {
2379
2412
  "type": "string",
2380
- "enum": ["recon", "explain", "call_graph", "smell_scan", "lineage",
2413
+ "enum": ["recon", "explain", "call_graph", "call_graph_summary",
2414
+ "smell_scan", "churn", "lineage",
2381
2415
  "harvest", "synergy", "scan", "swarm"],
2382
2416
  "default": "recon",
2383
2417
  "description": (
2384
2418
  "'recon' — tier map; 'explain' — narrative; "
2385
- "'call_graph' — symbol graph; 'smell_scan' — code smell; "
2419
+ "'call_graph' — symbol graph; 'call_graph_summary' — package portfolio; "
2420
+ "'smell_scan' — code smell; 'churn' — git file churn; "
2386
2421
  "'lineage' — audit log; 'harvest' — cross-repo grafts; "
2387
2422
  "'synergy' — composition patterns; "
2388
2423
  "'scan' — single-repo emergent; 'swarm' — multi-repo emergent."
@@ -2419,6 +2454,11 @@ TOOLS: dict[str, dict[str, Any]] = {
2419
2454
  "description": "[smell_scan] Optional subdir under project_root."},
2420
2455
  "top_n_findings": {"type": "integer", "default": 20,
2421
2456
  "description": "[smell_scan] Cap findings per category (0=unlimited)."},
2457
+ # churn params
2458
+ "since": {"type": "string", "default": "",
2459
+ "description": "[churn] Git date filter (e.g. '6 months ago'). Empty = all time."},
2460
+ "src_only": {"type": "boolean", "default": True,
2461
+ "description": "[churn/call_graph_summary] Restrict to src/ files only."},
2422
2462
  # lineage params
2423
2463
  "mode": {"type": "string", "enum": ["all", "by_file", "failed_for_area"],
2424
2464
  "default": "all", "description": "[lineage] Query mode."},
@@ -3121,6 +3161,8 @@ _CLI_FALLBACKS: dict[str, str] = {
3121
3161
  "forge recon <repo> --json (action=recon) | "
3122
3162
  "forge explain-repo <project-root> (action=explain) | "
3123
3163
  "forge call-graph <qualname> --project-root <repo> --json (action=call_graph) | "
3164
+ "forge call-graph-summary --project <repo> --json (action=call_graph_summary) | "
3165
+ "forge churn --project <repo> --json (action=churn) | "
3124
3166
  "forge smell-scan --project-root <repo> --json (action=smell_scan) | "
3125
3167
  "forge surface list/show/log (action=lineage)"
3126
3168
  ),
@@ -3201,6 +3243,8 @@ _CLI_FALLBACKS: dict[str, str] = {
3201
3243
  ),
3202
3244
  "code_intel": (
3203
3245
  "forge call-graph <qualname> --project-root <repo> --json — use explore(action=call_graph) via MCP | "
3246
+ "forge call-graph-summary --project <repo> --json — use explore(action=call_graph_summary) via MCP | "
3247
+ "forge churn --project <repo> --json — use explore(action=churn) via MCP | "
3204
3248
  "forge smell-scan --project-root <repo> --json — use explore(action=smell_scan) via MCP"
3205
3249
  ),
3206
3250
  "forge_util": (
@@ -1217,6 +1217,85 @@ def call_graph_cmd(
1217
1217
  typer.echo(" (no edges found — check that qualname and package are correct)")
1218
1218
 
1219
1219
 
1220
+ @app.command("call-graph-summary")
1221
+ def call_graph_summary_cmd(
1222
+ project_root: Annotated[Path, typer.Option(
1223
+ "--project",
1224
+ exists=True, file_okay=False, dir_okay=True, resolve_path=True,
1225
+ help="Project root.")] = Path("."),
1226
+ package: Annotated[str | None, typer.Option(
1227
+ "--package", help="Python package name.")] = None,
1228
+ top_n: Annotated[int, typer.Option(
1229
+ "--top-n", help="Max hotspots / orphans to surface.")] = 10,
1230
+ json_out: Annotated[bool, typer.Option("--json")] = False,
1231
+ ) -> None:
1232
+ """Whole-package call-graph portfolio: orphans, hotspots, max depth."""
1233
+ from ..a1_at_functions.call_graph import build_call_graph_summary
1234
+ report = build_call_graph_summary({
1235
+ "project_root": str(project_root),
1236
+ "package": package,
1237
+ "top_n": top_n,
1238
+ })
1239
+ if json_out:
1240
+ typer.echo(json.dumps(report, indent=2, default=str))
1241
+ return
1242
+ typer.echo(f"\nForge call-graph-summary: {project_root}")
1243
+ typer.echo("-" * 60)
1244
+ typer.echo(f" package: {report.get('package', '?')}")
1245
+ typer.echo(f" total_callers: {report.get('total_callers', '?')}")
1246
+ typer.echo(f" total_edges: {report.get('total_edges', '?')}")
1247
+ typer.echo(f" max_call_depth: {report.get('max_call_depth', '?')}")
1248
+ typer.echo(f" uncalled_callers: {report.get('uncalled_callers_count', '?')}")
1249
+ hotspots = report.get("hotspots", [])
1250
+ if hotspots:
1251
+ typer.echo(f" hotspots (top {len(hotspots)}):")
1252
+ for h in hotspots:
1253
+ typer.echo(f" [{h.get('fan_in', 0):>3} calls in] {h.get('qualname', '?')}")
1254
+
1255
+
1256
+ @app.command("churn")
1257
+ def churn_cmd(
1258
+ project_root: Annotated[Path, typer.Option(
1259
+ "--project",
1260
+ exists=True, file_okay=False, dir_okay=True, resolve_path=True,
1261
+ help="Project root (must be a git repo).")] = Path("."),
1262
+ since: Annotated[str, typer.Option(
1263
+ "--since", help="Git date filter, e.g. '6 months ago'.")] = "",
1264
+ top_n: Annotated[int, typer.Option(
1265
+ "--top-n", help="Hotspot / stable files to surface.")] = 15,
1266
+ all_files: Annotated[bool, typer.Option(
1267
+ "--all-files", help="Include all files, not just src/.")] = False,
1268
+ json_out: Annotated[bool, typer.Option("--json")] = False,
1269
+ ) -> None:
1270
+ """Git churn analysis — which files change most / least often."""
1271
+ from ..a1_at_functions.git_churn import compute_git_churn
1272
+ report = compute_git_churn(
1273
+ project_root, top_n=top_n, since=since, src_only=not all_files
1274
+ )
1275
+ if json_out:
1276
+ typer.echo(json.dumps(report, indent=2, default=str))
1277
+ return
1278
+ if not report.get("available"):
1279
+ typer.echo(f"Git churn unavailable: {report.get('reason', 'unknown')}")
1280
+ return
1281
+ typer.echo(f"\nForge churn: {project_root}")
1282
+ typer.echo("-" * 60)
1283
+ typer.echo(f" period: {report['churn_period']}")
1284
+ typer.echo(f" total_commits: {report['total_commits']}")
1285
+ typer.echo(f" files_tracked: {report['files_tracked']}")
1286
+ typer.echo(f" avg commits/file: {report['avg_commits_per_file']}")
1287
+ hotspots = report.get("hotspot_files", [])
1288
+ if hotspots:
1289
+ typer.echo(f" hotspot files (top {len(hotspots)}):")
1290
+ for h in hotspots:
1291
+ typer.echo(f" [{h['commits']:>4}] {h['path']}")
1292
+ stable = report.get("stable_files", [])
1293
+ if stable:
1294
+ typer.echo(f" stable files (≤2 commits, top {len(stable)}):")
1295
+ for s in stable:
1296
+ typer.echo(f" [{s['commits']:>4}] {s['path']}")
1297
+
1298
+
1220
1299
  @app.command("cna-check")
1221
1300
  def cna_check_cmd(
1222
1301
  proposed_name: Annotated[str, typer.Argument(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atomadic-forge
3
- Version: 0.52.1
3
+ Version: 0.53.0
4
4
  Summary: Atomadic Forge — absorb, enforce, emerge. Polyglot (Python · JavaScript/TypeScript · Rust · Go · Swift · Kotlin) architecture guardian for AI-generated code.
5
5
  Author: Atomadic
6
6
  License-Expression: BUSL-1.1
@@ -173,6 +173,7 @@ src/atomadic_forge/a1_at_functions/forge_feedback.py
173
173
  src/atomadic_forge/a1_at_functions/forge_locate.py
174
174
  src/atomadic_forge/a1_at_functions/forge_metrics.py
175
175
  src/atomadic_forge/a1_at_functions/generation_quality.py
176
+ src/atomadic_forge/a1_at_functions/git_churn.py
176
177
  src/atomadic_forge/a1_at_functions/handoff_builder.py
177
178
  src/atomadic_forge/a1_at_functions/harvest_absorb.py
178
179
  src/atomadic_forge/a1_at_functions/hive_consensus_math.py
@@ -329,6 +330,7 @@ tests/test_agent_plan_pkg_label.py
329
330
  tests/test_agent_summary.py
330
331
  tests/test_audit_verb.py
331
332
  tests/test_body_extractor_repairs.py
333
+ tests/test_call_graph_summary.py
332
334
  tests/test_card_renderer.py
333
335
  tests/test_certify_operational_axis.py
334
336
  tests/test_chat.py
@@ -362,6 +364,7 @@ tests/test_forge_auth_a1.py
362
364
  tests/test_forge_auth_a2.py
363
365
  tests/test_forge_enforce.py
364
366
  tests/test_generation_quality.py
367
+ tests/test_git_churn.py
365
368
  tests/test_handoff.py
366
369
  tests/test_hierarchical_memory.py
367
370
  tests/test_hive_sync.py