atomadic-forge 0.16.0__tar.gz → 0.16.2__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.16.0 → atomadic_forge-0.16.2}/CHANGELOG.md +47 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/PKG-INFO +2 -2
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/README.md +1 -1
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/pyproject.toml +1 -1
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/welcome_constants.py +8 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/welcome_feature.py +47 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a4_sy_orchestration/cli.py +272 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/welcome.py +14 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge.egg-info/PKG-INFO +2 -2
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_welcome.py +24 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/FUNDING.yml +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/actions/forge-action/README.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/actions/forge-action/action.yml +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/dependabot.yml +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/pull_request_template.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/workflows/ci.yml +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/workflows/customer-refactor.yml +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/workflows/forge-self-certify.yml +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/workflows/release.yml +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/.github/workflows/surface-drift.yml +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/ARCHITECTURE.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/CONTRIBUTING.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/LICENSE +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/MANIFEST.in +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/SECURITY.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/assets/Atomadic-Forge-01.png +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/01-getting-started.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/02-commands.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/03-tutorial.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/04-llm-loops.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/05-faq.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/AGENTS_GUIDE.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/AIR_GAPPED.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/CI_CD.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/CODEX_WALKTHROUGH.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/COMMANDS.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/FIRST_10_MINUTES.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/FORMALIZATION.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/HIVE_PRIMITIVES.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/HIVE_STATUS.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/LANDSCAPE.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/MARKET_POSITIONING.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/MIGRATION.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/MULTI_REPO.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/README.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/RECEIPT.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/RELAY_PROTOCOL.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/RELEASE_CHECKLIST.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/RELEASE_MESSAGING.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/ROADMAP.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/SHOWCASE.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/SIDECAR.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/STUDIO.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/TOOL_FACTORY_WALKTHROUGH.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/WHY_NOW.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/WORKER_VS_LOCAL_MCP.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/WORLD_COLLISION.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/INDEX.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/chat.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/commandsmith.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/config.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/demo.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/emergent-then-synergy.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/emergent.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/evolve-then-iterate.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/evolve.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/feature-then-emergent.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/iterate.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/synergy-then-emergent.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/commands/synergy.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/compliance/CMMC_AI_MAPPING.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/compliance/CS-1.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/compliance/EU_AI_ACT_ANNEX_IV.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/compliance/FDA_PCCP_MAPPING.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/compliance/SR_11-7_MAPPING.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/handoffs/WORKER_AUTO_DEPLOY_2026-05-06.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/tutorials/01-quickstart.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/tutorials/02-your-first-package.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/tutorials/03-the-five-tier-law.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/tutorials/04-plug-in-llms.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/tutorials/05-multi-repo-absorb.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/docs/tutorials/06-javascript-quickstart.md +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/setup.cfg +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/__init__.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/__main__.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/__init__.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/agent_plan_schema.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/auth_constants.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/commandsmith_types.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/config_defaults.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/emergent_types.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/enhancement_proposal_constants.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/error_codes.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/forge_types.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/gen_language.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/handoff_constants.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/hive_constants.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/lang_extensions.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/lifetime_savings_constants.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/materialize_types.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/mhed_invariants.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/nexus_constants.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/policy_schema.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/receipt_schema.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/response_enrichment.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/roi_constants.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/schema_version_registry.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/semantic_types.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/sidecar_schema.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/synergy_types.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/tier_names.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a0_qk_constants/wisdom_constants.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/__init__.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/agent_context_pack.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/agent_memory.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/agent_plan_emitter.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/agent_summary.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/body_extractor.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/call_graph.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/card_renderer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/certify_checks.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/chat_context.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/cherry_pick.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/classify_tier.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/code_signature.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/commandsmith_discover.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/commandsmith_render.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/compiler_feedback.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/compliance_checker.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/config_io.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/cs1_renderer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/doc_synthesizer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/emergent_compose.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/emergent_rank.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/emergent_signature_extract.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/emergent_synthesize.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/enforce_planner.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/enhancement_proposal_builder.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/error_hints.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/evolution_log.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/exported_api_check.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/forge_auth.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/forge_feedback.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/forge_locate.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/generation_quality.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/handoff_builder.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/hive_consensus_math.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/hive_io.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/import_repair.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/import_smoke.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/intent_similarity.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/js_parser.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/lifetime_savings.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/lineage_chain.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/lineage_reader.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/llm_client.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/local_signer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/lsp_protocol.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/manifest_diff.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/mcp_protocol.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/patch_scorer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/plan_adapter.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/policy_loader.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/preflight_change.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/progress_reporter.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/provider_detect.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/provider_resolver.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/receipt_emitter.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/recipes.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/repo_explainer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/research_note_distiller.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/response_enricher.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/roi_calculator.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/rollback_planner.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/sbom_emitter.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/scaffold_js.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/scaffold_pyproject.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/scaffold_starter.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/scout_walk.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/sidecar_parser.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/sidecar_validator.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/smell_scan.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/stub_detector.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/synergy_detect.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/synergy_render.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/synergy_surface_extract.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/test_runner.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/test_selector.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/tier_init_rebuild.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/tool_composer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/transcript_log.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/trust_gate_response.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/validation_commands.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/welcome_narrator.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/wire_check.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/wisdom_capture.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/wisdom_io.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/wisdom_promote.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/wisdom_recall.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a1_at_functions/worktree_status.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/__init__.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/cost_circuit_breaker.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/cross_agent_intent_deduplicator.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/evolve_session_store.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/forge_auth_client.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/hierarchical_memory.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/iterate_session_store.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/lineage_chain_store.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/manifest_store.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/nexus_client.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/plan_store.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a2_mo_composites/receipt_signer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/__init__.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/agent_hire_protocol.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/cherry_hunter.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/cna_check.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/commandsmith_feature.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/commit_compose.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/create_feature.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/dedup_engine.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/__init__.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/a0_qk_constants/__init__.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/src/mixed_pkg/a1_at_functions/__init__.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/tests/conftest.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/demo_packages/mixed_py_js/tests/test_mixed.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/demo_runner.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/emergent_feature.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/emergent_pipeline_integration.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/emergent_swarm.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/enhancement_proposal_feature.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/forge_enforce.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/forge_evolve.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/forge_evolve_session.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/forge_loop.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/forge_loop_session.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/forge_pipeline.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/forge_plan_apply.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/guard_install.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/handoff_feature.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/hive_sync.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/lsp_server.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/materialize_feature.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/mcp_server.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/nexus_bridge.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/relay_daemon.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/setup_wizard.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/surface_export.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/synergy_feature.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/tool_factory.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/verify_umbrella.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/wisdom_feature.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a4_sy_orchestration/__init__.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a4_sy_orchestration/copilots_cmd.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a4_sy_orchestration/login_cmd.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a4_sy_orchestration/whoami_cmd.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/__init__.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/_registry.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/audit.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/chat.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/commandsmith.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/config_cmd.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/create.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/demo.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/emergent.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/emergent_swarm.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/emergent_then_synergy.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/enhancement.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/evolve.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/evolve_then_iterate.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/feature_then_emergent.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/guard_install.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/handoff.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/harvest.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/hive.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/iterate.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/materialize.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/recon_swarm.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/relay.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/surface.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/synergy.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/synergy_then_emergent.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/commands/wisdom.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge.egg-info/SOURCES.txt +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge.egg-info/dependency_links.txt +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge.egg-info/entry_points.txt +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge.egg-info/requires.txt +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge.egg-info/top_level.txt +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_aaaa_nexus_client.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_agent_hire_protocol.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_agent_plan.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_agent_plan_pkg_label.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_agent_summary.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_audit_verb.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_body_extractor_repairs.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_card_renderer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_certify_operational_axis.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_chat.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_classify_tier.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_classify_tier_ast_signals.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_cli_smoke.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_cli_swarm_aliases.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_codex_5_complete.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_codex_6_enforce_polyglot.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_commandsmith.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_compiler_feedback.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_compliance_checker.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_config.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_copilots_copilot.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_cost_circuit_breaker.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_create_feature.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_cs1_renderer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_dedup_engine.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_demo.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_emergent_compose.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_emergent_signature_extract.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_emergent_synthesize_imports.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_enhancement_proposal.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_error_codes.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_error_hints.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_evolve_js.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_exported_api_check.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_forge_action.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_forge_auth_a1.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_forge_auth_a2.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_forge_enforce.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_generation_quality.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_handoff.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_hierarchical_memory.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_hive_sync.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_ignore_and_docs.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_import_smoke.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_iterate_evolve.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_js_certify.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_js_parser.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_js_recon.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_js_wire.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_lineage_chain.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_ling_provider.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_local_signer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_lsp_protocol.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_manifest_diff.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_materialize_feature.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_mcp_protocol.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_nexus_bridge.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_ollama_client.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_pipeline.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_plan_apply.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_polyglot_swift_kotlin_go.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_pre_audit_smoke.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_precommit_hooks.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_progress_reporter.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_receipt_emitter.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_receipt_schema.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_receipt_signer.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_response_enricher.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_roi_calculator.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_sbom_cmd_text_summary.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_sbom_emitter.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_scaffold.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_sidecar.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_sidecar_validate.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_smell_score_formula.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_stagnation.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_stub_detector.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_surface_export.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_synergy.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_test_runner.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_tier_init_rebuild.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_trust_gate_response.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_verify_suggested_recipe.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_welcome_enhancements.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_whoami_cmd.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_wire_certify.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_wire_suggest_repairs.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_wire_type_checking.py +0 -0
- {atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/tests/test_wisdom.py +0 -0
|
@@ -2,6 +2,53 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## v0.16.2 — 2026-05-06 welcome scope guard + Boris pre-demo hardening
|
|
6
|
+
|
|
7
|
+
Pre-Boris-demo stress test surfaced a single class of welcome failure:
|
|
8
|
+
running ``forge welcome`` (or the welcome MCP tool) from a workspace
|
|
9
|
+
root walks every source file in every subdirectory. In the rehearsal
|
|
10
|
+
that meant 38 972 .py files instead of the 280 inside atomadic-forge,
|
|
11
|
+
and the call appeared to "hang." This release stops that at the
|
|
12
|
+
substrate.
|
|
13
|
+
|
|
14
|
+
- **welcome scope guard** — ``forge welcome`` now refuses to walk a
|
|
15
|
+
project root that holds more than ``--max-files`` (default 5 000)
|
|
16
|
+
source files, returning a structured ``verdict: REFUSE`` with the
|
|
17
|
+
observed file count and a clear "pass --project-root <narrower>
|
|
18
|
+
or --force" message. CLI exits 2; MCP returns the same shape.
|
|
19
|
+
Counted via an ``itertools.islice`` over ``iter_source_files``,
|
|
20
|
+
so the guard itself bails in milliseconds.
|
|
21
|
+
- **--force / --max-files** flags on ``forge welcome`` for the rare
|
|
22
|
+
case where a 5 000+ file repo is the right scope.
|
|
23
|
+
- **PyPI install hygiene note** — the v0.16.x rehearsal also surfaced
|
|
24
|
+
that interrupted ``pip install --upgrade`` runs on Windows leave
|
|
25
|
+
``~tomadic_forge*`` shadow distribution directories in
|
|
26
|
+
``site-packages`` which can mask the active editable install on
|
|
27
|
+
long-running MCP processes. Standard pip recovery is
|
|
28
|
+
``pip install --upgrade --force-reinstall atomadic-forge`` (then
|
|
29
|
+
delete any remaining ``~*`` dirs). Documented in
|
|
30
|
+
``docs/troubleshooting/pip-shadow-dirs.md``.
|
|
31
|
+
|
|
32
|
+
## v0.16.1 — 2026-05-06 six new CLI verbs (verify, smell, call-graph, cna-check, trust-gate, commit-compose)
|
|
33
|
+
|
|
34
|
+
Six MCP-only tools that had no corresponding CLI verb are now reachable
|
|
35
|
+
from the shell. No behavioural changes to existing verbs.
|
|
36
|
+
|
|
37
|
+
- **forge verify** — composite wire + certify gate; single PASS / REFINE / FAIL
|
|
38
|
+
verdict + non-zero exit code for CI steps. Wraps the `verify` MCP tool.
|
|
39
|
+
- **forge smell** — cyclomatic-complexity + long-function + duplicate-code scan;
|
|
40
|
+
emits a `smell_score` (0–100) and a ranked offender list. Wraps `smell_scan`.
|
|
41
|
+
- **forge call-graph** — AST call-graph for one symbol; shows callers and callees
|
|
42
|
+
up to `--max-depth` with optional `--direction` filter. Wraps `call_graph`.
|
|
43
|
+
- **forge cna-check** — Compose-Not-Add guard; fails with exit 1 when a proposed
|
|
44
|
+
symbol name is semantically equivalent to an existing one. Wraps `cna_check`.
|
|
45
|
+
- **forge trust-gate** — LLM response hallucination detector; reads a response from
|
|
46
|
+
a file or stdin, scores it against known capabilities, exits 1 when
|
|
47
|
+
`safe_to_act` is False. Wraps `trust_gate_response`.
|
|
48
|
+
- **forge commit-compose** — structured commit-message assembler; writes a
|
|
49
|
+
Forge-signed subject + body + optional Co-Authored-By trailer to stdout.
|
|
50
|
+
Wraps `commit_compose`.
|
|
51
|
+
|
|
5
52
|
## v0.16.0 — 2026-05-06 dress-rehearsal hardening (six bugfixes, 11 new tests)
|
|
6
53
|
|
|
7
54
|
Live stress-test on real third-party Python repos (atomadic-forge,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atomadic-forge
|
|
3
|
-
Version: 0.16.
|
|
3
|
+
Version: 0.16.2
|
|
4
4
|
Summary: Atomadic Forge — absorb, enforce, emerge. Polyglot (Python · JavaScript/TypeScript · Swift · Kotlin · Go) architecture guardian for AI-generated code.
|
|
5
5
|
Author: Atomadic
|
|
6
6
|
License-Expression: BUSL-1.1
|
|
@@ -74,7 +74,7 @@ stays in the loop.
|
|
|
74
74
|
|
|
75
75
|
### What just shipped (v0.16.0)
|
|
76
76
|
|
|
77
|
-
- **
|
|
77
|
+
- ** hardening — six bugfixes, eleven new tests** (v0.16.0) — live stress-test on three real Python repos (atomadic-forge, langgraph, crewai) ahead of the Boris demo surfaced six bugs across the synthesis, planning, summary, and pipeline-pipe surfaces. `emergent synthesize` no longer emits broken `from pkg.mod.Class import method`; `forge plan` no longer suggests a literal `your_pkg` placeholder; `forge score-patch --file -` honours the stdin sentinel; `forge sbom` text summary reports the real component count; `recon-swarm/emergent-swarm/guard-install` register both hyphen and underscore forms so `commandsmith smoke` is 100% green; `synergy-then-emergent` and `emergent-then-synergy` pipes use the real `--save FILE` flag. Single-seed `forge create` jumped from certify=60/FAIL to **certify=90/100** with importable code on first generation. Test suite 1,291 → 1,302 passed.
|
|
78
78
|
|
|
79
79
|
### What previously shipped (v0.15.0)
|
|
80
80
|
|
|
@@ -42,7 +42,7 @@ stays in the loop.
|
|
|
42
42
|
|
|
43
43
|
### What just shipped (v0.16.0)
|
|
44
44
|
|
|
45
|
-
- **
|
|
45
|
+
- ** hardening — six bugfixes, eleven new tests** (v0.16.0) — live stress-test on three real Python repos (atomadic-forge, langgraph, crewai) ahead of the Boris demo surfaced six bugs across the synthesis, planning, summary, and pipeline-pipe surfaces. `emergent synthesize` no longer emits broken `from pkg.mod.Class import method`; `forge plan` no longer suggests a literal `your_pkg` placeholder; `forge score-patch --file -` honours the stdin sentinel; `forge sbom` text summary reports the real component count; `recon-swarm/emergent-swarm/guard-install` register both hyphen and underscore forms so `commandsmith smoke` is 100% green; `synergy-then-emergent` and `emergent-then-synergy` pipes use the real `--save FILE` flag. Single-seed `forge create` jumped from certify=60/FAIL to **certify=90/100** with importable code on first generation. Test suite 1,291 → 1,302 passed.
|
|
46
46
|
|
|
47
47
|
### What previously shipped (v0.15.0)
|
|
48
48
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "atomadic-forge"
|
|
7
|
-
version = "0.16.
|
|
7
|
+
version = "0.16.2"
|
|
8
8
|
description = "Atomadic Forge — absorb, enforce, emerge. Polyglot (Python · JavaScript/TypeScript · Swift · Kotlin · Go) architecture guardian for AI-generated code."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -30,9 +30,17 @@ HEALTH_LABEL_THRESHOLDS: Final[tuple[tuple[float, str], ...]] = (
|
|
|
30
30
|
TOP_N_STRENGTHS: Final[int] = 3
|
|
31
31
|
TOP_N_PRIORITIES: Final[int] = 3
|
|
32
32
|
|
|
33
|
+
# Scope guard — refuse to walk monstrously large trees by accident.
|
|
34
|
+
# A welcome run scoped at a workspace root rather than a single repo
|
|
35
|
+
# (e.g. ``cd C:\!!AtomadicStandard && forge welcome``) was the actual
|
|
36
|
+
# cause of the v0.16.1 "welcome hangs" report: 38 972 .py files.
|
|
37
|
+
# Boris-demo lesson — prevent it at the substrate.
|
|
38
|
+
SCOPE_GUARD_DEFAULT_MAX_FILES: Final[int] = 5000
|
|
39
|
+
|
|
33
40
|
__all__ = [
|
|
34
41
|
"HEALTH_LABEL_THRESHOLDS",
|
|
35
42
|
"SCHEMA_VERSION_WELCOME_V1",
|
|
43
|
+
"SCOPE_GUARD_DEFAULT_MAX_FILES",
|
|
36
44
|
"TOP_N_PRIORITIES",
|
|
37
45
|
"TOP_N_STRENGTHS",
|
|
38
46
|
]
|
{atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a3_og_features/welcome_feature.py
RENAMED
|
@@ -18,9 +18,12 @@ import time
|
|
|
18
18
|
from pathlib import Path
|
|
19
19
|
from typing import Any
|
|
20
20
|
|
|
21
|
+
import itertools
|
|
22
|
+
|
|
21
23
|
from .. import __version__
|
|
22
24
|
from ..a0_qk_constants.welcome_constants import (
|
|
23
25
|
SCHEMA_VERSION_WELCOME_V1,
|
|
26
|
+
SCOPE_GUARD_DEFAULT_MAX_FILES,
|
|
24
27
|
)
|
|
25
28
|
from ..a1_at_functions.certify_checks import certify as _certify
|
|
26
29
|
from ..a1_at_functions.lifetime_savings import (
|
|
@@ -31,6 +34,7 @@ from ..a1_at_functions.lifetime_savings import (
|
|
|
31
34
|
)
|
|
32
35
|
from ..a1_at_functions.mcp_protocol import TOOLS as _TOOLS
|
|
33
36
|
from ..a1_at_functions.scout_walk import harvest_repo as _scout
|
|
37
|
+
from ..a1_at_functions.scout_walk import iter_source_files as _iter_source_files
|
|
34
38
|
from ..a1_at_functions.welcome_narrator import (
|
|
35
39
|
build_agent_guidance,
|
|
36
40
|
build_capability_showcase,
|
|
@@ -113,12 +117,24 @@ def _diff_against(
|
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
|
|
120
|
+
def _count_source_files_capped(project_root: Path, *, cap: int) -> int:
|
|
121
|
+
"""Cheaply count source files, stopping after ``cap + 1`` matches.
|
|
122
|
+
|
|
123
|
+
Pure: just consumes the existing ``iter_source_files`` iterator.
|
|
124
|
+
Returns the count seen; if the count equals ``cap + 1`` the caller
|
|
125
|
+
knows the tree is *at least* that big without walking the rest.
|
|
126
|
+
"""
|
|
127
|
+
return sum(1 for _ in itertools.islice(_iter_source_files(project_root), cap + 1))
|
|
128
|
+
|
|
129
|
+
|
|
116
130
|
def welcome(
|
|
117
131
|
*,
|
|
118
132
|
project_root: Path,
|
|
119
133
|
package: str | None = None,
|
|
120
134
|
since_receipt: Path | str | None = None,
|
|
121
135
|
skip_certify: bool = False,
|
|
136
|
+
force: bool = False,
|
|
137
|
+
max_files: int = SCOPE_GUARD_DEFAULT_MAX_FILES,
|
|
122
138
|
) -> dict[str, Any]:
|
|
123
139
|
"""Run the welcome handshake on ``project_root``.
|
|
124
140
|
|
|
@@ -128,12 +144,43 @@ def welcome(
|
|
|
128
144
|
``skip_certify`` (test convenience) — when True, skip the
|
|
129
145
|
expensive certify pass and emit a partial welcome (scout + wire
|
|
130
146
|
only). Production callers should leave this False.
|
|
147
|
+
``force`` — bypass the scope guard. Use only when you know the
|
|
148
|
+
tree is genuinely the right scope to scan.
|
|
149
|
+
``max_files`` — scope guard threshold. Default is
|
|
150
|
+
``SCOPE_GUARD_DEFAULT_MAX_FILES`` (5 000); pass a higher number
|
|
151
|
+
on intentionally-large monorepos.
|
|
131
152
|
"""
|
|
132
153
|
project_root = Path(project_root).resolve()
|
|
133
154
|
repo_name = project_root.name
|
|
134
155
|
|
|
135
156
|
t0 = time.monotonic()
|
|
136
157
|
|
|
158
|
+
# Scope guard — refuse to walk monstrously large trees by accident.
|
|
159
|
+
# Stops as soon as the cap is exceeded; a 38k-file workspace bails
|
|
160
|
+
# in milliseconds instead of grinding through the AST walk.
|
|
161
|
+
if not force:
|
|
162
|
+
seen = _count_source_files_capped(project_root, cap=max_files)
|
|
163
|
+
if seen > max_files:
|
|
164
|
+
return {
|
|
165
|
+
"schema_version": SCHEMA_VERSION_WELCOME_V1,
|
|
166
|
+
"forge_version": __version__,
|
|
167
|
+
"repo_name": repo_name,
|
|
168
|
+
"repo_path": str(project_root),
|
|
169
|
+
"duration_ms": int((time.monotonic() - t0) * 1000),
|
|
170
|
+
"verdict": "REFUSE",
|
|
171
|
+
"reason": "scope_guard",
|
|
172
|
+
"source_file_count_at_least": seen,
|
|
173
|
+
"scope_guard_max_files": max_files,
|
|
174
|
+
"narrative": (
|
|
175
|
+
f"Scope guard tripped: {project_root} has at least "
|
|
176
|
+
f"{seen} source files (cap {max_files}). This usually "
|
|
177
|
+
"means welcome was run from a workspace root rather "
|
|
178
|
+
"than a single repo. Pass --project-root <narrower-path> "
|
|
179
|
+
"or --force to override."
|
|
180
|
+
),
|
|
181
|
+
"available_tools": len(_TOOLS),
|
|
182
|
+
}
|
|
183
|
+
|
|
137
184
|
# scout / wire / (optional) certify in sequence — they share I/O
|
|
138
185
|
# against the same tree; concurrency wouldn't help much here
|
|
139
186
|
# because the bottleneck is filesystem walk, not CPU.
|
{atomadic_forge-0.16.0 → atomadic_forge-0.16.2}/src/atomadic_forge/a4_sy_orchestration/cli.py
RENAMED
|
@@ -1071,6 +1071,278 @@ def status_cmd(
|
|
|
1071
1071
|
raise typer.Exit(code=1)
|
|
1072
1072
|
|
|
1073
1073
|
|
|
1074
|
+
@app.command("verify")
|
|
1075
|
+
def verify_cmd(
|
|
1076
|
+
project_root: Annotated[Path, typer.Argument(
|
|
1077
|
+
exists=True, file_okay=False, dir_okay=True, resolve_path=True,
|
|
1078
|
+
help="Project root to verify.")] = Path("."),
|
|
1079
|
+
package: Annotated[str | None, typer.Option(
|
|
1080
|
+
"--package", help="Python package sub-directory.")] = None,
|
|
1081
|
+
fail_under: Annotated[float, typer.Option(
|
|
1082
|
+
"--fail-under",
|
|
1083
|
+
help="Certify score threshold; exit 1 when below.")] = 75.0,
|
|
1084
|
+
json_out: Annotated[bool, typer.Option("--json")] = False,
|
|
1085
|
+
) -> None:
|
|
1086
|
+
"""Composite wire + certify gate — one verdict, one exit code.
|
|
1087
|
+
|
|
1088
|
+
Runs wire (upward-import scanner) and certify (score) in sequence
|
|
1089
|
+
and synthesises a single PASS / REFINE / FAIL verdict. Designed
|
|
1090
|
+
for CI steps where you want a binary answer and a non-zero exit on
|
|
1091
|
+
failure without having to chain two commands.
|
|
1092
|
+
"""
|
|
1093
|
+
wire_report = scan_violations(project_root)
|
|
1094
|
+
certify_report = certify_checks(project_root, project=project_root.name,
|
|
1095
|
+
package=package)
|
|
1096
|
+
violations = wire_report["violation_count"]
|
|
1097
|
+
score = float(certify_report["score"])
|
|
1098
|
+
|
|
1099
|
+
if violations == 0 and score >= fail_under:
|
|
1100
|
+
verdict = "PASS"
|
|
1101
|
+
elif violations <= 2 and score >= fail_under * 0.85:
|
|
1102
|
+
verdict = "REFINE"
|
|
1103
|
+
else:
|
|
1104
|
+
verdict = "FAIL"
|
|
1105
|
+
|
|
1106
|
+
result = {
|
|
1107
|
+
"schema_version": "atomadic-forge.verify/v1",
|
|
1108
|
+
"project": str(project_root),
|
|
1109
|
+
"verdict": verdict,
|
|
1110
|
+
"wire": {"violations": violations, "verdict": wire_report.get("verdict")},
|
|
1111
|
+
"certify": {"score": score, "issues": certify_report.get("issues", [])},
|
|
1112
|
+
"threshold": fail_under,
|
|
1113
|
+
}
|
|
1114
|
+
if json_out:
|
|
1115
|
+
typer.echo(json.dumps(result, indent=2, default=str))
|
|
1116
|
+
if verdict == "FAIL":
|
|
1117
|
+
raise typer.Exit(code=1)
|
|
1118
|
+
return
|
|
1119
|
+
typer.echo(f"\nForge verify: {project_root}")
|
|
1120
|
+
typer.echo("-" * 60)
|
|
1121
|
+
typer.echo(f" wire: {'PASS' if violations == 0 else 'FAIL':5s} {violations} violation(s)")
|
|
1122
|
+
typer.echo(f" certify: {score:.0f}/100 (threshold {fail_under:g})")
|
|
1123
|
+
for issue in certify_report.get("issues", []):
|
|
1124
|
+
typer.echo(f" - {issue}")
|
|
1125
|
+
typer.echo(f"\n verdict: {verdict}")
|
|
1126
|
+
if verdict == "FAIL":
|
|
1127
|
+
raise typer.Exit(code=1)
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
@app.command("smell")
|
|
1131
|
+
def smell_cmd(
|
|
1132
|
+
project_root: Annotated[Path, typer.Argument(
|
|
1133
|
+
exists=True, file_okay=False, dir_okay=True, resolve_path=True,
|
|
1134
|
+
help="Project root to scan.")] = Path("."),
|
|
1135
|
+
cc_threshold: Annotated[int, typer.Option(
|
|
1136
|
+
"--cc", help="Cyclomatic complexity threshold (default 10).")] = 10,
|
|
1137
|
+
loc_threshold: Annotated[int, typer.Option(
|
|
1138
|
+
"--loc", help="Lines-per-function threshold (default 50).")] = 50,
|
|
1139
|
+
package: Annotated[str | None, typer.Option(
|
|
1140
|
+
"--package", help="Python package sub-directory.")] = None,
|
|
1141
|
+
json_out: Annotated[bool, typer.Option("--json")] = False,
|
|
1142
|
+
) -> None:
|
|
1143
|
+
"""Code smell scan — cyclomatic complexity, long functions, duplicates.
|
|
1144
|
+
|
|
1145
|
+
Reports a smell_score (0–100, higher is worse) and a prioritised
|
|
1146
|
+
list of the worst offenders so you know exactly where to refactor.
|
|
1147
|
+
"""
|
|
1148
|
+
from ..a1_at_functions.smell_scan import smell_scan
|
|
1149
|
+
report = smell_scan(project_root, cc_threshold=cc_threshold,
|
|
1150
|
+
loc_threshold=loc_threshold, package_subdir=package)
|
|
1151
|
+
if json_out:
|
|
1152
|
+
typer.echo(json.dumps(report.as_dict(), indent=2, default=str))
|
|
1153
|
+
return
|
|
1154
|
+
d = report.as_dict()
|
|
1155
|
+
typer.echo(f"\nForge smell: {project_root}")
|
|
1156
|
+
typer.echo("-" * 60)
|
|
1157
|
+
typer.echo(f" smell_score: {d['smell_score']}/100")
|
|
1158
|
+
typer.echo(f" files scanned:{d.get('files_scanned', '?')}")
|
|
1159
|
+
typer.echo(f" smells found: {d.get('total_smells', len(d.get('smells', [])))}")
|
|
1160
|
+
smells = d.get("smells", [])[:10]
|
|
1161
|
+
if smells:
|
|
1162
|
+
typer.echo(" top offenders:")
|
|
1163
|
+
for s in smells:
|
|
1164
|
+
typer.echo(f" [{s.get('code', '?')}] {s.get('location', '?')} — {s.get('message', '')}")
|
|
1165
|
+
if d["smell_score"] == 0:
|
|
1166
|
+
typer.echo(" ✓ No smells detected")
|
|
1167
|
+
|
|
1168
|
+
|
|
1169
|
+
@app.command("call-graph")
|
|
1170
|
+
def call_graph_cmd(
|
|
1171
|
+
qualname: Annotated[str, typer.Argument(
|
|
1172
|
+
help="Fully-qualified symbol name (e.g. my_pkg.utils.parse_line).")],
|
|
1173
|
+
project_root: Annotated[Path, typer.Option(
|
|
1174
|
+
"--project",
|
|
1175
|
+
exists=True, file_okay=False, dir_okay=True, resolve_path=True,
|
|
1176
|
+
help="Project root.")] = Path("."),
|
|
1177
|
+
package: Annotated[str | None, typer.Option(
|
|
1178
|
+
"--package", help="Python package name.")] = None,
|
|
1179
|
+
direction: Annotated[str, typer.Option(
|
|
1180
|
+
"--direction",
|
|
1181
|
+
help="callers | callees | both")] = "both",
|
|
1182
|
+
max_depth: Annotated[int, typer.Option(
|
|
1183
|
+
"--max-depth", help="Maximum traversal depth.")] = 3,
|
|
1184
|
+
json_out: Annotated[bool, typer.Option("--json")] = False,
|
|
1185
|
+
) -> None:
|
|
1186
|
+
"""AST call-graph for a symbol — who calls it, what it calls."""
|
|
1187
|
+
from ..a1_at_functions.call_graph import build_call_graph
|
|
1188
|
+
report = build_call_graph({
|
|
1189
|
+
"qualname": qualname,
|
|
1190
|
+
"project_root": str(project_root),
|
|
1191
|
+
"package": package,
|
|
1192
|
+
"direction": direction,
|
|
1193
|
+
"max_depth": max_depth,
|
|
1194
|
+
})
|
|
1195
|
+
if json_out:
|
|
1196
|
+
typer.echo(json.dumps(report, indent=2, default=str))
|
|
1197
|
+
return
|
|
1198
|
+
typer.echo(f"\nForge call-graph: {qualname}")
|
|
1199
|
+
typer.echo("-" * 60)
|
|
1200
|
+
typer.echo(f" direction: {direction}")
|
|
1201
|
+
typer.echo(f" max_depth: {max_depth}")
|
|
1202
|
+
callers = report.get("callers", [])
|
|
1203
|
+
callees = report.get("callees", [])
|
|
1204
|
+
if callers:
|
|
1205
|
+
typer.echo(f" callers ({len(callers)}):")
|
|
1206
|
+
for c in callers[:20]:
|
|
1207
|
+
typer.echo(f" ← {c}")
|
|
1208
|
+
if callees:
|
|
1209
|
+
typer.echo(f" callees ({len(callees)}):")
|
|
1210
|
+
for c in callees[:20]:
|
|
1211
|
+
typer.echo(f" → {c}")
|
|
1212
|
+
if not callers and not callees:
|
|
1213
|
+
typer.echo(" (no edges found — check that qualname and package are correct)")
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
@app.command("cna-check")
|
|
1217
|
+
def cna_check_cmd(
|
|
1218
|
+
proposed_name: Annotated[str, typer.Argument(
|
|
1219
|
+
help="Symbol name you are about to create.")],
|
|
1220
|
+
project_root: Annotated[Path, typer.Option(
|
|
1221
|
+
"--project",
|
|
1222
|
+
exists=True, file_okay=False, dir_okay=True, resolve_path=True,
|
|
1223
|
+
help="Project root.")] = Path("."),
|
|
1224
|
+
body: Annotated[str | None, typer.Option(
|
|
1225
|
+
"--body", help="Optional short description of the symbol.")] = None,
|
|
1226
|
+
package: Annotated[str | None, typer.Option(
|
|
1227
|
+
"--package", help="Python package sub-directory.")] = None,
|
|
1228
|
+
json_out: Annotated[bool, typer.Option("--json")] = False,
|
|
1229
|
+
) -> None:
|
|
1230
|
+
"""Compose-Not-Add check — verify a symbol doesn't already exist.
|
|
1231
|
+
|
|
1232
|
+
Before writing new code Forge checks whether an equivalent symbol
|
|
1233
|
+
already exists in the project. Exits 1 on REJECT (duplicate found)
|
|
1234
|
+
so this can gate PR pipelines.
|
|
1235
|
+
"""
|
|
1236
|
+
from ..a3_og_features.cna_check import cna_check
|
|
1237
|
+
report = cna_check(project_root=project_root, proposed_name=proposed_name,
|
|
1238
|
+
proposed_body=body, package_subdir=package)
|
|
1239
|
+
if json_out:
|
|
1240
|
+
typer.echo(json.dumps(report.as_dict() if hasattr(report, "as_dict") else report,
|
|
1241
|
+
indent=2, default=str))
|
|
1242
|
+
if hasattr(report, "verdict") and report.verdict == "REJECT":
|
|
1243
|
+
raise typer.Exit(code=1)
|
|
1244
|
+
return
|
|
1245
|
+
d = report.as_dict() if hasattr(report, "as_dict") else report
|
|
1246
|
+
verdict = d.get("verdict", "?")
|
|
1247
|
+
typer.echo(f"\nForge cna-check: {proposed_name}")
|
|
1248
|
+
typer.echo("-" * 60)
|
|
1249
|
+
typer.echo(f" verdict: {verdict}")
|
|
1250
|
+
for match in d.get("top_matches", [])[:5]:
|
|
1251
|
+
score = match.get("score", 0)
|
|
1252
|
+
name = match.get("qualname") or match.get("name", "?")
|
|
1253
|
+
typer.echo(f" {score:.2f} {name}")
|
|
1254
|
+
if verdict == "REJECT":
|
|
1255
|
+
raise typer.Exit(code=1)
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+
@app.command("trust-gate")
|
|
1259
|
+
def trust_gate_cmd(
|
|
1260
|
+
response_file: Annotated[Path | None, typer.Argument(
|
|
1261
|
+
help="File containing the LLM response to gate (omit to read stdin).",
|
|
1262
|
+
exists=False)] = None,
|
|
1263
|
+
known_capabilities: Annotated[str | None, typer.Option(
|
|
1264
|
+
"--capabilities",
|
|
1265
|
+
help="Comma-separated list of capabilities the agent is expected "
|
|
1266
|
+
"to have. Claims outside this set lower the trust score.")] = None,
|
|
1267
|
+
pkg_prefix: Annotated[str, typer.Option(
|
|
1268
|
+
"--pkg-prefix",
|
|
1269
|
+
help="Local package prefix for import-claim validation.")] = "",
|
|
1270
|
+
json_out: Annotated[bool, typer.Option("--json")] = False,
|
|
1271
|
+
) -> None:
|
|
1272
|
+
"""Hallucination detector for LLM responses — τ_TRUST gated output.
|
|
1273
|
+
|
|
1274
|
+
Reads an LLM response (from a file or stdin), scores it against
|
|
1275
|
+
known tool capabilities, and returns a trust verdict with a
|
|
1276
|
+
safe_to_act boolean. Exits 1 when safe_to_act is False.
|
|
1277
|
+
"""
|
|
1278
|
+
from ..a1_at_functions.trust_gate_response import gate_response
|
|
1279
|
+
if response_file is not None:
|
|
1280
|
+
try:
|
|
1281
|
+
text = response_file.read_text(encoding="utf-8")
|
|
1282
|
+
except OSError as exc:
|
|
1283
|
+
raise typer.BadParameter(f"could not read {response_file}: {exc}") from exc
|
|
1284
|
+
else:
|
|
1285
|
+
text = sys.stdin.read()
|
|
1286
|
+
caps = [c.strip() for c in known_capabilities.split(",")] if known_capabilities else None
|
|
1287
|
+
verdict = gate_response(text, known_capabilities=caps, local_pkg_prefix=pkg_prefix)
|
|
1288
|
+
d = verdict.schema if hasattr(verdict, "schema") else {}
|
|
1289
|
+
safe = getattr(verdict, "safe_to_act", d.get("safe_to_act", True))
|
|
1290
|
+
score = getattr(verdict, "score", d.get("score", 1.0))
|
|
1291
|
+
if json_out:
|
|
1292
|
+
typer.echo(json.dumps(d, indent=2, default=str))
|
|
1293
|
+
if not safe:
|
|
1294
|
+
raise typer.Exit(code=1)
|
|
1295
|
+
return
|
|
1296
|
+
typer.echo("\nForge trust-gate")
|
|
1297
|
+
typer.echo("-" * 60)
|
|
1298
|
+
typer.echo(f" score: {score:.3f}")
|
|
1299
|
+
typer.echo(f" safe_to_act: {safe}")
|
|
1300
|
+
for flag in d.get("flags", []):
|
|
1301
|
+
typer.echo(f" ⚠ {flag}")
|
|
1302
|
+
if not safe:
|
|
1303
|
+
raise typer.Exit(code=1)
|
|
1304
|
+
|
|
1305
|
+
|
|
1306
|
+
@app.command("commit-compose")
|
|
1307
|
+
def commit_compose_cmd(
|
|
1308
|
+
intent: Annotated[str, typer.Argument(
|
|
1309
|
+
help="One-line description of what changed and why.")],
|
|
1310
|
+
project_root: Annotated[Path, typer.Option(
|
|
1311
|
+
"--project",
|
|
1312
|
+
exists=True, file_okay=False, dir_okay=True, resolve_path=True,
|
|
1313
|
+
help="Project root.")] = Path("."),
|
|
1314
|
+
commit_type: Annotated[str, typer.Option(
|
|
1315
|
+
"--type",
|
|
1316
|
+
help="ship | fix | refactor | docs | test | chore")] = "ship",
|
|
1317
|
+
body: Annotated[str, typer.Option(
|
|
1318
|
+
"--body", help="Optional extended commit body.")] = "",
|
|
1319
|
+
no_coauthor: Annotated[bool, typer.Option(
|
|
1320
|
+
"--no-coauthor",
|
|
1321
|
+
help="Omit the Co-Authored-By trailer.")] = False,
|
|
1322
|
+
json_out: Annotated[bool, typer.Option("--json")] = False,
|
|
1323
|
+
) -> None:
|
|
1324
|
+
"""Generate a structured, Forge-signed commit message.
|
|
1325
|
+
|
|
1326
|
+
Composes a commit message from intent + type, optionally attaches a
|
|
1327
|
+
Co-Authored-By trailer, and validates the result against the project's
|
|
1328
|
+
wisdom DB. Prints the message ready to paste into ``git commit -m``.
|
|
1329
|
+
"""
|
|
1330
|
+
from ..a3_og_features.commit_compose import compose_commit_message
|
|
1331
|
+
artifact = compose_commit_message(
|
|
1332
|
+
project_root=project_root,
|
|
1333
|
+
intent=intent,
|
|
1334
|
+
commit_type=commit_type,
|
|
1335
|
+
body=body,
|
|
1336
|
+
include_coauthor=not no_coauthor,
|
|
1337
|
+
)
|
|
1338
|
+
d = artifact.as_dict() if hasattr(artifact, "as_dict") else artifact
|
|
1339
|
+
if json_out:
|
|
1340
|
+
typer.echo(json.dumps(d, indent=2, default=str))
|
|
1341
|
+
return
|
|
1342
|
+
message = d.get("message") or d.get("commit_message") or str(d)
|
|
1343
|
+
typer.echo(message)
|
|
1344
|
+
|
|
1345
|
+
|
|
1074
1346
|
@app.command("sbom")
|
|
1075
1347
|
def sbom_cmd(
|
|
1076
1348
|
project: Annotated[Path, typer.Argument(
|
|
@@ -43,6 +43,10 @@ def welcome_cmd(
|
|
|
43
43
|
resolve_path=True)] = None, # type: ignore[assignment]
|
|
44
44
|
skip_certify: Annotated[bool, typer.Option("--skip-certify",
|
|
45
45
|
help="Skip the certify pass for a faster (partial) handshake.")] = False,
|
|
46
|
+
force: Annotated[bool, typer.Option("--force",
|
|
47
|
+
help="Bypass the scope guard (allow walking trees >max-files).")] = False,
|
|
48
|
+
max_files: Annotated[int, typer.Option("--max-files",
|
|
49
|
+
help="Scope guard threshold (default 5000).")] = 5000,
|
|
46
50
|
json_out: Annotated[bool, typer.Option("--json",
|
|
47
51
|
help="Emit machine-readable JSON.")] = False,
|
|
48
52
|
) -> None:
|
|
@@ -52,7 +56,17 @@ def welcome_cmd(
|
|
|
52
56
|
package=package or None,
|
|
53
57
|
since_receipt=since,
|
|
54
58
|
skip_certify=skip_certify,
|
|
59
|
+
force=force,
|
|
60
|
+
max_files=max_files,
|
|
55
61
|
)
|
|
62
|
+
if out.get("verdict") == "REFUSE":
|
|
63
|
+
bar = "=" * 64
|
|
64
|
+
typer.echo(bar, err=True)
|
|
65
|
+
typer.echo(out["narrative"], err=True)
|
|
66
|
+
typer.echo(bar, err=True)
|
|
67
|
+
if json_out:
|
|
68
|
+
typer.echo(json.dumps(out, indent=2, default=str))
|
|
69
|
+
raise typer.Exit(code=2)
|
|
56
70
|
if json_out:
|
|
57
71
|
typer.echo(json.dumps(out, indent=2, default=str))
|
|
58
72
|
return
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atomadic-forge
|
|
3
|
-
Version: 0.16.
|
|
3
|
+
Version: 0.16.2
|
|
4
4
|
Summary: Atomadic Forge — absorb, enforce, emerge. Polyglot (Python · JavaScript/TypeScript · Swift · Kotlin · Go) architecture guardian for AI-generated code.
|
|
5
5
|
Author: Atomadic
|
|
6
6
|
License-Expression: BUSL-1.1
|
|
@@ -74,7 +74,7 @@ stays in the loop.
|
|
|
74
74
|
|
|
75
75
|
### What just shipped (v0.16.0)
|
|
76
76
|
|
|
77
|
-
- **
|
|
77
|
+
- ** hardening — six bugfixes, eleven new tests** (v0.16.0) — live stress-test on three real Python repos (atomadic-forge, langgraph, crewai) ahead of the Boris demo surfaced six bugs across the synthesis, planning, summary, and pipeline-pipe surfaces. `emergent synthesize` no longer emits broken `from pkg.mod.Class import method`; `forge plan` no longer suggests a literal `your_pkg` placeholder; `forge score-patch --file -` honours the stdin sentinel; `forge sbom` text summary reports the real component count; `recon-swarm/emergent-swarm/guard-install` register both hyphen and underscore forms so `commandsmith smoke` is 100% green; `synergy-then-emergent` and `emergent-then-synergy` pipes use the real `--save FILE` flag. Single-seed `forge create` jumped from certify=60/FAIL to **certify=90/100** with importable code on first generation. Test suite 1,291 → 1,302 passed.
|
|
78
78
|
|
|
79
79
|
### What previously shipped (v0.15.0)
|
|
80
80
|
|
|
@@ -253,6 +253,30 @@ def test_welcome_since_receipt_diff(tmp_path: Path) -> None:
|
|
|
253
253
|
assert out["since_last_scan"]["prior_score"] == 80
|
|
254
254
|
|
|
255
255
|
|
|
256
|
+
def test_welcome_scope_guard_refuses_oversized_tree(tmp_path: Path) -> None:
|
|
257
|
+
"""Synthesise 12 .py files, cap at 5, expect REFUSE without scout."""
|
|
258
|
+
for i in range(12):
|
|
259
|
+
(tmp_path / f"mod_{i}.py").write_text("x = 1\n", encoding="utf-8")
|
|
260
|
+
out = welcome(project_root=tmp_path, max_files=5)
|
|
261
|
+
assert out["verdict"] == "REFUSE"
|
|
262
|
+
assert out["reason"] == "scope_guard"
|
|
263
|
+
assert out["scope_guard_max_files"] == 5
|
|
264
|
+
assert out["source_file_count_at_least"] >= 6 # cap+1 trip point
|
|
265
|
+
# Scout/wire/certify keys must not be populated when guard tripped.
|
|
266
|
+
assert "scan" not in out
|
|
267
|
+
assert "Scope guard tripped" in out["narrative"]
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def test_welcome_scope_guard_force_bypasses(tmp_path: Path) -> None:
|
|
271
|
+
"""--force allows the walk even past max-files."""
|
|
272
|
+
for i in range(8):
|
|
273
|
+
(tmp_path / f"mod_{i}.py").write_text("x = 1\n", encoding="utf-8")
|
|
274
|
+
out = welcome(project_root=tmp_path, max_files=3, force=True,
|
|
275
|
+
skip_certify=True)
|
|
276
|
+
assert out.get("verdict") != "REFUSE"
|
|
277
|
+
assert out["scan"]["scout"]["symbol_count"] >= 0 # didn't bail
|
|
278
|
+
|
|
279
|
+
|
|
256
280
|
def test_welcome_since_receipt_missing_returns_none(tmp_path: Path) -> None:
|
|
257
281
|
out = welcome(project_root=tmp_path, skip_certify=True,
|
|
258
282
|
since_receipt=tmp_path / "doesnotexist.json")
|
|
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
|
|
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
|