atomadic-forge 0.58.0__tar.gz → 0.60.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 (451) hide show
  1. {atomadic_forge-0.58.0/src/atomadic_forge.egg-info → atomadic_forge-0.60.0}/PKG-INFO +1 -1
  2. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/pyproject.toml +1 -1
  3. atomadic_forge-0.60.0/src/atomadic_forge/a1_at_functions/abstract_method_repair.py +333 -0
  4. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/cherry_pick.py +24 -1
  5. atomadic_forge-0.60.0/src/atomadic_forge/a1_at_functions/scaffold_starter.py +268 -0
  6. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/stub_detector.py +25 -4
  7. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/forge_pipeline.py +145 -0
  8. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0/src/atomadic_forge.egg-info}/PKG-INFO +1 -1
  9. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge.egg-info/SOURCES.txt +4 -0
  10. atomadic_forge-0.60.0/tests/test_abstract_method_repair.py +122 -0
  11. atomadic_forge-0.60.0/tests/test_cherry_pick.py +68 -0
  12. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_cli_smoke.py +33 -0
  13. atomadic_forge-0.60.0/tests/test_finalize_scaffold.py +110 -0
  14. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_stub_detector.py +55 -2
  15. atomadic_forge-0.58.0/src/atomadic_forge/a1_at_functions/scaffold_starter.py +0 -167
  16. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/FUNDING.yml +0 -0
  17. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  18. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  19. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  20. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/actions/forge-action/README.md +0 -0
  21. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/actions/forge-action/action.yml +0 -0
  22. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/dependabot.yml +0 -0
  23. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/pull_request_template.md +0 -0
  24. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/workflows/ci.yml +0 -0
  25. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/workflows/customer-refactor.yml +0 -0
  26. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/workflows/forge-self-certify.yml +0 -0
  27. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/workflows/mcp-registry-publish.yml +0 -0
  28. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/workflows/metrics-auto-regen.yml +0 -0
  29. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/workflows/metrics-drift.yml +0 -0
  30. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/workflows/publish-on-tag.yml +0 -0
  31. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/workflows/release-readiness.yml +0 -0
  32. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/workflows/release.yml +0 -0
  33. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/workflows/surface-drift.yml +0 -0
  34. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/.github/workflows/uptime.yml +0 -0
  35. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/ARCHITECTURE.md +0 -0
  36. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/CHANGELOG.md +0 -0
  37. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/CONTRIBUTING.md +0 -0
  38. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/LICENSE +0 -0
  39. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/MANIFEST.in +0 -0
  40. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/README.md +0 -0
  41. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/SECURITY.md +0 -0
  42. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/assets/Atomadic-Forge-01.png +0 -0
  43. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/01-getting-started.md +0 -0
  44. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/02-commands.md +0 -0
  45. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/03-tutorial.md +0 -0
  46. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/04-llm-loops.md +0 -0
  47. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/05-faq.md +0 -0
  48. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/AGENTS_GUIDE.md +0 -0
  49. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/AIR_GAPPED.md +0 -0
  50. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/CI_CD.md +0 -0
  51. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/CODEX_WALKTHROUGH.md +0 -0
  52. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/COMMANDS.md +0 -0
  53. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/FIRST_10_MINUTES.md +0 -0
  54. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/FORMALIZATION.md +0 -0
  55. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/HIVE_PRIMITIVES.md +0 -0
  56. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/HIVE_STATUS.md +0 -0
  57. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/IDE_INTEGRATION.md +0 -0
  58. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/LANDSCAPE.md +0 -0
  59. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/MARKET_POSITIONING.md +0 -0
  60. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/MCP_TOOLS.md +0 -0
  61. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/MIGRATION.md +0 -0
  62. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/MULTI_REPO.md +0 -0
  63. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/PROVIDERS.md +0 -0
  64. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/README.md +0 -0
  65. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/RECEIPT.md +0 -0
  66. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/RELAY_PROTOCOL.md +0 -0
  67. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/RELEASE_CHECKLIST.md +0 -0
  68. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/RELEASE_MESSAGING.md +0 -0
  69. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/ROADMAP.md +0 -0
  70. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/SHOWCASE.md +0 -0
  71. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/SIDECAR.md +0 -0
  72. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/STUDIO.md +0 -0
  73. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/TOOL_FACTORY_WALKTHROUGH.md +0 -0
  74. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/V0.46.0_JUSTIFICATION_REPORT.md +0 -0
  75. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/V0.47.0_SELF_TEST_REPORT.md +0 -0
  76. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/WHY_NOW.md +0 -0
  77. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/WORKER_VS_LOCAL_MCP.md +0 -0
  78. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/WORLD_COLLISION.md +0 -0
  79. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/INDEX.md +0 -0
  80. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/absorb.md +0 -0
  81. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/audit.md +0 -0
  82. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/chat.md +0 -0
  83. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/commandsmith.md +0 -0
  84. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/config.md +0 -0
  85. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/create.md +0 -0
  86. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/demo.md +0 -0
  87. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/emergent-swarm.md +0 -0
  88. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/emergent-then-synergy.md +0 -0
  89. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/emergent.md +0 -0
  90. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/enhancement.md +0 -0
  91. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/evolve-then-iterate.md +0 -0
  92. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/evolve.md +0 -0
  93. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/feature-then-emergent.md +0 -0
  94. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/guard-install.md +0 -0
  95. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/handoff.md +0 -0
  96. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/harvest.md +0 -0
  97. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/hive.md +0 -0
  98. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/iterate.md +0 -0
  99. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/materialize.md +0 -0
  100. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/metrics.md +0 -0
  101. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/recon-swarm.md +0 -0
  102. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/relay.md +0 -0
  103. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/surface.md +0 -0
  104. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/synergy-then-emergent.md +0 -0
  105. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/synergy.md +0 -0
  106. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/welcome.md +0 -0
  107. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/commands/wisdom.md +0 -0
  108. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/compliance/CMMC_AI_MAPPING.md +0 -0
  109. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/compliance/CS-1.md +0 -0
  110. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/compliance/EU_AI_ACT_ANNEX_IV.md +0 -0
  111. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/compliance/FDA_PCCP_MAPPING.md +0 -0
  112. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/compliance/SR_11-7_MAPPING.md +0 -0
  113. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/handoffs/WORKER_AUTO_DEPLOY_2026-05-06.md +0 -0
  114. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/tutorials/01-quickstart.md +0 -0
  115. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/tutorials/02-your-first-package.md +0 -0
  116. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/tutorials/03-the-five-tier-law.md +0 -0
  117. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/tutorials/04-plug-in-llms.md +0 -0
  118. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/tutorials/05-multi-repo-absorb.md +0 -0
  119. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/docs/tutorials/06-javascript-quickstart.md +0 -0
  120. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/setup.cfg +0 -0
  121. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/__init__.py +0 -0
  122. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/__main__.py +0 -0
  123. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/__init__.py +0 -0
  124. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/agent_plan_schema.py +0 -0
  125. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/auth_constants.py +0 -0
  126. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/commandsmith_types.py +0 -0
  127. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/config_defaults.py +0 -0
  128. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/emergent_types.py +0 -0
  129. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/enhancement_proposal_constants.py +0 -0
  130. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/error_codes.py +0 -0
  131. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/forge_types.py +0 -0
  132. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/gen_language.py +0 -0
  133. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/handoff_constants.py +0 -0
  134. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/hive_constants.py +0 -0
  135. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/lang_extensions.py +0 -0
  136. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/lifetime_savings_constants.py +0 -0
  137. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/materialize_types.py +0 -0
  138. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/mhed_invariants.py +0 -0
  139. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/nexus_constants.py +0 -0
  140. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/policy_schema.py +0 -0
  141. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/receipt_schema.py +0 -0
  142. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/response_enrichment.py +0 -0
  143. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/roi_constants.py +0 -0
  144. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/schema_version_registry.py +0 -0
  145. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/semantic_types.py +0 -0
  146. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/sidecar_schema.py +0 -0
  147. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/synergy_types.py +0 -0
  148. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/tier_names.py +0 -0
  149. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/welcome_constants.py +0 -0
  150. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a0_qk_constants/wisdom_constants.py +0 -0
  151. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/__init__.py +0 -0
  152. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/agent_context_pack.py +0 -0
  153. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/agent_memory.py +0 -0
  154. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/agent_plan_emitter.py +0 -0
  155. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/agent_summary.py +0 -0
  156. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/ast_scope_lock.py +0 -0
  157. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/body_extractor.py +0 -0
  158. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/call_graph.py +0 -0
  159. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/capability_scout.py +0 -0
  160. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/card_renderer.py +0 -0
  161. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/certify_checks.py +0 -0
  162. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/chat_context.py +0 -0
  163. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/classify_tier.py +0 -0
  164. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/code_signature.py +0 -0
  165. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/commandsmith_discover.py +0 -0
  166. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/commandsmith_render.py +0 -0
  167. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/compiler_feedback.py +0 -0
  168. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/compliance_checker.py +0 -0
  169. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/config_io.py +0 -0
  170. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/cs1_renderer.py +0 -0
  171. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/custom_provider_client.py +0 -0
  172. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/dead_code_check.py +0 -0
  173. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/doc_auto_update.py +0 -0
  174. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/doc_synthesizer.py +0 -0
  175. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/emergent_compose.py +0 -0
  176. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/emergent_rank.py +0 -0
  177. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/emergent_signature_extract.py +0 -0
  178. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/emergent_synthesize.py +0 -0
  179. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/enforce_planner.py +0 -0
  180. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/enhancement_proposal_builder.py +0 -0
  181. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/error_hints.py +0 -0
  182. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/evolution_log.py +0 -0
  183. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/exported_api_check.py +0 -0
  184. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/forge_auth.py +0 -0
  185. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/forge_feedback.py +0 -0
  186. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/forge_locate.py +0 -0
  187. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/forge_metrics.py +0 -0
  188. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/generation_quality.py +0 -0
  189. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/git_churn.py +0 -0
  190. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/handoff_builder.py +0 -0
  191. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/harvest_absorb.py +0 -0
  192. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/harvest_concept_bridge.py +0 -0
  193. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/hive_consensus_math.py +0 -0
  194. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/hive_io.py +0 -0
  195. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/import_repair.py +0 -0
  196. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/import_smoke.py +0 -0
  197. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/intent_similarity.py +0 -0
  198. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/js_parser.py +0 -0
  199. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/lifetime_savings.py +0 -0
  200. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/lineage_chain.py +0 -0
  201. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/lineage_reader.py +0 -0
  202. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/llm_client.py +0 -0
  203. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/local_signer.py +0 -0
  204. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/lsp_protocol.py +0 -0
  205. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/maintainability_index.py +0 -0
  206. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/manifest_diff.py +0 -0
  207. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/mcp_protocol.py +0 -0
  208. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/patch_scorer.py +0 -0
  209. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/plan_adapter.py +0 -0
  210. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/policy_loader.py +0 -0
  211. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/polyglot_classify.py +0 -0
  212. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/polyglot_imports.py +0 -0
  213. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/polyglot_surface.py +0 -0
  214. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/preflight_change.py +0 -0
  215. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/progress_reporter.py +0 -0
  216. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/provider_detect.py +0 -0
  217. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/provider_resolver.py +0 -0
  218. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/receipt_emitter.py +0 -0
  219. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/recipes.py +0 -0
  220. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/repo_explainer.py +0 -0
  221. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/research_note_distiller.py +0 -0
  222. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/response_enricher.py +0 -0
  223. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/roi_calculator.py +0 -0
  224. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/rollback_planner.py +0 -0
  225. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/sbom_emitter.py +0 -0
  226. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/scaffold_js.py +0 -0
  227. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/scaffold_polyglot.py +0 -0
  228. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/scaffold_pyproject.py +0 -0
  229. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/scout_walk.py +0 -0
  230. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/sidecar_parser.py +0 -0
  231. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/sidecar_validator.py +0 -0
  232. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/smell_scan.py +0 -0
  233. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/steersman_pack.py +0 -0
  234. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/surface_gap_check.py +0 -0
  235. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/synergy_detect.py +0 -0
  236. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/synergy_render.py +0 -0
  237. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/synergy_surface_extract.py +0 -0
  238. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/test_runner.py +0 -0
  239. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/test_selector.py +0 -0
  240. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/tier_init_rebuild.py +0 -0
  241. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/tool_composer.py +0 -0
  242. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/transcript_log.py +0 -0
  243. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/trust_gate_response.py +0 -0
  244. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/validation_commands.py +0 -0
  245. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/welcome_narrator.py +0 -0
  246. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/wire_check.py +0 -0
  247. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/wire_stubs_gen.py +0 -0
  248. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/wisdom_capture.py +0 -0
  249. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/wisdom_io.py +0 -0
  250. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/wisdom_promote.py +0 -0
  251. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/wisdom_recall.py +0 -0
  252. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a1_at_functions/worktree_status.py +0 -0
  253. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/__init__.py +0 -0
  254. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/cost_circuit_breaker.py +0 -0
  255. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/cross_agent_intent_deduplicator.py +0 -0
  256. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/evolve_session_store.py +0 -0
  257. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/forge_auth_client.py +0 -0
  258. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/hierarchical_memory.py +0 -0
  259. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/iterate_session_store.py +0 -0
  260. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/lineage_chain_store.py +0 -0
  261. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/manifest_store.py +0 -0
  262. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/nexus_client.py +0 -0
  263. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/plan_store.py +0 -0
  264. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/receipt_signer.py +0 -0
  265. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a2_mo_composites/remote_seed_store.py +0 -0
  266. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/__init__.py +0 -0
  267. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/absorb_feature.py +0 -0
  268. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/agent_hire_protocol.py +0 -0
  269. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/cherry_hunter.py +0 -0
  270. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/cna_check.py +0 -0
  271. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/commandsmith_feature.py +0 -0
  272. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/commit_compose.py +0 -0
  273. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/create_feature.py +0 -0
  274. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/dedup_engine.py +0 -0
  275. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/__init__.py +0 -0
  276. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/a0_qk_constants/__init__.py +0 -0
  277. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/a1_at_functions/__init__.py +0 -0
  278. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/tests/conftest.py +0 -0
  279. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/tests/test_mixed.py +0 -0
  280. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/demo_runner.py +0 -0
  281. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/emergent_feature.py +0 -0
  282. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/emergent_pipeline_integration.py +0 -0
  283. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/emergent_swarm.py +0 -0
  284. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/enhancement_proposal_feature.py +0 -0
  285. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/forge_enforce.py +0 -0
  286. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/forge_evolve.py +0 -0
  287. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/forge_evolve_session.py +0 -0
  288. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/forge_loop.py +0 -0
  289. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/forge_loop_session.py +0 -0
  290. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/forge_metrics_feature.py +0 -0
  291. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/forge_plan_apply.py +0 -0
  292. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/guard_install.py +0 -0
  293. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/handoff_feature.py +0 -0
  294. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/hive_sync.py +0 -0
  295. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/lsp_server.py +0 -0
  296. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/materialize_feature.py +0 -0
  297. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/mcp_server.py +0 -0
  298. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/nexus_bridge.py +0 -0
  299. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/relay_daemon.py +0 -0
  300. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/setup_wizard.py +0 -0
  301. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/surface_export.py +0 -0
  302. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/synergy_feature.py +0 -0
  303. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/tool_factory.py +0 -0
  304. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/verify_umbrella.py +0 -0
  305. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/welcome_feature.py +0 -0
  306. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a3_og_features/wisdom_feature.py +0 -0
  307. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a4_sy_orchestration/__init__.py +0 -0
  308. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a4_sy_orchestration/cli.py +0 -0
  309. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a4_sy_orchestration/copilots_cmd.py +0 -0
  310. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a4_sy_orchestration/login_cmd.py +0 -0
  311. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/a4_sy_orchestration/whoami_cmd.py +0 -0
  312. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/__init__.py +0 -0
  313. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/_registry.py +0 -0
  314. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/absorb.py +0 -0
  315. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/audit.py +0 -0
  316. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/chat.py +0 -0
  317. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/commandsmith.py +0 -0
  318. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/config_cmd.py +0 -0
  319. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/create.py +0 -0
  320. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/demo.py +0 -0
  321. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/emergent.py +0 -0
  322. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/emergent_swarm.py +0 -0
  323. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/emergent_then_synergy.py +0 -0
  324. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/enhancement.py +0 -0
  325. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/evolve.py +0 -0
  326. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/evolve_then_iterate.py +0 -0
  327. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/feature_then_emergent.py +0 -0
  328. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/guard_install.py +0 -0
  329. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/handoff.py +0 -0
  330. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/harvest.py +0 -0
  331. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/hive.py +0 -0
  332. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/iterate.py +0 -0
  333. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/materialize.py +0 -0
  334. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/metrics.py +0 -0
  335. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/recon_swarm.py +0 -0
  336. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/relay.py +0 -0
  337. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/surface.py +0 -0
  338. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/synergy.py +0 -0
  339. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/synergy_then_emergent.py +0 -0
  340. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/welcome.py +0 -0
  341. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge/commands/wisdom.py +0 -0
  342. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge.egg-info/dependency_links.txt +0 -0
  343. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge.egg-info/entry_points.txt +0 -0
  344. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge.egg-info/requires.txt +0 -0
  345. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/src/atomadic_forge.egg-info/top_level.txt +0 -0
  346. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_aaaa_nexus_client.py +0 -0
  347. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_agent_hire_protocol.py +0 -0
  348. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_agent_plan.py +0 -0
  349. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_agent_plan_pkg_label.py +0 -0
  350. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_agent_summary.py +0 -0
  351. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_ast_scope_lock.py +0 -0
  352. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_audit_verb.py +0 -0
  353. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_body_extractor_repairs.py +0 -0
  354. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_call_graph_summary.py +0 -0
  355. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_capability_scout.py +0 -0
  356. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_card_renderer.py +0 -0
  357. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_certify_operational_axis.py +0 -0
  358. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_chat.py +0 -0
  359. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_classify_tier.py +0 -0
  360. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_classify_tier_ast_signals.py +0 -0
  361. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_cli_swarm_aliases.py +0 -0
  362. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_codex_5_complete.py +0 -0
  363. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_codex_6_enforce_polyglot.py +0 -0
  364. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_commandsmith.py +0 -0
  365. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_compiler_feedback.py +0 -0
  366. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_compliance_checker.py +0 -0
  367. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_config.py +0 -0
  368. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_copilots_copilot.py +0 -0
  369. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_cost_circuit_breaker.py +0 -0
  370. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_create_feature.py +0 -0
  371. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_cs1_renderer.py +0 -0
  372. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_custom_provider.py +0 -0
  373. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_dead_code_check.py +0 -0
  374. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_dedup_engine.py +0 -0
  375. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_demo.py +0 -0
  376. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_doc_auto_update.py +0 -0
  377. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_emergent_compose.py +0 -0
  378. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_emergent_signature_extract.py +0 -0
  379. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_emergent_synthesize_imports.py +0 -0
  380. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_enhancement_proposal.py +0 -0
  381. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_error_codes.py +0 -0
  382. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_error_hints.py +0 -0
  383. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_evolve_js.py +0 -0
  384. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_exported_api_check.py +0 -0
  385. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_forge_action.py +0 -0
  386. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_forge_auth_a1.py +0 -0
  387. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_forge_auth_a2.py +0 -0
  388. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_forge_enforce.py +0 -0
  389. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_generation_quality.py +0 -0
  390. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_git_churn.py +0 -0
  391. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_handoff.py +0 -0
  392. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_harvest_concept_bridge.py +0 -0
  393. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_hierarchical_memory.py +0 -0
  394. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_hive_sync.py +0 -0
  395. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_ignore_and_docs.py +0 -0
  396. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_import_smoke.py +0 -0
  397. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_iterate_evolve.py +0 -0
  398. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_js_certify.py +0 -0
  399. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_js_parser.py +0 -0
  400. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_js_recon.py +0 -0
  401. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_js_wire.py +0 -0
  402. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_lineage_chain.py +0 -0
  403. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_ling_provider.py +0 -0
  404. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_local_signer.py +0 -0
  405. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_lsp_protocol.py +0 -0
  406. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_maintainability_index.py +0 -0
  407. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_manifest_diff.py +0 -0
  408. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_materialize_feature.py +0 -0
  409. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_mcp_lazy_bootstrap.py +0 -0
  410. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_mcp_protocol.py +0 -0
  411. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_nexus_bridge.py +0 -0
  412. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_ollama_client.py +0 -0
  413. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_pipeline.py +0 -0
  414. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_plan_apply.py +0 -0
  415. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_polyglot_cli_mcp.py +0 -0
  416. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_polyglot_full_pipeline.py +0 -0
  417. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_polyglot_hardening.py +0 -0
  418. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_polyglot_swift_kotlin_go.py +0 -0
  419. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_polyglot_symbol_parity.py +0 -0
  420. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_pre_audit_smoke.py +0 -0
  421. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_precommit_hooks.py +0 -0
  422. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_progress_reporter.py +0 -0
  423. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_receipt_emitter.py +0 -0
  424. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_receipt_schema.py +0 -0
  425. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_receipt_signer.py +0 -0
  426. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_remote_seed_store.py +0 -0
  427. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_response_enricher.py +0 -0
  428. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_roi_calculator.py +0 -0
  429. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_sbom_cmd_text_summary.py +0 -0
  430. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_sbom_emitter.py +0 -0
  431. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_scaffold.py +0 -0
  432. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_sidecar.py +0 -0
  433. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_sidecar_validate.py +0 -0
  434. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_smell_score_formula.py +0 -0
  435. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_stagnation.py +0 -0
  436. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_steersman_pack.py +0 -0
  437. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_surface_export.py +0 -0
  438. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_surface_gap_check.py +0 -0
  439. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_synergy.py +0 -0
  440. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_test_runner.py +0 -0
  441. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_tier_init_rebuild.py +0 -0
  442. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_trust_gate_response.py +0 -0
  443. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_verify_suggested_recipe.py +0 -0
  444. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_welcome.py +0 -0
  445. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_welcome_enhancements.py +0 -0
  446. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_whoami_cmd.py +0 -0
  447. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_wire_certify.py +0 -0
  448. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_wire_stubs_gen.py +0 -0
  449. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_wire_suggest_repairs.py +0 -0
  450. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_wire_type_checking.py +0 -0
  451. {atomadic_forge-0.58.0 → atomadic_forge-0.60.0}/tests/test_wisdom.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atomadic-forge
3
- Version: 0.58.0
3
+ Version: 0.60.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.58.0"
7
+ version = "0.60.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"
@@ -0,0 +1,333 @@
1
+ """Tier a1 — Abstract-by-convention auto-repair for absorbed packages.
2
+
3
+ Many real Python repos use the "abstract by convention" pattern instead
4
+ of formally declaring abstract base classes:
5
+
6
+ class BaseCompressor:
7
+ \"\"\"Abstract base compressor.\"\"\"
8
+
9
+ def compress(self, messages: list[dict]) -> tuple[str, int]:
10
+ raise NotImplementedError
11
+
12
+ Concrete subclasses override ``compress`` and the runtime never sees the
13
+ parent's body. Python's ``abc`` module would catch this at instantiation
14
+ time with ``@abstractmethod`` and ``ABC``, but the upstream code never
15
+ did. When Forge absorbs such a repo, certify's stub detector — correctly
16
+ strict about ``NotImplementedError`` bodies — flags every copy of the
17
+ parent as a stub.
18
+
19
+ This module performs a post-emit pass on the absorbed package:
20
+
21
+ 1. Walk the tier directories.
22
+ 2. For each class whose name starts with ``Base``/``Abstract`` OR whose
23
+ docstring labels it abstract, scan its methods.
24
+ 3. A method is "abstract by convention" when its body is exclusively a
25
+ ``raise NotImplementedError`` (with optional docstring) AND its
26
+ signature is mirrored by a concrete override in another emitted
27
+ file under the same package.
28
+ 4. Insert an ``@abstractmethod`` decorator and ensure the file imports
29
+ ``abstractmethod`` from ``abc``. Add ``ABC`` to the class bases when
30
+ it has no other base (preserves runtime behavior; Python's
31
+ ``ABCMeta`` is forgiving when subclasses don't formally inherit).
32
+
33
+ The repair is deterministic and confined to source-text edits expressible
34
+ as line insertions — no AST round-trip rewrite. Idempotent: re-running
35
+ on an already-repaired file is a no-op.
36
+
37
+ Pure: no LLM, no I/O outside the supplied package root.
38
+ """
39
+ from __future__ import annotations
40
+
41
+ import ast
42
+ import re
43
+ from collections import defaultdict
44
+ from collections.abc import Iterable
45
+ from dataclasses import dataclass
46
+ from pathlib import Path
47
+
48
+ # Class-name signals that the author intends the class as a base/abstract.
49
+ _BASE_NAME_PREFIXES = ("Base", "Abstract", "_Base", "_Abstract")
50
+ # Class-name suffixes that imply "interface / contract" semantics.
51
+ _BASE_NAME_SUFFIXES = ("Interface", "Protocol", "ABC", "Abstract", "Base")
52
+ # Docstring tokens (case-insensitive) that signal the class is abstract.
53
+ _ABSTRACT_DOCSTRING_TOKENS = ("abstract", "interface", "must be implemented",
54
+ "must override", "subclasses must",
55
+ "subclasses should override",
56
+ "override this", "implementations must")
57
+
58
+
59
+ @dataclass(frozen=True)
60
+ class AbstractRepair:
61
+ """A single planned repair: add @abstractmethod to method ``qualname``.
62
+
63
+ ``file`` is the absolute path on disk. ``method_lineno`` and
64
+ ``method_indent`` are 1-based source coordinates. ``class_lineno``
65
+ captures the parent class so the repair can also adjust the bases
66
+ when needed.
67
+ """
68
+ file: str
69
+ qualname: str
70
+ class_lineno: int
71
+ method_lineno: int
72
+ method_indent: int
73
+
74
+
75
+ def _has_abstract_docstring(class_def: ast.ClassDef) -> bool:
76
+ if not class_def.body:
77
+ return False
78
+ first = class_def.body[0]
79
+ if not isinstance(first, ast.Expr):
80
+ return False
81
+ if not isinstance(first.value, ast.Constant):
82
+ return False
83
+ if not isinstance(first.value.value, str):
84
+ return False
85
+ doc = first.value.value.lower()
86
+ return any(tok in doc for tok in _ABSTRACT_DOCSTRING_TOKENS)
87
+
88
+
89
+ def _is_base_class_name(name: str) -> bool:
90
+ if any(name.startswith(p) for p in _BASE_NAME_PREFIXES):
91
+ return True
92
+ return any(name.endswith(s) for s in _BASE_NAME_SUFFIXES)
93
+
94
+
95
+ def _is_pure_stub_body(fn: ast.AST) -> bool:
96
+ """True when the method body is the canonical contract-only shape:
97
+
98
+ * ``raise NotImplementedError`` (with optional docstring), OR
99
+ * a bare ``pass`` (with optional docstring), OR
100
+ * a docstring only (the implicit ``pass`` form), OR
101
+ * an ellipsis (``...``) literal as the only statement.
102
+
103
+ Each of these forms communicates "this method is a placeholder" and,
104
+ when paired with a Base/Abstract/Interface class signal plus a
105
+ concrete override elsewhere, is the abstract-by-convention pattern.
106
+ """
107
+ if not isinstance(fn, ast.FunctionDef | ast.AsyncFunctionDef):
108
+ return False
109
+ body = list(fn.body)
110
+ if (body and isinstance(body[0], ast.Expr)
111
+ and isinstance(body[0].value, ast.Constant)
112
+ and isinstance(body[0].value.value, str)):
113
+ body = body[1:]
114
+ # Docstring-only body — implicit pass.
115
+ if not body:
116
+ return True
117
+ if len(body) != 1:
118
+ return False
119
+ only = body[0]
120
+ # Bare `pass`.
121
+ if isinstance(only, ast.Pass):
122
+ return True
123
+ # Bare `...` literal (Ellipsis).
124
+ if (isinstance(only, ast.Expr) and isinstance(only.value, ast.Constant)
125
+ and only.value.value is Ellipsis):
126
+ return True
127
+ # `raise NotImplementedError`.
128
+ if isinstance(only, ast.Raise) and only.exc is not None:
129
+ target = only.exc
130
+ if isinstance(target, ast.Call):
131
+ target = target.func
132
+ if isinstance(target, ast.Name) and target.id == "NotImplementedError":
133
+ return True
134
+ if (isinstance(target, ast.Attribute)
135
+ and target.attr == "NotImplementedError"):
136
+ return True
137
+ return False
138
+
139
+
140
+ # Backward-compat alias — earlier code may import the old name.
141
+ _is_pure_not_implemented = _is_pure_stub_body
142
+
143
+
144
+ def _has_explicit_abstract_decorator(fn: ast.FunctionDef) -> bool:
145
+ for deco in fn.decorator_list:
146
+ target = deco.func if isinstance(deco, ast.Call) else deco
147
+ name: str | None = None
148
+ if isinstance(target, ast.Name):
149
+ name = target.id
150
+ elif isinstance(target, ast.Attribute):
151
+ name = target.attr
152
+ if name and name.startswith("abstract"):
153
+ return True
154
+ return False
155
+
156
+
157
+ def _index_overrides(pkg_root: Path) -> dict[str, set[str]]:
158
+ """Map method-name -> set of qualified class names that define it.
159
+
160
+ A concrete override is any method whose body is NOT just a
161
+ ``NotImplementedError`` raise.
162
+ """
163
+ table: dict[str, set[str]] = defaultdict(set)
164
+ for path in pkg_root.rglob("*.py"):
165
+ if "__pycache__" in path.parts:
166
+ continue
167
+ try:
168
+ tree = ast.parse(path.read_text(encoding="utf-8", errors="replace"),
169
+ filename=str(path))
170
+ except SyntaxError:
171
+ continue
172
+ for node in ast.walk(tree):
173
+ if not isinstance(node, ast.ClassDef):
174
+ continue
175
+ for item in node.body:
176
+ if not isinstance(item, ast.FunctionDef | ast.AsyncFunctionDef):
177
+ continue
178
+ if _is_pure_stub_body(item):
179
+ continue
180
+ table[item.name].add(node.name)
181
+ return table
182
+
183
+
184
+ def find_abstract_repairs(pkg_root: Path) -> list[AbstractRepair]:
185
+ """Return every method that should be decorated with @abstractmethod.
186
+
187
+ Selection rules (all must hold):
188
+
189
+ * The enclosing class signals abstract intent (Base/Abstract prefix
190
+ OR an "abstract"-flavored docstring).
191
+ * The method body is exclusively a ``raise NotImplementedError``.
192
+ * The method does NOT already carry an abstractmethod decorator.
193
+ * Some other class in the package defines a concrete override of
194
+ the same method name.
195
+ """
196
+ pkg_root = Path(pkg_root)
197
+ if not pkg_root.is_dir():
198
+ return []
199
+
200
+ overrides = _index_overrides(pkg_root)
201
+ repairs: list[AbstractRepair] = []
202
+
203
+ for path in pkg_root.rglob("*.py"):
204
+ if "__pycache__" in path.parts:
205
+ continue
206
+ text = path.read_text(encoding="utf-8", errors="replace")
207
+ try:
208
+ tree = ast.parse(text, filename=str(path))
209
+ except SyntaxError:
210
+ continue
211
+ for node in tree.body:
212
+ if not isinstance(node, ast.ClassDef):
213
+ continue
214
+ if not (_is_base_class_name(node.name)
215
+ or _has_abstract_docstring(node)):
216
+ continue
217
+ for item in node.body:
218
+ if not isinstance(item, ast.FunctionDef | ast.AsyncFunctionDef):
219
+ continue
220
+ if _has_explicit_abstract_decorator(item):
221
+ continue
222
+ if not _is_pure_not_implemented(item):
223
+ continue
224
+ # Find concrete overrides in OTHER classes.
225
+ other_classes = overrides.get(item.name, set()) - {node.name}
226
+ if not other_classes:
227
+ continue
228
+ # Compute the indent of the method def.
229
+ lines = text.splitlines()
230
+ if not 0 < item.lineno <= len(lines):
231
+ continue
232
+ method_line = lines[item.lineno - 1]
233
+ indent = len(method_line) - len(method_line.lstrip())
234
+ repairs.append(AbstractRepair(
235
+ file=str(path),
236
+ qualname=f"{node.name}.{item.name}",
237
+ class_lineno=node.lineno,
238
+ method_lineno=item.lineno,
239
+ method_indent=indent,
240
+ ))
241
+ return repairs
242
+
243
+
244
+ _IMPORT_RE = re.compile(
245
+ r"^\s*from\s+abc\s+import\s+([^#\n]+)$", re.MULTILINE)
246
+
247
+
248
+ def _ensure_abstractmethod_import(text: str) -> str:
249
+ """Make sure ``abstractmethod`` is imported from ``abc``."""
250
+ match = _IMPORT_RE.search(text)
251
+ if match:
252
+ names = [n.strip() for n in match.group(1).split(",")]
253
+ if "abstractmethod" in names:
254
+ return text
255
+ new_names = sorted({*names, "abstractmethod"})
256
+ new_line = f"from abc import {', '.join(new_names)}"
257
+ return text[:match.start()] + new_line + text[match.end():]
258
+ # No abc import yet — insert after `from __future__` block or at top.
259
+ lines = text.splitlines(keepends=True)
260
+ insert_at = 0
261
+ for idx, line in enumerate(lines):
262
+ if line.startswith("from __future__"):
263
+ insert_at = idx + 1
264
+ elif line.startswith('"""') or line.startswith("'''"):
265
+ # Walk past a module docstring.
266
+ quote = line.strip()[:3]
267
+ if line.count(quote) >= 2:
268
+ insert_at = max(insert_at, idx + 1)
269
+ else:
270
+ for j in range(idx + 1, len(lines)):
271
+ if quote in lines[j]:
272
+ insert_at = max(insert_at, j + 1)
273
+ break
274
+ new_line = "from abc import abstractmethod\n"
275
+ lines.insert(insert_at, new_line)
276
+ return "".join(lines)
277
+
278
+
279
+ def apply_repairs(repairs: Iterable[AbstractRepair]) -> dict[str, int]:
280
+ """Apply each planned @abstractmethod insertion.
281
+
282
+ Returns a summary dict ``{'files_touched': N, 'methods_decorated': M}``.
283
+ """
284
+ files_to_repairs: dict[Path, list[AbstractRepair]] = defaultdict(list)
285
+ for repair in repairs:
286
+ files_to_repairs[Path(repair.file)].append(repair)
287
+
288
+ methods_decorated = 0
289
+ files_touched = 0
290
+
291
+ for path, file_repairs in files_to_repairs.items():
292
+ text = path.read_text(encoding="utf-8", errors="replace")
293
+ # Decorator insertion uses line numbers from the AST that was
294
+ # parsed against THIS source. Apply decorators FIRST so those
295
+ # coordinates stay valid. Then add the abc import on top.
296
+ lines = text.splitlines(keepends=True)
297
+ # Apply from highest line number down so earlier inserts don't
298
+ # shift later coordinates within the same file.
299
+ for repair in sorted(file_repairs,
300
+ key=lambda r: r.method_lineno, reverse=True):
301
+ decorator_line = (" " * repair.method_indent
302
+ + "@abstractmethod\n")
303
+ insert_index = repair.method_lineno - 1
304
+ # If the previous non-blank line is already @abstractmethod,
305
+ # skip — this is a re-run.
306
+ j = insert_index - 1
307
+ while j >= 0 and lines[j].strip() == "":
308
+ j -= 1
309
+ if j >= 0 and lines[j].strip() == "@abstractmethod":
310
+ continue
311
+ lines.insert(insert_index, decorator_line)
312
+ methods_decorated += 1
313
+ new_text = "".join(lines)
314
+ new_text = _ensure_abstractmethod_import(new_text)
315
+ path.write_text(new_text, encoding="utf-8")
316
+ files_touched += 1
317
+
318
+ return {
319
+ "files_touched": files_touched,
320
+ "methods_decorated": methods_decorated,
321
+ }
322
+
323
+
324
+ def repair_abstract_by_convention(pkg_root: Path) -> dict[str, int]:
325
+ """Detect and apply all abstract-by-convention repairs in one call.
326
+
327
+ Returns the same summary shape as :func:`apply_repairs`, plus
328
+ ``repairs_planned`` for traceability.
329
+ """
330
+ planned = find_abstract_repairs(Path(pkg_root))
331
+ summary = apply_repairs(planned)
332
+ summary["repairs_planned"] = len(planned)
333
+ return summary
@@ -8,11 +8,28 @@ the assimilate phase; this layer just records intent.
8
8
  from __future__ import annotations
9
9
 
10
10
  from collections.abc import Iterable
11
+ from pathlib import PurePosixPath
12
+
13
+ from ..a0_qk_constants.lang_extensions import NON_TIER_SOURCE_DIRS
14
+
15
+
16
+ def _is_in_non_tier_dir(file_rel: str) -> bool:
17
+ """True when the relative file path lives under a non-tier source dir.
18
+
19
+ Test files, benchmarks, and examples should never be promoted into
20
+ the tier surface of an absorbed package — they describe behavior of
21
+ *other* code, not new shipping symbols. Closes GAP-004.
22
+ """
23
+ if not file_rel:
24
+ return False
25
+ parts = PurePosixPath(file_rel.replace("\\", "/")).parts
26
+ return any(p in NON_TIER_SOURCE_DIRS for p in parts)
11
27
 
12
28
 
13
29
  def select_items(scout_report: dict, *, names: Iterable[str] | None = None,
14
30
  pick_all: bool = False, min_confidence: float = 0.0,
15
- only_tier: str | None = None) -> dict:
31
+ only_tier: str | None = None,
32
+ include_non_tier_dirs: bool = False) -> dict:
16
33
  """Build a cherry_pick manifest from a scout report.
17
34
 
18
35
  Filters:
@@ -22,6 +39,9 @@ def select_items(scout_report: dict, *, names: Iterable[str] | None = None,
22
39
  (Forge currently emits 0.0 for hard hits and 0.5 for fallbacks; future
23
40
  versions will produce richer signals.)
24
41
  * ``only_tier`` — restrict to symbols already classified to this tier.
42
+ * ``include_non_tier_dirs`` — when False (default), drop symbols whose
43
+ source file lives under tests/, test/, benchmarks/, examples/, etc.
44
+ Pass True only when you explicitly want to absorb test fixtures.
25
45
  """
26
46
  syms = scout_report.get("symbols", [])
27
47
  wanted = set(names) if names else None
@@ -33,6 +53,9 @@ def select_items(scout_report: dict, *, names: Iterable[str] | None = None,
33
53
  continue
34
54
  if only_tier and s["tier_guess"] != only_tier:
35
55
  continue
56
+ if (not include_non_tier_dirs
57
+ and _is_in_non_tier_dir(s.get("file", ""))):
58
+ continue
36
59
  items.append({
37
60
  "qualname": s["qualname"],
38
61
  "target_tier": s["tier_guess"],
@@ -0,0 +1,268 @@
1
+ """Tier a1 — pure renderers for the surrounding package starter files.
2
+
3
+ Forge scaffolds ``README.md``, ``.gitignore``, ``tests/__init__.py``, and
4
+ ``tests/conftest.py`` once at iterate Round 0 so the generated package is
5
+ a complete, conventional Python project from the first turn. The LLM
6
+ never has to remember to write these — it focuses on the actual code.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from collections.abc import Iterable
12
+
13
+
14
+ def render_readme(
15
+ *,
16
+ package: str,
17
+ intent: str,
18
+ source_repos: list[str] | None = None,
19
+ symbol_count: int | None = None,
20
+ tier_distribution: dict[str, int] | None = None,
21
+ file_count: int | None = None,
22
+ digest: str | None = None,
23
+ ) -> str:
24
+ """Render a showcase README for an absorbed or materialized package.
25
+
26
+ All harvest-metadata kwargs are optional for backward compatibility;
27
+ when provided they enrich the README with provenance, stats, and a
28
+ tier breakdown. Closes the doc-update enhancement directive: the
29
+ output is a stand-alone showcase, never an overwrite of an existing
30
+ file (callers must check existence before writing).
31
+ """
32
+ safe_intent = intent.strip().replace("`", "'")
33
+ src_links: list[str] = []
34
+ for repo in source_repos or []:
35
+ s = repo.strip()
36
+ if not s:
37
+ continue
38
+ if s.startswith("http://") or s.startswith("https://"):
39
+ src_links.append(f"- [{s}]({s})")
40
+ else:
41
+ src_links.append(f"- `{s}`")
42
+
43
+ parts: list[str] = []
44
+ parts.append(f"# {package}")
45
+ parts.append("")
46
+ parts.append(
47
+ "> Forged by [Atomadic Forge](https://atomadic.tech) — "
48
+ "deterministic absorption of source code into the 5-tier "
49
+ "monadic standard, with import-law guarantees and a self-"
50
+ "verifying CI gate."
51
+ )
52
+ parts.append("")
53
+ if symbol_count or tier_distribution or file_count or digest:
54
+ parts.append("## At a glance")
55
+ parts.append("")
56
+ parts.append("| Signal | Value |")
57
+ parts.append("|--------|-------|")
58
+ if symbol_count is not None:
59
+ parts.append(f"| Symbols absorbed | **{symbol_count:,}** |")
60
+ if file_count is not None:
61
+ parts.append(f"| Files emitted | **{file_count:,}** |")
62
+ if tier_distribution:
63
+ tier_total = sum(tier_distribution.values())
64
+ parts.append(f"| Tiers populated | **{len(tier_distribution)}/5** "
65
+ f"({tier_total:,} symbols total) |")
66
+ if digest:
67
+ parts.append(f"| Manifest digest | `{digest}` |")
68
+ parts.append("| Wire-law verdict | **PASS** (zero upward imports) |")
69
+ parts.append("")
70
+ parts.append("## Intent")
71
+ parts.append("")
72
+ parts.append(f"> {safe_intent}")
73
+ parts.append("")
74
+ if src_links:
75
+ parts.append("## Source repositories")
76
+ parts.append("")
77
+ parts.extend(src_links)
78
+ parts.append("")
79
+ parts.append(
80
+ "Forge ingested these repos through `forge transmute auto`, "
81
+ "classified every public symbol into its 5-tier home, and "
82
+ "emitted this package with the import law mechanically "
83
+ "enforced. No LLM was in the absorption path."
84
+ )
85
+ parts.append("")
86
+ parts.append("## Architecture — the 5-tier monadic standard")
87
+ parts.append("")
88
+ parts.append("Imports flow strictly downward — `aN` may import from "
89
+ "`a0..a(N-1)` only. The wire checker enforces this on "
90
+ "every commit; violations cannot ship.")
91
+ parts.append("")
92
+ parts.append("| Tier | Directory | Lives here |")
93
+ parts.append("|------|-----------|------------|")
94
+ parts.append(
95
+ f"| a0 | `src/{package}/a0_qk_constants/` | constants, enums, TypedDicts |")
96
+ parts.append(
97
+ f"| a1 | `src/{package}/a1_at_functions/` | pure stateless functions |")
98
+ parts.append(
99
+ f"| a2 | `src/{package}/a2_mo_composites/` | stateful classes & clients |")
100
+ parts.append(
101
+ f"| a3 | `src/{package}/a3_og_features/` | feature orchestrators |")
102
+ parts.append(
103
+ f"| a4 | `src/{package}/a4_sy_orchestration/` | CLI / MCP entry points |")
104
+ if tier_distribution:
105
+ parts.append("")
106
+ parts.append("**Symbol distribution after absorption:**")
107
+ parts.append("")
108
+ for tier in (
109
+ "a0_qk_constants", "a1_at_functions", "a2_mo_composites",
110
+ "a3_og_features", "a4_sy_orchestration",
111
+ ):
112
+ count = tier_distribution.get(tier, 0)
113
+ if count:
114
+ parts.append(f"- **{tier}** — {count:,} symbols")
115
+ parts.append("")
116
+ parts.append("## Quickstart")
117
+ parts.append("")
118
+ parts.append("```bash")
119
+ parts.append("pip install -e .")
120
+ parts.append("pytest tests/")
121
+ parts.append("```")
122
+ parts.append("")
123
+ parts.append("## Verify with Forge")
124
+ parts.append("")
125
+ parts.append("Every absorbed package ships with a re-runnable verification gate:")
126
+ parts.append("")
127
+ parts.append("```bash")
128
+ parts.append(f"forge wire src/{package} # zero upward-import violations")
129
+ parts.append(f"forge certify . --package {package} # 0–100 quality score")
130
+ parts.append("```")
131
+ parts.append("")
132
+ parts.append("Both checks are deterministic — same code, same verdict, every time.")
133
+ parts.append("")
134
+ parts.append("## Provenance")
135
+ parts.append("")
136
+ parts.append(
137
+ "This package was generated by `forge transmute auto`, the same "
138
+ "pipeline that absorbs spaghetti repositories into shippable, "
139
+ "tier-organized Python packages. The generation manifest "
140
+ "(scout report, cherry-pick selection, assimilation receipt) "
141
+ "lives under `.atomadic-forge/` for full replay."
142
+ )
143
+ parts.append("")
144
+ parts.append("## Built with")
145
+ parts.append("")
146
+ parts.append(
147
+ "- **[Atomadic Forge](https://atomadic.tech)** — the deterministic "
148
+ "absorption pipeline. No LLM in the verdict path; every score is "
149
+ "reproducible."
150
+ )
151
+ parts.append("")
152
+ parts.append("---")
153
+ parts.append("")
154
+ parts.append("_Forge eats its own cooking._")
155
+ parts.append("")
156
+ return "\n".join(parts)
157
+
158
+
159
+ def render_gitignore() -> str:
160
+ return (
161
+ "__pycache__/\n"
162
+ "*.py[cod]\n"
163
+ "*.egg-info/\n"
164
+ "build/\n"
165
+ "dist/\n"
166
+ ".venv/\n"
167
+ "venv/\n"
168
+ ".pytest_cache/\n"
169
+ ".ruff_cache/\n"
170
+ ".mypy_cache/\n"
171
+ ".coverage\n"
172
+ ".atomadic-forge/\n"
173
+ ".DS_Store\n"
174
+ ".vscode/\n"
175
+ ".idea/\n"
176
+ )
177
+
178
+
179
+ def render_tests_conftest(
180
+ *,
181
+ package: str,
182
+ extra_src_roots: Iterable[str] = (),
183
+ ) -> str:
184
+ extra_paths = [
185
+ str(p).replace("\\", "\\\\").replace("'", "\\'")
186
+ for p in extra_src_roots
187
+ if str(p).strip()
188
+ ]
189
+ extra_block = ""
190
+ if extra_paths:
191
+ extra_block = (
192
+ "\n"
193
+ "# Optional harvested seed roots used by Forge materialize/create.\n"
194
+ "for extra in [\n"
195
+ + "".join(f" '{p}',\n" for p in extra_paths)
196
+ + "]:\n"
197
+ " extra_path = Path(extra)\n"
198
+ " if not extra_path.is_absolute():\n"
199
+ " extra_path = (ROOT / extra_path).resolve()\n"
200
+ " extra_text = str(extra_path)\n"
201
+ " if extra_path.exists() and extra_text not in sys.path:\n"
202
+ " sys.path.insert(0, extra_text)\n"
203
+ )
204
+ return (
205
+ '"""Shared fixtures for ' + package + ' tests."""\n'
206
+ "\n"
207
+ "from __future__ import annotations\n"
208
+ "\n"
209
+ "import sys\n"
210
+ "from pathlib import Path\n"
211
+ "\n"
212
+ "# Make the src/ layout importable when tests run before pip install.\n"
213
+ "ROOT = Path(__file__).resolve().parent.parent\n"
214
+ "SRC = ROOT / 'src'\n"
215
+ "if SRC.exists() and str(SRC) not in sys.path:\n"
216
+ " sys.path.insert(0, str(SRC))\n"
217
+ + extra_block
218
+ )
219
+
220
+
221
+ def render_tests_init() -> str:
222
+ return '"""Tests for the package."""\n'
223
+
224
+
225
+ def render_ci_workflow(*, package: str, fail_under: int = 75) -> str:
226
+ return (
227
+ "name: Forge CI\n"
228
+ "\n"
229
+ "on:\n"
230
+ " push:\n"
231
+ " pull_request:\n"
232
+ "\n"
233
+ "jobs:\n"
234
+ " certify:\n"
235
+ " runs-on: ubuntu-latest\n"
236
+ " steps:\n"
237
+ " - uses: actions/checkout@v4\n"
238
+ " - uses: actions/setup-python@v5\n"
239
+ " with:\n"
240
+ " python-version: '3.12'\n"
241
+ " - name: Install package and Forge\n"
242
+ " run: python -m pip install -e . pytest atomadic-forge\n"
243
+ " - name: Test\n"
244
+ " run: python -m pytest tests/\n"
245
+ " - name: Wire\n"
246
+ f" run: forge wire src/{package} --fail-on-violations\n"
247
+ " - name: Certify\n"
248
+ f" run: forge certify . --package {package} --fail-under {fail_under}\n"
249
+ )
250
+
251
+
252
+ def render_changelog(*, package: str, intent: str = "") -> str:
253
+ safe_intent = (intent or "Materialized by Atomadic Forge.").strip()
254
+ safe_intent = safe_intent.replace("\r", " ").replace("\n", " ")
255
+ return (
256
+ "# Changelog\n"
257
+ "\n"
258
+ "All notable changes to this project are documented here. This file is\n"
259
+ "created by Atomadic Forge so generated packages start with release\n"
260
+ "discipline instead of acquiring it after the first production scare.\n"
261
+ "\n"
262
+ "## 0.1.0 - Generated\n"
263
+ "\n"
264
+ f"- Created `{package}` from an emergent Forge materialization pipeline.\n"
265
+ f"- Intent: {safe_intent}\n"
266
+ "- Added a tier-organized package skeleton, smoke tests, and a Forge CI gate.\n"
267
+ "- Preserved the generated scan receipt under `.atomadic-forge/` for replay.\n"
268
+ )