atomadic-forge 0.78.0__tar.gz → 0.79.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.
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/workflows/metrics-auto-regen.yml +1 -1
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/CHANGELOG.md +11 -0
- {atomadic_forge-0.78.0/src/atomadic_forge.egg-info → atomadic_forge-0.79.0}/PKG-INFO +3 -3
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/README.md +2 -2
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/CI_CD.md +3 -3
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/COMMANDS.md +1 -1
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/FORMALIZATION.md +2 -2
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/RECEIPT.md +2 -2
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/pyproject.toml +1 -1
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/doc_auto_update.py +2 -2
- atomadic_forge-0.79.0/src/atomadic_forge/a3_og_features/recipe_replay.py +158 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a4_sy_orchestration/cli.py +5 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/metrics.py +8 -13
- atomadic_forge-0.79.0/src/atomadic_forge/commands/replay.py +101 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0/src/atomadic_forge.egg-info}/PKG-INFO +3 -3
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge.egg-info/SOURCES.txt +3 -0
- atomadic_forge-0.79.0/tests/test_recipe_replay.py +88 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/FUNDING.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/actions/forge-action/README.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/actions/forge-action/action.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/dependabot.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/pull_request_template.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/workflows/ci.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/workflows/customer-refactor.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/workflows/forge-self-certify.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/workflows/mcp-registry-publish.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/workflows/metrics-drift.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/workflows/publish-on-tag.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/workflows/release-readiness.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/workflows/release.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/workflows/surface-drift.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/.github/workflows/uptime.yml +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/ARCHITECTURE.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/CONTRIBUTING.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/LICENSE +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/MANIFEST.in +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/SECURITY.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/assets/Atomadic-Forge-01.png +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/01-getting-started.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/02-commands.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/03-tutorial.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/04-llm-loops.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/05-faq.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/AGENTS_GUIDE.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/AIR_GAPPED.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/CODEX_WALKTHROUGH.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/FIRST_10_MINUTES.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/HIVE_PRIMITIVES.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/HIVE_STATUS.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/IDE_INTEGRATION.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/LANDSCAPE.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/MARKET_POSITIONING.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/MCP_TOOLS.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/MIGRATION.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/MULTI_REPO.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/PROVIDERS.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/README.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/RELAY_PROTOCOL.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/RELEASE_CHECKLIST.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/RELEASE_MESSAGING.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/ROADMAP.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/SHOWCASE.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/SIDECAR.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/STUDIO.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/TOOL_FACTORY_WALKTHROUGH.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/V0.46.0_JUSTIFICATION_REPORT.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/V0.47.0_SELF_TEST_REPORT.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/WHY_NOW.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/WORKER_VS_LOCAL_MCP.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/WORLD_COLLISION.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/INDEX.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/absorb.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/audit.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/chat.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/commandsmith.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/config.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/create.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/demo.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/emergent-swarm.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/emergent-then-synergy.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/emergent.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/enhancement.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/evolve-then-iterate.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/evolve.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/feature-then-emergent.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/guard-install.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/handoff.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/harvest.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/hive.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/iterate.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/materialize.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/metrics.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/recon-swarm.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/relay.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/surface.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/synergy-then-emergent.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/synergy.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/welcome.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/commands/wisdom.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/compliance/CMMC_AI_MAPPING.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/compliance/CS-1.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/compliance/EU_AI_ACT_ANNEX_IV.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/compliance/FDA_PCCP_MAPPING.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/compliance/SR_11-7_MAPPING.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/handoffs/WORKER_AUTO_DEPLOY_2026-05-06.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/tutorials/01-quickstart.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/tutorials/02-your-first-package.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/tutorials/03-the-five-tier-law.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/tutorials/04-plug-in-llms.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/tutorials/05-multi-repo-absorb.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/docs/tutorials/06-javascript-quickstart.md +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/setup.cfg +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/__init__.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/__main__.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/__init__.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/agent_plan_schema.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/auth_constants.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/commandsmith_types.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/config_defaults.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/emergent_types.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/enhancement_proposal_constants.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/error_codes.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/forge_types.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/gen_language.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/handoff_constants.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/hive_constants.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/lang_extensions.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/lifetime_savings_constants.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/materialize_types.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/mhed_invariants.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/nexus_constants.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/policy_schema.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/receipt_schema.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/response_enrichment.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/roi_constants.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/schema_version_registry.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/semantic_types.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/sidecar_schema.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/synergy_types.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/tier_names.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/welcome_constants.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a0_qk_constants/wisdom_constants.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/__init__.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/abstract_method_repair.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/agent_context_pack.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/agent_memory.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/agent_plan_emitter.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/agent_summary.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/ast_scope_lock.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/body_extractor.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/call_graph.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/capability_scout.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/card_renderer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/certify_checks.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/chat_context.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/cherry_pick.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/classify_tier.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/code_signature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/commandsmith_discover.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/commandsmith_render.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/compiler_feedback.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/compliance_checker.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/config_io.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/cosine_similarity.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/cs1_renderer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/custom_provider_client.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/dead_code_check.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/doc_synthesizer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/emergent_compose.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/emergent_rank.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/emergent_signature_extract.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/emergent_synthesize.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/enforce_planner.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/enhancement_proposal_builder.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/error_hints.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/evolution_log.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/exported_api_check.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/forge_auth.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/forge_feedback.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/forge_locate.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/forge_metrics.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/generation_quality.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/git_churn.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/graft_extract.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/handoff_builder.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/harvest_absorb.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/harvest_concept_bridge.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/hive_consensus_math.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/hive_io.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/import_repair.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/import_smoke.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/intent_similarity.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/js_parser.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/lifetime_savings.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/lineage_chain.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/lineage_reader.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/llm_client.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/local_signer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/lsp_protocol.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/maintainability_index.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/manifest_diff.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/mcp_protocol.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/patch_scorer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/plan_adapter.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/policy_loader.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/polyglot_classify.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/polyglot_imports.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/polyglot_surface.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/preflight_change.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/progress_reporter.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/provider_detect.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/provider_resolver.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/receipt_emitter.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/recipes.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/repo_explainer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/repo_public_surface.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/research_note_distiller.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/response_enricher.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/roi_calculator.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/rollback_planner.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/sbom_emitter.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/scaffold_js.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/scaffold_polyglot.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/scaffold_pyproject.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/scaffold_starter.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/scout_walk.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/sidecar_parser.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/sidecar_validator.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/smell_scan.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/steersman_pack.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/stub_detector.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/surface_gap_check.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/synergy_detect.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/synergy_render.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/synergy_surface_extract.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/test_runner.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/test_selector.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/tier_init_rebuild.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/tool_composer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/transcript_log.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/trust_gate_response.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/validation_commands.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/welcome_narrator.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/wire_check.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/wire_stubs_gen.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/wisdom_capture.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/wisdom_io.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/wisdom_promote.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/wisdom_recall.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a1_at_functions/worktree_status.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/__init__.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/cost_circuit_breaker.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/cross_agent_intent_deduplicator.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/evolve_session_store.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/forge_auth_client.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/hierarchical_memory.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/iterate_session_store.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/lineage_chain_store.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/manifest_store.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/nexus_client.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/plan_store.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/receipt_signer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/remote_seed_store.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a2_mo_composites/repo_public_surface_sync.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/__init__.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/absorb_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/agent_hire_protocol.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/cherry_hunter.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/cna_check.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/commandsmith_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/commit_compose.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/create_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/dedup_engine.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/__init__.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/a0_qk_constants/__init__.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/a1_at_functions/__init__.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/tests/conftest.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/tests/test_mixed.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/demo_runner.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/emergent_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/emergent_pipeline_integration.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/emergent_swarm.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/enhancement_proposal_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/forge_enforce.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/forge_evolve.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/forge_evolve_session.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/forge_loop.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/forge_loop_session.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/forge_metrics_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/forge_pipeline.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/forge_plan_apply.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/graft_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/guard_install.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/handoff_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/hive_sync.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/lsp_server.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/materialize_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/mcp_server.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/nexus_bridge.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/relay_daemon.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/setup_wizard.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/surface_export.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/synergy_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/tool_factory.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/verify_umbrella.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/welcome_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a3_og_features/wisdom_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a4_sy_orchestration/__init__.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a4_sy_orchestration/copilots_cmd.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a4_sy_orchestration/login_cmd.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a4_sy_orchestration/whoami_cmd.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/__init__.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/_registry.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/absorb.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/audit.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/chat.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/commandsmith.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/config_cmd.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/create.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/demo.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/emergent.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/emergent_swarm.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/emergent_then_synergy.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/enhancement.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/evolve.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/evolve_then_iterate.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/feature_then_emergent.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/graft.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/guard_install.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/handoff.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/harvest.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/hive.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/iterate.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/materialize.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/recon_swarm.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/relay.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/surface.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/synergy.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/synergy_then_emergent.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/token_savings.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/welcome.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/commands/wisdom.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge.egg-info/dependency_links.txt +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge.egg-info/entry_points.txt +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge.egg-info/requires.txt +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge.egg-info/top_level.txt +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_aaaa_nexus_client.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_abstract_method_repair.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_agent_hire_protocol.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_agent_plan.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_agent_plan_pkg_label.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_agent_summary.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_ast_scope_lock.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_audit_verb.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_body_extractor_repairs.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_call_graph_summary.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_capability_scout.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_card_renderer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_certify_operational_axis.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_chat.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_cherry_dedup_class_methods.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_cherry_pick.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_classify_tier.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_classify_tier_ast_signals.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_cli_smoke.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_cli_swarm_aliases.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_codex_5_complete.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_codex_6_enforce_polyglot.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_commandsmith.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_compiler_feedback.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_compliance_checker.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_config.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_copilots_copilot.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_cost_circuit_breaker.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_create_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_cs1_renderer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_custom_provider.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_dead_code_check.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_dedup_engine.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_demo.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_doc_auto_update.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_emergent_compose.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_emergent_signature_extract.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_emergent_synthesize_imports.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_enhancement_proposal.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_error_codes.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_error_hints.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_evolve_js.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_exported_api_check.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_finalize_scaffold.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_forge_action.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_forge_auth_a1.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_forge_auth_a2.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_forge_enforce.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_generation_quality.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_git_churn.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_graft_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_handoff.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_harvest_concept_bridge.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_harvest_source_warnings.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_hierarchical_memory.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_hive_sync.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_ignore_and_docs.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_import_smoke.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_iterate_evolve.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_js_certify.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_js_parser.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_js_recon.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_js_wire.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_lineage_chain.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_ling_provider.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_local_signer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_lsp_protocol.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_maintainability_index.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_manifest_diff.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_materialize_feature.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_mcp_lazy_bootstrap.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_mcp_protocol.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_nexus_bridge.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_ollama_client.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_pipeline.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_plan_apply.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_polyglot_cli_mcp.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_polyglot_full_pipeline.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_polyglot_hardening.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_polyglot_swift_kotlin_go.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_polyglot_symbol_parity.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_pre_audit_smoke.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_precommit_hooks.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_progress_reporter.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_receipt_emitter.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_receipt_schema.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_receipt_signer.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_remote_seed_store.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_repo_public_surface.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_response_enricher.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_roi_calculator.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_sbom_cmd_text_summary.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_sbom_emitter.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_scaffold.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_sidecar.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_sidecar_validate.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_smell_score_formula.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_stagnation.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_steersman_pack.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_stub_detector.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_surface_export.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_surface_gap_check.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_synergy.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_test_runner.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_tier_init_rebuild.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_token_savings_ledger.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_trust_gate_response.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_verify_suggested_recipe.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_welcome.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_welcome_enhancements.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_whoami_cmd.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_wire_certify.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_wire_stubs_gen.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_wire_suggest_repairs.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_wire_type_checking.py +0 -0
- {atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/tests/test_wisdom.py +0 -0
|
@@ -33,7 +33,7 @@ jobs:
|
|
|
33
33
|
regen:
|
|
34
34
|
runs-on: ubuntu-latest
|
|
35
35
|
timeout-minutes: 8
|
|
36
|
-
if: ${{ !contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, 'chore(metrics): auto-regenerate') }}
|
|
36
|
+
if: ${{ !contains(github.event.head_commit.message || '', '[skip ci]') && !contains(github.event.head_commit.message || '', 'chore(metrics): auto-regenerate') }}
|
|
37
37
|
steps:
|
|
38
38
|
- uses: actions/checkout@v4
|
|
39
39
|
with:
|
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## v0.79.0 — 2026-05-08
|
|
6
|
+
|
|
7
|
+
- feat(forge): replay — deterministic golden-recipe execution
|
|
8
|
+
- fix(compat): replace datetime.UTC with timezone.utc for Python 3.10 compat
|
|
9
|
+
- fix(ci): null-safe head_commit.message in metrics-auto-regen if condition
|
|
10
|
+
- chore(metrics): sync forge_metrics.json after cli_verb_count method change
|
|
11
|
+
- fix(surface): regenerate surface.json with package_version 0.78.0
|
|
12
|
+
- fix(metrics): replace upward a4 import in _live_cli_verb_count with file scan
|
|
13
|
+
- chore(release): sync artifacts + doc anchors for v0.78.0
|
|
14
|
+
|
|
15
|
+
|
|
5
16
|
## v0.78.0 — 2026-05-08
|
|
6
17
|
|
|
7
18
|
- feat(forge): token-savings auto-ledger across every enriched verb
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atomadic-forge
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.79.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
|
|
@@ -225,8 +225,8 @@ Full tool reference: [docs/MCP_TOOLS.md](docs/MCP_TOOLS.md) | First call: `welco
|
|
|
225
225
|
|
|
226
226
|
| MCP tools | **10 tools · 116 actions** |
|
|
227
227
|
| CLI verbs | **59** |
|
|
228
|
-
| Source files | **
|
|
229
|
-
| Tests | **
|
|
228
|
+
| Source files | **235** (~47K LOC) |
|
|
229
|
+
| Tests | **1597 passing** across **117 test files** |
|
|
230
230
|
| Lean4 formal proofs | **872 theorems** (mathematically verified core logic) |
|
|
231
231
|
| Monadic tiers | **5** (a0 → a4, strict upward-only composition) |
|
|
232
232
|
| Languages | Python, JS/TS, Swift, Kotlin, Go, Rust |
|
|
@@ -193,8 +193,8 @@ Full tool reference: [docs/MCP_TOOLS.md](docs/MCP_TOOLS.md) | First call: `welco
|
|
|
193
193
|
|
|
194
194
|
| MCP tools | **10 tools · 116 actions** |
|
|
195
195
|
| CLI verbs | **59** |
|
|
196
|
-
| Source files | **
|
|
197
|
-
| Tests | **
|
|
196
|
+
| Source files | **235** (~47K LOC) |
|
|
197
|
+
| Tests | **1597 passing** across **117 test files** |
|
|
198
198
|
| Lean4 formal proofs | **872 theorems** (mathematically verified core logic) |
|
|
199
199
|
| Monadic tiers | **5** (a0 → a4, strict upward-only composition) |
|
|
200
200
|
| Languages | Python, JS/TS, Swift, Kotlin, Go, Rust |
|
|
@@ -46,7 +46,7 @@ jobs:
|
|
|
46
46
|
run: |
|
|
47
47
|
pip install atomadic-forge # PyPI (preferred)
|
|
48
48
|
# Or pin to an exact tag:
|
|
49
|
-
# pip install "git+https://github.com/atomadictech/atomadic-forge@v0.
|
|
49
|
+
# pip install "git+https://github.com/atomadictech/atomadic-forge@v0.78.0"
|
|
50
50
|
# Or vendor wheels: pip install --no-index --find-links wheels/ atomadic-forge
|
|
51
51
|
|
|
52
52
|
- name: Wire scan (upward-import discipline)
|
|
@@ -97,7 +97,7 @@ forge-certify:
|
|
|
97
97
|
image: python:3.11-slim
|
|
98
98
|
timeout: 10 minutes
|
|
99
99
|
before_script:
|
|
100
|
-
- pip install "git+https://github.com/atomadictech/atomadic-forge@v0.
|
|
100
|
+
- pip install "git+https://github.com/atomadictech/atomadic-forge@v0.78.0"
|
|
101
101
|
script:
|
|
102
102
|
- forge wire src/your_package --fail-on-violations --json > wire.json
|
|
103
103
|
- forge certify . --package your_package --fail-under 75 --json > certify.json
|
|
@@ -156,7 +156,7 @@ Then in **the consuming repo's** `.pre-commit-config.yaml`:
|
|
|
156
156
|
```yaml
|
|
157
157
|
repos:
|
|
158
158
|
- repo: https://github.com/atomadictech/atomadic-forge
|
|
159
|
-
rev: v0.
|
|
159
|
+
rev: v0.78.0
|
|
160
160
|
hooks:
|
|
161
161
|
- id: forge-wire
|
|
162
162
|
- id: forge-certify
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Atomadic Forge — Command Reference
|
|
2
2
|
|
|
3
|
-
All verbs available in the `forge` CLI as of 0.
|
|
3
|
+
All verbs available in the `forge` CLI as of 0.78.0
|
|
4
4
|
|
|
5
5
|
> For the structured per-verb reference (with options, examples, and
|
|
6
6
|
> output samples), see [02-commands.md](02-commands.md). This page is
|
|
@@ -39,7 +39,7 @@ Forge certify scores out of **100** in two layers:
|
|
|
39
39
|
JS / TS packages cap at **60/100** today: they earn the four
|
|
40
40
|
structural axes, but the +25 runtime-import smoke and +30 behavioural
|
|
41
41
|
pytest are Python-only. Wiring `npm test` / Vitest into the
|
|
42
|
-
behavioural axis is on the post-v0.
|
|
42
|
+
behavioural axis is on the post-v0.78.0 roadmap.
|
|
43
43
|
|
|
44
44
|
---
|
|
45
45
|
|
|
@@ -131,7 +131,7 @@ runtime dependency makes the package unusable.
|
|
|
131
131
|
|
|
132
132
|
**Why JS/TS does not get this gate yet.** AAM §5.4 (Threats to
|
|
133
133
|
Validity) explicitly flags polyglot runtime gating as a roadmap
|
|
134
|
-
item (post-v0.
|
|
134
|
+
item (post-v0.78.0): the equivalent for JS would be an `npm test`
|
|
135
135
|
invocation, which requires a Node toolchain we do not yet bundle.
|
|
136
136
|
|
|
137
137
|
**Citation.** AAM §5.1 (Core Pipeline Pseudocode); AAM §5.4 (Threats
|
|
@@ -30,7 +30,7 @@ referenced from the Receipt.
|
|
|
30
30
|
{
|
|
31
31
|
"schema_version": "atomadic-forge.receipt/v1",
|
|
32
32
|
"generated_at_utc": "2026-04-28T17:42:11Z",
|
|
33
|
-
"forge_version": "0.
|
|
33
|
+
"forge_version": "0.78.0",
|
|
34
34
|
"verdict": "PASS",
|
|
35
35
|
"project": { ... },
|
|
36
36
|
"certify": { ... },
|
|
@@ -108,7 +108,7 @@ cited:
|
|
|
108
108
|
{
|
|
109
109
|
"schema_version": "atomadic-forge.receipt/v1",
|
|
110
110
|
"generated_at_utc": "2026-04-28T17:42:11Z",
|
|
111
|
-
"forge_version": "0.
|
|
111
|
+
"forge_version": "0.78.0",
|
|
112
112
|
"verdict": "PASS",
|
|
113
113
|
|
|
114
114
|
"project": {
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "atomadic-forge"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.79.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"
|
|
@@ -58,7 +58,7 @@ from __future__ import annotations
|
|
|
58
58
|
import json
|
|
59
59
|
import re
|
|
60
60
|
import subprocess
|
|
61
|
-
from datetime import
|
|
61
|
+
from datetime import datetime, timezone
|
|
62
62
|
from pathlib import Path
|
|
63
63
|
from typing import Any
|
|
64
64
|
|
|
@@ -318,7 +318,7 @@ def _build_metrics_table(metrics: dict[str, Any]) -> str:
|
|
|
318
318
|
|
|
319
319
|
def _build_changelog_block(version: str, log_lines: list[str]) -> str:
|
|
320
320
|
"""Generate a CHANGELOG section for the given version."""
|
|
321
|
-
today = datetime.now(
|
|
321
|
+
today = datetime.now(timezone.utc).strftime("%Y-%m-%d")
|
|
322
322
|
items = "\n".join(f"- {line}" for line in log_lines[:20]) if log_lines else "- (see git log)"
|
|
323
323
|
return (
|
|
324
324
|
f"## v{version} — {today}\n\n"
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""Tier a3 — Recipe Replayer: deterministic execution of golden recipes.
|
|
2
|
+
|
|
3
|
+
Each ``GoldenRecipe`` carries a ``validation_gate`` list of shell
|
|
4
|
+
commands that an LLM agent would otherwise reason about and run one
|
|
5
|
+
at a time. The replayer just runs them — no LLM round-trip per step
|
|
6
|
+
— and reports per-step verdict + token savings.
|
|
7
|
+
|
|
8
|
+
Token savings basis: each command an LLM would have planned + dispatched
|
|
9
|
+
costs ~80 tokens of round-trip overhead (read prior result, decide next
|
|
10
|
+
step, emit tool call). Replaying N commands deterministically avoids
|
|
11
|
+
N × 80 tokens.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import subprocess
|
|
16
|
+
import time
|
|
17
|
+
from dataclasses import asdict, dataclass
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
from ..a1_at_functions.lifetime_savings import append_savings
|
|
22
|
+
from ..a1_at_functions.recipes import get_recipe
|
|
23
|
+
|
|
24
|
+
SCHEMA_VERSION_REPLAY_V1 = "atomadic-forge.replay/v1"
|
|
25
|
+
TOKENS_PER_LLM_DISPATCH = 80
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class StepResult:
|
|
30
|
+
command: str
|
|
31
|
+
exit_code: int
|
|
32
|
+
duration_ms: int
|
|
33
|
+
stdout_tail: str
|
|
34
|
+
stderr_tail: str
|
|
35
|
+
skipped: bool = False
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class ReplayReport:
|
|
40
|
+
schema_version: str
|
|
41
|
+
recipe_name: str
|
|
42
|
+
project_root: str
|
|
43
|
+
steps: list[StepResult]
|
|
44
|
+
verdict: str # PASS | FAIL | PARTIAL
|
|
45
|
+
pass_count: int
|
|
46
|
+
fail_count: int
|
|
47
|
+
skipped_count: int
|
|
48
|
+
duration_ms: int
|
|
49
|
+
tokens_saved_estimate: int
|
|
50
|
+
|
|
51
|
+
def to_dict(self) -> dict[str, Any]:
|
|
52
|
+
return {**asdict(self),
|
|
53
|
+
"steps": [asdict(s) for s in self.steps]}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _tail(text: str, lines: int = 10) -> str:
|
|
57
|
+
if not text:
|
|
58
|
+
return ""
|
|
59
|
+
return "\n".join(text.splitlines()[-lines:])
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def replay_recipe(
|
|
63
|
+
*,
|
|
64
|
+
recipe_name: str,
|
|
65
|
+
project_root: Path,
|
|
66
|
+
stop_on_fail: bool = True,
|
|
67
|
+
dry_run: bool = False,
|
|
68
|
+
) -> ReplayReport:
|
|
69
|
+
"""Replay a golden recipe's ``validation_gate`` deterministically.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
recipe_name: name from :func:`recipes.list_recipes`.
|
|
73
|
+
project_root: cwd for the subprocesses.
|
|
74
|
+
stop_on_fail: when True, remaining steps are marked skipped on
|
|
75
|
+
the first non-zero exit. When False, every step runs and
|
|
76
|
+
failures accumulate.
|
|
77
|
+
dry_run: print the plan, mark all steps skipped, don't shell out.
|
|
78
|
+
|
|
79
|
+
Raises:
|
|
80
|
+
KeyError: when ``recipe_name`` is not in the catalogue.
|
|
81
|
+
"""
|
|
82
|
+
recipe = get_recipe(recipe_name)
|
|
83
|
+
if recipe is None:
|
|
84
|
+
raise KeyError(f"unknown recipe: {recipe_name!r}")
|
|
85
|
+
|
|
86
|
+
commands = list(recipe.get("validation_gate") or [])
|
|
87
|
+
project_root = Path(project_root).resolve()
|
|
88
|
+
|
|
89
|
+
t0 = time.monotonic()
|
|
90
|
+
steps: list[StepResult] = []
|
|
91
|
+
failed = False
|
|
92
|
+
for cmd in commands:
|
|
93
|
+
if dry_run or (failed and stop_on_fail):
|
|
94
|
+
steps.append(StepResult(
|
|
95
|
+
command=cmd, exit_code=-1, duration_ms=0,
|
|
96
|
+
stdout_tail="", stderr_tail="", skipped=True,
|
|
97
|
+
))
|
|
98
|
+
continue
|
|
99
|
+
s_t0 = time.monotonic()
|
|
100
|
+
try:
|
|
101
|
+
proc = subprocess.run( # noqa: S602
|
|
102
|
+
cmd, cwd=project_root, shell=True,
|
|
103
|
+
capture_output=True, text=True, timeout=600,
|
|
104
|
+
)
|
|
105
|
+
steps.append(StepResult(
|
|
106
|
+
command=cmd,
|
|
107
|
+
exit_code=proc.returncode,
|
|
108
|
+
duration_ms=int((time.monotonic() - s_t0) * 1000),
|
|
109
|
+
stdout_tail=_tail(proc.stdout),
|
|
110
|
+
stderr_tail=_tail(proc.stderr),
|
|
111
|
+
))
|
|
112
|
+
if proc.returncode != 0:
|
|
113
|
+
failed = True
|
|
114
|
+
except (OSError, subprocess.TimeoutExpired) as exc:
|
|
115
|
+
steps.append(StepResult(
|
|
116
|
+
command=cmd, exit_code=-2,
|
|
117
|
+
duration_ms=int((time.monotonic() - s_t0) * 1000),
|
|
118
|
+
stdout_tail="", stderr_tail=str(exc),
|
|
119
|
+
))
|
|
120
|
+
failed = True
|
|
121
|
+
|
|
122
|
+
pass_count = sum(1 for s in steps
|
|
123
|
+
if not s.skipped and s.exit_code == 0)
|
|
124
|
+
fail_count = sum(1 for s in steps
|
|
125
|
+
if not s.skipped and s.exit_code != 0)
|
|
126
|
+
skipped_count = sum(1 for s in steps if s.skipped)
|
|
127
|
+
|
|
128
|
+
if dry_run:
|
|
129
|
+
verdict = "DRY_RUN"
|
|
130
|
+
elif fail_count == 0 and pass_count > 0:
|
|
131
|
+
verdict = "PASS"
|
|
132
|
+
elif fail_count > 0 and pass_count > 0:
|
|
133
|
+
verdict = "PARTIAL"
|
|
134
|
+
else:
|
|
135
|
+
verdict = "FAIL"
|
|
136
|
+
|
|
137
|
+
# Token-savings: every non-skipped command avoided one LLM dispatch.
|
|
138
|
+
tokens_saved = (pass_count + fail_count) * TOKENS_PER_LLM_DISPATCH
|
|
139
|
+
|
|
140
|
+
if tokens_saved > 0 and not dry_run:
|
|
141
|
+
append_savings(
|
|
142
|
+
project_root=project_root,
|
|
143
|
+
tool=f"replay/{recipe_name}",
|
|
144
|
+
tokens_saved=tokens_saved,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
return ReplayReport(
|
|
148
|
+
schema_version=SCHEMA_VERSION_REPLAY_V1,
|
|
149
|
+
recipe_name=recipe_name,
|
|
150
|
+
project_root=str(project_root),
|
|
151
|
+
steps=steps,
|
|
152
|
+
verdict=verdict,
|
|
153
|
+
pass_count=pass_count,
|
|
154
|
+
fail_count=fail_count,
|
|
155
|
+
skipped_count=skipped_count,
|
|
156
|
+
duration_ms=int((time.monotonic() - t0) * 1000),
|
|
157
|
+
tokens_saved_estimate=tokens_saved,
|
|
158
|
+
)
|
{atomadic_forge-0.78.0 → atomadic_forge-0.79.0}/src/atomadic_forge/a4_sy_orchestration/cli.py
RENAMED
|
@@ -2739,6 +2739,11 @@ def _register_specialty_apps() -> None:
|
|
|
2739
2739
|
# lifetime_savings.jsonl automatically.
|
|
2740
2740
|
("atomadic_forge.commands.token_savings", "token-savings",
|
|
2741
2741
|
"Show the project's lifetime token-savings ledger."),
|
|
2742
|
+
# v0.79.0 — replay: deterministic golden-recipe execution.
|
|
2743
|
+
# Skips the LLM round-trip per step that an agent would
|
|
2744
|
+
# otherwise spend planning + dispatching each command.
|
|
2745
|
+
("atomadic_forge.commands.replay", "replay",
|
|
2746
|
+
"Replay a golden recipe's validation_gate deterministically."),
|
|
2742
2747
|
("atomadic_forge.commands.emergent_swarm", "emergent-swarm",
|
|
2743
2748
|
"Round-5: cross-repo emergent composition discovery."),
|
|
2744
2749
|
("atomadic_forge.commands.emergent_swarm", "emergent_swarm",
|
|
@@ -32,19 +32,14 @@ from atomadic_forge.a2_mo_composites.repo_public_surface_sync import (
|
|
|
32
32
|
from atomadic_forge.a3_og_features.forge_metrics_feature import emit_forge_metrics
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
def _live_cli_verb_count() -> int:
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"""
|
|
41
|
-
try:
|
|
42
|
-
from atomadic_forge.a4_sy_orchestration import cli as _cli
|
|
43
|
-
commands = getattr(_cli.app, "registered_commands", []) or []
|
|
44
|
-
groups = getattr(_cli.app, "registered_groups", []) or []
|
|
45
|
-
return len(commands) + len(groups)
|
|
46
|
-
except Exception:
|
|
35
|
+
def _live_cli_verb_count(project_root: Path = Path(".")) -> int:
|
|
36
|
+
"""Count CLI verbs by scanning cli.py for @app.command( decorators."""
|
|
37
|
+
import re
|
|
38
|
+
cli_path = project_root / "src" / "atomadic_forge" / "a4_sy_orchestration" / "cli.py"
|
|
39
|
+
if not cli_path.exists():
|
|
47
40
|
return 0
|
|
41
|
+
text = cli_path.read_text(encoding="utf-8", errors="replace")
|
|
42
|
+
return len(re.findall(r'@\w+\.command\(', text))
|
|
48
43
|
|
|
49
44
|
COMMAND_NAME = "metrics"
|
|
50
45
|
COMMAND_HELP = (
|
|
@@ -95,7 +90,7 @@ def run(
|
|
|
95
90
|
apply=apply,
|
|
96
91
|
proof_corpus_root=mhed,
|
|
97
92
|
skip_self_cert=not self_cert,
|
|
98
|
-
cli_verbs_count=_live_cli_verb_count(),
|
|
93
|
+
cli_verbs_count=_live_cli_verb_count(project),
|
|
99
94
|
tests_passing=tests_passing,
|
|
100
95
|
)
|
|
101
96
|
if json_out:
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Tier a4 — `forge replay` CLI surface.
|
|
2
|
+
|
|
3
|
+
Run a golden recipe's validation_gate deterministically — no LLM in
|
|
4
|
+
the loop. Each command an LLM would otherwise plan + dispatch costs
|
|
5
|
+
real round-trip tokens; replaying skips that overhead entirely.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Annotated
|
|
12
|
+
|
|
13
|
+
import typer
|
|
14
|
+
|
|
15
|
+
from atomadic_forge.a1_at_functions.recipes import list_recipes
|
|
16
|
+
from atomadic_forge.a3_og_features.recipe_replay import replay_recipe
|
|
17
|
+
|
|
18
|
+
COMMAND_NAME = "replay"
|
|
19
|
+
COMMAND_HELP = (
|
|
20
|
+
"Replay a golden recipe's validation_gate deterministically — zero "
|
|
21
|
+
"LLM round-trips. Use `--list` to see available recipes."
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
app = typer.Typer(no_args_is_help=False, help=COMMAND_HELP)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@app.callback(invoke_without_command=True)
|
|
28
|
+
def run(
|
|
29
|
+
recipe: Annotated[str, typer.Argument(
|
|
30
|
+
help="Recipe name (use --list to see all).")] = "",
|
|
31
|
+
project: Annotated[Path, typer.Option(
|
|
32
|
+
"--project", "-p",
|
|
33
|
+
help="Project root used as cwd for each step.",
|
|
34
|
+
exists=True, file_okay=False, dir_okay=True,
|
|
35
|
+
resolve_path=True)] = Path("."),
|
|
36
|
+
list_all: Annotated[bool, typer.Option(
|
|
37
|
+
"--list", help="List available recipes and exit.")] = False,
|
|
38
|
+
dry_run: Annotated[bool, typer.Option(
|
|
39
|
+
"--dry-run", help="Print the plan without running.")] = False,
|
|
40
|
+
keep_going: Annotated[bool, typer.Option(
|
|
41
|
+
"--keep-going",
|
|
42
|
+
help="Run every step even if one fails (default: stop on first fail).",
|
|
43
|
+
)] = False,
|
|
44
|
+
json_out: Annotated[bool, typer.Option(
|
|
45
|
+
"--json", help="Emit machine-readable JSON.")] = False,
|
|
46
|
+
) -> None:
|
|
47
|
+
"""Replay a recipe's validation_gate."""
|
|
48
|
+
if list_all:
|
|
49
|
+
names = list_recipes()
|
|
50
|
+
if json_out:
|
|
51
|
+
typer.echo(json.dumps({"recipes": names}, indent=2))
|
|
52
|
+
return
|
|
53
|
+
typer.echo("Available recipes:")
|
|
54
|
+
for n in names:
|
|
55
|
+
typer.echo(f" • {n}")
|
|
56
|
+
return
|
|
57
|
+
|
|
58
|
+
if not recipe:
|
|
59
|
+
typer.secho("forge replay: pass a recipe name or --list", fg="red", err=True)
|
|
60
|
+
raise typer.Exit(2)
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
report = replay_recipe(
|
|
64
|
+
recipe_name=recipe,
|
|
65
|
+
project_root=project,
|
|
66
|
+
stop_on_fail=not keep_going,
|
|
67
|
+
dry_run=dry_run,
|
|
68
|
+
)
|
|
69
|
+
except KeyError as exc:
|
|
70
|
+
typer.secho(f"forge replay: {exc}", fg="red", err=True)
|
|
71
|
+
raise typer.Exit(2) from exc
|
|
72
|
+
|
|
73
|
+
if json_out:
|
|
74
|
+
typer.echo(json.dumps(report.to_dict(), indent=2, default=str))
|
|
75
|
+
if report.verdict in ("FAIL", "PARTIAL"):
|
|
76
|
+
raise typer.Exit(1)
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
typer.echo("")
|
|
80
|
+
typer.echo(f"Replay — {recipe}")
|
|
81
|
+
typer.echo("-" * 60)
|
|
82
|
+
for i, step in enumerate(report.steps, 1):
|
|
83
|
+
if step.skipped:
|
|
84
|
+
mark = typer.style("SKIP", fg="yellow")
|
|
85
|
+
elif step.exit_code == 0:
|
|
86
|
+
mark = typer.style("PASS", fg="green")
|
|
87
|
+
else:
|
|
88
|
+
mark = typer.style("FAIL", fg="red")
|
|
89
|
+
typer.echo(f" [{i}] {mark} {step.command}")
|
|
90
|
+
if step.exit_code not in (0, -1) and step.stderr_tail:
|
|
91
|
+
for line in step.stderr_tail.splitlines()[:3]:
|
|
92
|
+
typer.echo(f" {line}")
|
|
93
|
+
typer.echo("-" * 60)
|
|
94
|
+
typer.echo(f" verdict: {report.verdict}")
|
|
95
|
+
typer.echo(f" pass / fail: {report.pass_count} / {report.fail_count}"
|
|
96
|
+
+ (f" ({report.skipped_count} skipped)"
|
|
97
|
+
if report.skipped_count else ""))
|
|
98
|
+
typer.echo(f" duration: {report.duration_ms} ms")
|
|
99
|
+
typer.echo(f" tokens saved: ~{report.tokens_saved_estimate:,}")
|
|
100
|
+
if report.verdict in ("FAIL", "PARTIAL"):
|
|
101
|
+
raise typer.Exit(1)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atomadic-forge
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.79.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
|
|
@@ -225,8 +225,8 @@ Full tool reference: [docs/MCP_TOOLS.md](docs/MCP_TOOLS.md) | First call: `welco
|
|
|
225
225
|
|
|
226
226
|
| MCP tools | **10 tools · 116 actions** |
|
|
227
227
|
| CLI verbs | **59** |
|
|
228
|
-
| Source files | **
|
|
229
|
-
| Tests | **
|
|
228
|
+
| Source files | **235** (~47K LOC) |
|
|
229
|
+
| Tests | **1597 passing** across **117 test files** |
|
|
230
230
|
| Lean4 formal proofs | **872 theorems** (mathematically verified core logic) |
|
|
231
231
|
| Monadic tiers | **5** (a0 → a4, strict upward-only composition) |
|
|
232
232
|
| Languages | Python, JS/TS, Swift, Kotlin, Go, Rust |
|
|
@@ -292,6 +292,7 @@ src/atomadic_forge/a3_og_features/lsp_server.py
|
|
|
292
292
|
src/atomadic_forge/a3_og_features/materialize_feature.py
|
|
293
293
|
src/atomadic_forge/a3_og_features/mcp_server.py
|
|
294
294
|
src/atomadic_forge/a3_og_features/nexus_bridge.py
|
|
295
|
+
src/atomadic_forge/a3_og_features/recipe_replay.py
|
|
295
296
|
src/atomadic_forge/a3_og_features/relay_daemon.py
|
|
296
297
|
src/atomadic_forge/a3_og_features/setup_wizard.py
|
|
297
298
|
src/atomadic_forge/a3_og_features/surface_export.py
|
|
@@ -336,6 +337,7 @@ src/atomadic_forge/commands/materialize.py
|
|
|
336
337
|
src/atomadic_forge/commands/metrics.py
|
|
337
338
|
src/atomadic_forge/commands/recon_swarm.py
|
|
338
339
|
src/atomadic_forge/commands/relay.py
|
|
340
|
+
src/atomadic_forge/commands/replay.py
|
|
339
341
|
src/atomadic_forge/commands/surface.py
|
|
340
342
|
src/atomadic_forge/commands/synergy.py
|
|
341
343
|
src/atomadic_forge/commands/synergy_then_emergent.py
|
|
@@ -429,6 +431,7 @@ tests/test_progress_reporter.py
|
|
|
429
431
|
tests/test_receipt_emitter.py
|
|
430
432
|
tests/test_receipt_schema.py
|
|
431
433
|
tests/test_receipt_signer.py
|
|
434
|
+
tests/test_recipe_replay.py
|
|
432
435
|
tests/test_remote_seed_store.py
|
|
433
436
|
tests/test_repo_public_surface.py
|
|
434
437
|
tests/test_response_enricher.py
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""Tests for `forge replay` — deterministic recipe execution."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from atomadic_forge.a3_og_features.recipe_replay import (
|
|
9
|
+
SCHEMA_VERSION_REPLAY_V1,
|
|
10
|
+
TOKENS_PER_LLM_DISPATCH,
|
|
11
|
+
replay_recipe,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_unknown_recipe_raises(tmp_path: Path) -> None:
|
|
16
|
+
with pytest.raises(KeyError):
|
|
17
|
+
replay_recipe(recipe_name="not_a_real_recipe", project_root=tmp_path)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_dry_run_marks_all_skipped_no_savings(tmp_path: Path, monkeypatch) -> None:
|
|
21
|
+
"""Dry-run runs no commands, logs no savings."""
|
|
22
|
+
# Inject a recipe with two trivial commands.
|
|
23
|
+
from atomadic_forge.a1_at_functions import recipes as r
|
|
24
|
+
monkeypatch.setitem(r._RECIPES, "test_demo", {
|
|
25
|
+
"schema_version": "atomadic-forge.recipe/v1",
|
|
26
|
+
"name": "test_demo",
|
|
27
|
+
"validation_gate": ["python -c \"print('ok')\"",
|
|
28
|
+
"python -c \"print('also ok')\""],
|
|
29
|
+
})
|
|
30
|
+
report = replay_recipe(recipe_name="test_demo",
|
|
31
|
+
project_root=tmp_path, dry_run=True)
|
|
32
|
+
assert report.schema_version == SCHEMA_VERSION_REPLAY_V1
|
|
33
|
+
assert report.verdict == "DRY_RUN"
|
|
34
|
+
assert report.skipped_count == 2
|
|
35
|
+
assert report.pass_count == 0
|
|
36
|
+
assert report.tokens_saved_estimate == 0
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_all_pass_logs_full_savings(tmp_path: Path, monkeypatch) -> None:
|
|
40
|
+
"""All pass ⇒ verdict PASS and N × 80 token savings."""
|
|
41
|
+
from atomadic_forge.a1_at_functions import recipes as r
|
|
42
|
+
monkeypatch.setitem(r._RECIPES, "test_pass", {
|
|
43
|
+
"schema_version": "atomadic-forge.recipe/v1",
|
|
44
|
+
"name": "test_pass",
|
|
45
|
+
"validation_gate": ["python -c \"print('a')\"",
|
|
46
|
+
"python -c \"print('b')\""],
|
|
47
|
+
})
|
|
48
|
+
report = replay_recipe(recipe_name="test_pass", project_root=tmp_path)
|
|
49
|
+
assert report.verdict == "PASS"
|
|
50
|
+
assert report.pass_count == 2
|
|
51
|
+
assert report.fail_count == 0
|
|
52
|
+
assert report.tokens_saved_estimate == 2 * TOKENS_PER_LLM_DISPATCH
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_first_fail_skips_remaining_by_default(tmp_path: Path, monkeypatch) -> None:
|
|
56
|
+
"""stop_on_fail (default) marks remaining steps skipped after a fail."""
|
|
57
|
+
from atomadic_forge.a1_at_functions import recipes as r
|
|
58
|
+
monkeypatch.setitem(r._RECIPES, "test_fail", {
|
|
59
|
+
"schema_version": "atomadic-forge.recipe/v1",
|
|
60
|
+
"name": "test_fail",
|
|
61
|
+
"validation_gate": [
|
|
62
|
+
"python -c \"import sys; sys.exit(3)\"",
|
|
63
|
+
"python -c \"print('never runs')\"",
|
|
64
|
+
],
|
|
65
|
+
})
|
|
66
|
+
report = replay_recipe(recipe_name="test_fail", project_root=tmp_path)
|
|
67
|
+
assert report.verdict == "FAIL"
|
|
68
|
+
assert report.fail_count == 1
|
|
69
|
+
assert report.skipped_count == 1
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_keep_going_runs_every_step(tmp_path: Path, monkeypatch) -> None:
|
|
73
|
+
"""stop_on_fail=False keeps running after a failure."""
|
|
74
|
+
from atomadic_forge.a1_at_functions import recipes as r
|
|
75
|
+
monkeypatch.setitem(r._RECIPES, "test_keep", {
|
|
76
|
+
"schema_version": "atomadic-forge.recipe/v1",
|
|
77
|
+
"name": "test_keep",
|
|
78
|
+
"validation_gate": [
|
|
79
|
+
"python -c \"import sys; sys.exit(1)\"",
|
|
80
|
+
"python -c \"print('still runs')\"",
|
|
81
|
+
],
|
|
82
|
+
})
|
|
83
|
+
report = replay_recipe(recipe_name="test_keep",
|
|
84
|
+
project_root=tmp_path, stop_on_fail=False)
|
|
85
|
+
assert report.verdict == "PARTIAL"
|
|
86
|
+
assert report.pass_count == 1
|
|
87
|
+
assert report.fail_count == 1
|
|
88
|
+
assert report.skipped_count == 0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|