roam-code 12.38__tar.gz → 12.40__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.
- {roam_code-12.38 → roam_code-12.40}/PKG-INFO +4 -4
- {roam_code-12.38 → roam_code-12.40}/README.md +3 -3
- {roam_code-12.38 → roam_code-12.40}/pyproject.toml +1 -1
- {roam_code-12.38 → roam_code-12.40}/src/roam/cli.py +6 -0
- roam_code-12.40/src/roam/commands/cmd_article_12_check.py +381 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_check_rules.py +2 -2
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_coverage_gaps.py +1 -1
- roam_code-12.40/src/roam/commands/cmd_permit.py +283 -0
- roam_code-12.40/src/roam/commands/cmd_postmortem.py +270 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_report.py +1 -1
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_trends.py +1 -1
- {roam_code-12.38 → roam_code-12.40}/src/roam/competitor_site_data.py +2 -2
- {roam_code-12.38 → roam_code-12.40}/src/roam/mcp-server-card.json +1 -1
- {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/PKG-INFO +4 -4
- {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/SOURCES.txt +4 -0
- roam_code-12.40/tests/test_pivot_phase0_commands.py +134 -0
- {roam_code-12.38 → roam_code-12.40}/LICENSE +0 -0
- {roam_code-12.38 → roam_code-12.40}/setup.cfg +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/__main__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/analysis/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/analysis/effects.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/analysis/taint.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/api.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/ask/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/ask/classifier.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/ask/recipes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/ask/runner.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/ask/workflow.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/attest/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/attest/cga.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/base.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_config.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_django.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_protobuf.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_rest_api.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_salesforce.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_template.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/registry.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/detectors.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/fixes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/python_idioms.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/smells.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/tasks.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/audit_trail_helpers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/changed_files.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_adrs.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_adversarial.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_affected.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_affected_tests.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_agent_context.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_agent_export.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_agent_plan.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ai_ratio.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ai_readiness.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_alerts.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_annotate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_api.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_api_changes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_api_drift.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ask.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_attest.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_audit.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_audit_trail_conformance.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_audit_trail_export.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_audit_trail_verify.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_auth_gaps.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_bisect.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_breaking.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_budget.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_bus_factor.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_capsule.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_cga.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_changelog.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ci_setup.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_clean.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_clones.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_closure.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_clusters.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_codeowners.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_complexity.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_config.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_congestion.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_context.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_conventions.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_coupling.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_critique.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_cut.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_dark_matter.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_dashboard.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_dead.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_debt.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_deps.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_describe.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_dev_profile.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_diagnose.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_diff.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_disambiguate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_doc_staleness.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_docs_coverage.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_doctor.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_dogfood.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_drift.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_duplicates.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_effects.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_endpoints.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_entry_points.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_eval_retrieve.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_exit_codes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_fan.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_file.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_fingerprint.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_fitness.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_flag_dead.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_fleet.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_fn_coupling.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_forecast.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_graph_export.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_graph_stats.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_grep.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_guard.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_health.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_help_search.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_hooks.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_hotspots.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_hover.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_impact.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_index.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_index_bundle.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_index_stats.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ingest_trace.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_init.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_intent.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_invariants.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_layers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_map.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_math.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_mcp_setup.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_mcp_status.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_metrics.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_metrics_push.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_migration_safety.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_minimap.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_missing_index.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_module.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_mutate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_n1.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_oracle.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_orchestrate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_orphan_imports.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_orphan_routes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_over_fetch.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_owner.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_partition.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_path_coverage.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_patterns.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_plan.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_plan_refactor.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_plugins.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pr_analyze.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pr_comment_render.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pr_diff.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pr_prep.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pr_risk.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pre_commit.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_preflight.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_py_modern.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_py_types.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pytest_fixtures.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_recipes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_recommend.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_relate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_reset.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_retrieve.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_risk.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_rules.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_rules_validate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_safe_delete.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_safe_zones.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_sbom.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_schema.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_search.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_search_semantic.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_secrets.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_semantic_diff.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_simulate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_simulate_departure.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_sketch.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_smells.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_spectral.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_split.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_stats.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_suggest_refactoring.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_suggest_reviewers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_supply_chain.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_suppress.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_symbol.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_syntax_check.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_taint.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_telemetry.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_test_gaps.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_test_impact.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_test_pyramid.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_test_scaffold.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_testmap.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_timeline.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_tour.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_trace.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_triage.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_understand.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_uses.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_verify.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_verify_imports.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_version.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_vibe_check.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_visualize.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_vuln_map.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_vuln_reach.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_vulns.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_watch.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_weather.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_why.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_why_fail.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_workflow.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ws.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_xlang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/codeowners_helpers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/context_helpers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/finding_suppress.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/gate_presets.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/git_helpers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/graph_helpers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/metrics_history.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/next_steps.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/pr_analyze/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/pr_analyze/audit_trail.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/pr_analyze/cache.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/pr_analyze/rules.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/resolve.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/commands/suppression.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/config.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/coverage_reports.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/critique/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/critique/aggregator.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/critique/checks.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/db/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/db/connection.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/db/queries.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/db/schema.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/eval/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/eval/harness.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/exit_codes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/fleet/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/fleet/adapters.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/fleet/manifest.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/git_utils.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/anomaly.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/builder.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/clone_detect.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/clusters.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/cycles.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/dark_matter.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/diff.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/fingerprint.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/layers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/pagerank.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/partition.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/pathfinding.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/propagation.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/simulate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/spectral.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/graph/stats.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/complexity.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/discovery.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/django_post.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/file_roles.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/git_stats.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/gitignore.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/incremental.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/indexer.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/parser.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/pytest_fixtures.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/registry_dispatch.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/relations.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/symbols.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/index/test_conventions.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/apex_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/aura_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/base.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/c_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/csharp_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/extractor_schema.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/extractors/kotlin.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/foxpro_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/generic_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/go_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/hcl_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/java_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/javascript_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/kotlin_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/php_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/python_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/query_engine.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/registry.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/ruby_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/rust_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/scala_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/sfxml_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/sql_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/swift_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/typescript_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/visualforce_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/languages/yaml_lang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/completions.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/concurrency.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/progress.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/sampling.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/session.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/watcher.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_server.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/observability.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/output/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/output/confidence.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/output/errors.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/output/file_role_hints.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/output/formatter.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/output/framework_filter.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/output/mermaid.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/output/project_shape.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/output/sarif.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/output/schema_registry.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/plugins.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/refactor/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/refactor/codegen.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/refactor/transforms.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/learned_ranker.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/pipeline.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/rerank.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/seeds.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/semantic.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/rules/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/rules/ast_match.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/rules/builtin.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/rules/dataflow.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/rules/engine.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/daemon.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/graph_backend.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/hotspots.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/lock_modes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/lockmgr.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/trace_ingest.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/search/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/search/framework_packs.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/search/index_embeddings.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/search/onnx_embeddings.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/search/tfidf.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/aibom_extension.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_classifier.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_engine.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/api_error_leak.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/java_fileupload_path_traversal.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/js_insecure_jwt_decode.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/js_localstorage_secrets.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/js_prototype_pollution.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/js_ssrf.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/js_xss.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_basic.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_deserialization.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_path_traversal.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_socketio_remote_source.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_sqli.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_urllib_open_redirect.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/vue_v_html.yaml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/vuln_reach.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/security/vuln_store.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/surface_counts.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/telemetry.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/templates/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/Jenkinsfile +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/agent-review.yml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/azure-pipelines.yml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/bitbucket-pipelines.yml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/gitlab-ci.yml +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/workspace/__init__.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/workspace/aggregator.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/workspace/api_scanner.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/workspace/config.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam/workspace/db.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/dependency_links.txt +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/entry_points.txt +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/requires.txt +0 -0
- {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/top_level.txt +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_adrs.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_adversarial.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_affected.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_agent_export.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_agent_mode.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_agent_plan_context.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_ai_ratio.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_ai_readiness.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_alerts_cmd.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_annotations.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_anomaly.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_api_changes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_api_drift.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_ask.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_attest.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_audit_trail_aggregate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_audit_trail_conformance.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_audit_trail_sequence.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_audit_trail_verify.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_auth_gaps.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_backend_fixes_round2.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_backend_fixes_round3.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_basic.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_batch_mcp.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_bisect.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_bridge_django.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_bridges.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_bridges_extended.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_budget.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_budget_flag.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_budget_phase2.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_bus_factor.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_capsule.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_cga.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_check_rules.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_ci_gate_eval.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_ci_sarif_guard.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_ci_setup.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_clones.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_closure.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_codeowners.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_commands_architecture.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_commands_exploration.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_commands_health.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_commands_refactoring.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_commands_workflow.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_competitor_site_data.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_comprehensive.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_config.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_congestion.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_context_propagation.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_conventions_cmd.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_coverage_gaps_cmd.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_coverage_ingestion.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_critique.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_cut.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_dark_matter.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_dark_matter_helpers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_dashboard.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_dataflow_dead.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_dead_aging.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_defer_loading.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_demo_gif_asset.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_describe.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_detail_flag_hints.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_detector_precision.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_deterministic_output.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_dev_profile.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_difficulty_scoring.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_doc_consistency.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_doc_staleness.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_docker_assets.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_docs_coverage.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_docs_site_quality.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_doctor.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_dogfood.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_drift.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_drift_by_team.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_duplicates.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_effects.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_effects_propagation.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_endpoints.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_entry_points_cmd.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_eval_retrieve.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_except_pass_narrow.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_exclude_patterns.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_exit_codes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_extractor_grammar_drift.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_fallback_contracts.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_file_roles.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_finding_suppress.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_fingerprint.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_fixes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_flag_dead.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_fleet.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_fn_coupling.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_forecast.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_formatters.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_foxpro.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_framework_detection.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_gate_presets.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_git_helpers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_git_utils.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_guard.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_health_gate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_hooks.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_hotspots.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_hover.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_index.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_index_bundle.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_init_cmd.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_install_check.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_intent.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_invariants.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_json_contracts.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_json_error_envelope.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_kotlin_swift_extractors.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_language_corpus.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_languages.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_laravel_fp_fixes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_library_api.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_math.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_math_fp_fixes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_math_tips.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_mcp_extras.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_mcp_server.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_mcp_setup.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_mermaid.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_metrics_cmd.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_metrics_push.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_migration_safety.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_minimap.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_missing_index.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_mutate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_n1.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_next_steps.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_onboard.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_oracle.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_orchestrate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_orphan_routes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_oss_bench_harness.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_over_fetch.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_pagerank_truncation.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_partition.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_path_coverage.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_patterns_cmd.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_performance.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_personalized_pagerank.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_plan.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_plugin_discovery.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_pr_analyze.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_pr_analyze_cache.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_pr_analyze_edge_cases.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_pr_analyze_helpers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_pr_analyze_v2_signals.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_pr_comment_render.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_pr_comment_script.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_pr_diff.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_pr_risk_author.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_progress.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_progressive_disclosure.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_properties.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_pytest_fixtures.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_python_extractor_v2.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_python_idioms_e2e.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_python_pivot.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_readme_surface_consistency.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_realworld_feedback.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_refactoring_intelligence.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_registry_dispatch.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_regression_fp_corpus.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_relate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_report.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_reset_clean.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_resolve.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_retrieve.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_retrieve_cross_repo.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_retrieve_seeds.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_risk.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_ruby.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_rule_profiles.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_rules.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_rules_ast_match.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_rules_community_pack.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_rules_dataflow.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_rules_symbol_requirements.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_rules_validate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_runtime.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_runtime_score.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_salesforce.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_sarif_flag.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_sbom.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_scala.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_schema_versioning.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_search_explain.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_secrets.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_secrets_v2.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_semantic_diff.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_semantic_onnx.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_semantic_search.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_simulate.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_simulate_departure.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_sketch.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_smells.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_smoke.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_sna_metrics.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_spectral.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_split_cmd.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_sql.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_suggest_reviewers.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_supply_chain.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_surface_counts.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_syntax_check.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_taint.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_taint_analysis.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_taint_classifier.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_taint_intraprocedural.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_test_conventions.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_test_gaps.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_test_scaffold.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_testmap.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_top_flag_consistency.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_tour_cmd.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_trends.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_trends_cohort.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_triage.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_uses_cmd.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v1215_passes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v1216_passes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v1216_passes_41_50.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v1216_passes_51_60.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v1217_passes_61_80.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v1218_passes_81_90.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v1219_passes_91_100.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v1220_passes_101_110.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v1221_query_timeout.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v1221_untested_commands.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v12_2.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v2_edge_cases.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v2_integration.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v6_features.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v71_features.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v7_features.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_v82_features.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_verify.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_verify_imports.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_vibe_check.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_visualize.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_vuln.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_vulns_cmd.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_watch.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_why.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_workspace.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_ws_resolve_fixes.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_xlang.py +0 -0
- {roam_code-12.38 → roam_code-12.40}/tests/test_yaml_hcl.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: roam-code
|
|
3
|
-
Version: 12.
|
|
3
|
+
Version: 12.40
|
|
4
4
|
Summary: Instant codebase comprehension for AI coding agents
|
|
5
5
|
Author: CosmoHac
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -64,9 +64,9 @@ Dynamic: license-file
|
|
|
64
64
|
|
|
65
65
|
**Architectural sight for AI coding agents — before they edit.**
|
|
66
66
|
|
|
67
|
-
A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other
|
|
67
|
+
A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other 185 specialised commands are advanced surface for specialised workflows.
|
|
68
68
|
|
|
69
|
-
*
|
|
69
|
+
*190 commands · 136 MCP tools · 27 languages · 100% local · zero API keys*
|
|
70
70
|
|
|
71
71
|
[](https://pypi.org/project/roam-code/)
|
|
72
72
|
[](https://github.com/Cranot/roam-code/stargazers)
|
|
@@ -334,7 +334,7 @@ roam health
|
|
|
334
334
|
|
|
335
335
|
## Commands
|
|
336
336
|
|
|
337
|
-
**Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining
|
|
337
|
+
**Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 185 commands are detail surface for specialised workflows (taint, fleet, cga, oracle, eval, …) — they're called by agents on demand, not memorised. This is intentional design; under the hood the canonical surface is **190 commands organised into 7 categories** (plus 6 aliases for muscle memory: `algo` → `math`, `weather` → `churn`, `digest` / `snapshot` / `trend` → `trends`, `onboard` → `understand`), but you don't need to know that to start.
|
|
338
338
|
|
|
339
339
|
<details>
|
|
340
340
|
<summary><strong>Full command reference</strong></summary>
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
**Architectural sight for AI coding agents — before they edit.**
|
|
6
6
|
|
|
7
|
-
A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other
|
|
7
|
+
A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other 185 specialised commands are advanced surface for specialised workflows.
|
|
8
8
|
|
|
9
|
-
*
|
|
9
|
+
*190 commands · 136 MCP tools · 27 languages · 100% local · zero API keys*
|
|
10
10
|
|
|
11
11
|
[](https://pypi.org/project/roam-code/)
|
|
12
12
|
[](https://github.com/Cranot/roam-code/stargazers)
|
|
@@ -274,7 +274,7 @@ roam health
|
|
|
274
274
|
|
|
275
275
|
## Commands
|
|
276
276
|
|
|
277
|
-
**Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining
|
|
277
|
+
**Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 185 commands are detail surface for specialised workflows (taint, fleet, cga, oracle, eval, …) — they're called by agents on demand, not memorised. This is intentional design; under the hood the canonical surface is **190 commands organised into 7 categories** (plus 6 aliases for muscle memory: `algo` → `math`, `weather` → `churn`, `digest` / `snapshot` / `trend` → `trends`, `onboard` → `understand`), but you don't need to know that to start.
|
|
278
278
|
|
|
279
279
|
<details>
|
|
280
280
|
<summary><strong>Full command reference</strong></summary>
|
|
@@ -83,6 +83,9 @@ _COMMANDS = {
|
|
|
83
83
|
"fitness": ("roam.commands.cmd_fitness", "fitness"),
|
|
84
84
|
"patterns": ("roam.commands.cmd_patterns", "patterns"),
|
|
85
85
|
"preflight": ("roam.commands.cmd_preflight", "preflight"),
|
|
86
|
+
"permit": ("roam.commands.cmd_permit", "permit_cmd"),
|
|
87
|
+
"postmortem": ("roam.commands.cmd_postmortem", "postmortem_cmd"),
|
|
88
|
+
"article-12-check": ("roam.commands.cmd_article_12_check", "article_12_check_cmd"),
|
|
86
89
|
"guard": ("roam.commands.cmd_guard", "guard"),
|
|
87
90
|
"init": ("roam.commands.cmd_init", "init"),
|
|
88
91
|
"config": ("roam.commands.cmd_config", "config"),
|
|
@@ -272,6 +275,8 @@ _CATEGORIES = {
|
|
|
272
275
|
],
|
|
273
276
|
"Daily Workflow": [
|
|
274
277
|
"preflight",
|
|
278
|
+
"permit",
|
|
279
|
+
"postmortem",
|
|
275
280
|
"guard",
|
|
276
281
|
"agent-plan",
|
|
277
282
|
"agent-context",
|
|
@@ -284,6 +289,7 @@ _CATEGORIES = {
|
|
|
284
289
|
"audit-trail-verify",
|
|
285
290
|
"audit-trail-export",
|
|
286
291
|
"audit-trail-conformance-check",
|
|
292
|
+
"article-12-check",
|
|
287
293
|
"dogfood",
|
|
288
294
|
"suppress",
|
|
289
295
|
"pr-diff",
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
"""``roam article-12-check`` — EU AI Act Article 12 readiness assessment.
|
|
2
|
+
|
|
3
|
+
EU AI Act Article 12 takes effect August 2, 2026, and requires high-risk
|
|
4
|
+
AI systems to "technically allow for the automatic recording of events
|
|
5
|
+
(logs) over the lifetime of the system." Penalty for non-compliance: up
|
|
6
|
+
to €15M or 3% of global turnover.
|
|
7
|
+
|
|
8
|
+
Most coding tools are NOT classified as high-risk under Annex III, BUT
|
|
9
|
+
they BECOME high-risk if their telemetry feeds into HR / promotion /
|
|
10
|
+
retention decisions. The non-applicability assessment itself is a
|
|
11
|
+
deliverable that DPOs and compliance officers need to file.
|
|
12
|
+
|
|
13
|
+
This command runs a checklist over the indexed repo and emits a
|
|
14
|
+
1-page assessment report (Markdown by default; ``--pdf`` if reportlab
|
|
15
|
+
is installed). Each item references the specific Article (12, 18, 19)
|
|
16
|
+
or Annex (III) it maps to.
|
|
17
|
+
|
|
18
|
+
Phase 0.4 of the v2 monetization plan: stand-alone OSS funnel artifact
|
|
19
|
+
that captures Article-12-curious leads before they pick another
|
|
20
|
+
vendor. The pull quote is:
|
|
21
|
+
|
|
22
|
+
"becomes the vendor my DPO calls when Article 12 does apply."
|
|
23
|
+
|
|
24
|
+
Usage:
|
|
25
|
+
|
|
26
|
+
roam article-12-check # markdown to stdout
|
|
27
|
+
roam article-12-check --output report.md # write markdown
|
|
28
|
+
roam article-12-check --pdf out.pdf # write PDF (needs reportlab)
|
|
29
|
+
roam --json article-12-check # structured envelope
|
|
30
|
+
|
|
31
|
+
The assessment is deliberately conservative: items that don't apply
|
|
32
|
+
to a typical codebase get a "N/A — not classified as high-risk" tag
|
|
33
|
+
instead of a "FAIL" so the readiness report doesn't false-alarm
|
|
34
|
+
compliance teams.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
from __future__ import annotations
|
|
38
|
+
|
|
39
|
+
import re
|
|
40
|
+
from datetime import datetime, timezone
|
|
41
|
+
from pathlib import Path
|
|
42
|
+
|
|
43
|
+
import click
|
|
44
|
+
|
|
45
|
+
from roam.commands.git_helpers import git_origin_url
|
|
46
|
+
from roam.commands.resolve import ensure_index
|
|
47
|
+
from roam.exit_codes import EXIT_SUCCESS
|
|
48
|
+
from roam.output.formatter import json_envelope, to_json
|
|
49
|
+
|
|
50
|
+
# ---------------------------------------------------------------------------
|
|
51
|
+
# Checklist items — each mapped to an Article / Annex
|
|
52
|
+
# ---------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _check_logs_directory_exists(project_root: Path) -> dict:
|
|
56
|
+
"""Item 1 — Article 12: events must be recorded automatically."""
|
|
57
|
+
candidates = [".roam", ".roam/audit-trail", "logs", ".github/audit"]
|
|
58
|
+
found = [c for c in candidates if (project_root / c).exists()]
|
|
59
|
+
return {
|
|
60
|
+
"item": "Audit trail directory exists",
|
|
61
|
+
"article": "12 (event logging)",
|
|
62
|
+
"passed": bool(found),
|
|
63
|
+
"evidence": f"found: {', '.join(found)}" if found else "no .roam/ or logs/ directory found",
|
|
64
|
+
"fix": "Run `roam audit-trail-export` to bootstrap an audit trail under .roam/audit-trail.jsonl",
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _check_audit_trail_has_records(project_root: Path) -> dict:
|
|
69
|
+
"""Item 2 — Article 12: trail must accumulate over the lifetime of the system."""
|
|
70
|
+
trail_path = project_root / ".roam" / "audit-trail.jsonl"
|
|
71
|
+
record_count = 0
|
|
72
|
+
if trail_path.exists():
|
|
73
|
+
try:
|
|
74
|
+
record_count = sum(1 for line in trail_path.open(encoding="utf-8") if line.strip())
|
|
75
|
+
except OSError:
|
|
76
|
+
record_count = 0
|
|
77
|
+
return {
|
|
78
|
+
"item": "Audit trail has at least 1 record",
|
|
79
|
+
"article": "12 (event logging)",
|
|
80
|
+
"passed": record_count > 0,
|
|
81
|
+
"evidence": f"{record_count} record(s) in {trail_path}"
|
|
82
|
+
if record_count
|
|
83
|
+
else "audit-trail.jsonl missing or empty",
|
|
84
|
+
"fix": "Pipe `roam pr-analyze --emit-audit-record` (default) on every PR; first record bootstraps the chain",
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _check_retention_documented(project_root: Path) -> dict:
|
|
89
|
+
"""Item 3 — Article 19: minimum 6-month log retention by deployers."""
|
|
90
|
+
candidates = [
|
|
91
|
+
"docs/retention.md",
|
|
92
|
+
"docs/audit-retention.md",
|
|
93
|
+
"RETENTION.md",
|
|
94
|
+
".roam/retention.yaml",
|
|
95
|
+
"AGENTS.md",
|
|
96
|
+
"CLAUDE.md",
|
|
97
|
+
]
|
|
98
|
+
keywords = ("retention", "6 month", "180 day", "Article 19")
|
|
99
|
+
matches = []
|
|
100
|
+
for c in candidates:
|
|
101
|
+
p = project_root / c
|
|
102
|
+
if not p.exists():
|
|
103
|
+
continue
|
|
104
|
+
try:
|
|
105
|
+
text = p.read_text(encoding="utf-8", errors="replace").lower()
|
|
106
|
+
except OSError:
|
|
107
|
+
continue
|
|
108
|
+
if any(k in text for k in keywords):
|
|
109
|
+
matches.append(c)
|
|
110
|
+
return {
|
|
111
|
+
"item": "Log-retention policy documented (≥6 months per Article 19)",
|
|
112
|
+
"article": "19 (deployer obligations)",
|
|
113
|
+
"passed": bool(matches),
|
|
114
|
+
"evidence": f"keyword found in: {', '.join(matches)}"
|
|
115
|
+
if matches
|
|
116
|
+
else "no retention keyword in standard locations",
|
|
117
|
+
"fix": "Add a `## Retention` section to AGENTS.md or docs/retention.md stating 6-month minimum",
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _check_technical_documentation(project_root: Path) -> dict:
|
|
122
|
+
"""Item 4 — Article 18: technical documentation retained 10 years."""
|
|
123
|
+
candidates = ["README.md", "ARCHITECTURE.md", "docs/", "AGENTS.md", "CLAUDE.md"]
|
|
124
|
+
found = [c for c in candidates if (project_root / c).exists()]
|
|
125
|
+
return {
|
|
126
|
+
"item": "Technical documentation present (Article 18: 10-year retention)",
|
|
127
|
+
"article": "18 (provider obligations)",
|
|
128
|
+
"passed": len(found) >= 2,
|
|
129
|
+
"evidence": f"found: {', '.join(found)}",
|
|
130
|
+
"fix": "Add ARCHITECTURE.md or expand AGENTS.md with system overview, data flows, and contacts",
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _check_attestation_artifacts(project_root: Path) -> dict:
|
|
135
|
+
"""Item 5 — bonus: in-toto / sigstore attestations for AI-generated changes."""
|
|
136
|
+
candidates = [".roam/attestations", ".roam/cga", "attestations/"]
|
|
137
|
+
found = [c for c in candidates if (project_root / c).exists()]
|
|
138
|
+
return {
|
|
139
|
+
"item": "Cryptographic attestation surface exists (in-toto / sigstore)",
|
|
140
|
+
"article": "12 (event integrity)",
|
|
141
|
+
"passed": bool(found),
|
|
142
|
+
"evidence": f"found: {', '.join(found)}" if found else "no attestation artifacts",
|
|
143
|
+
"fix": "Run `roam attest cga --sign` to bootstrap signed CodeGraph attestations",
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _classify_high_risk_likelihood(project_root: Path) -> dict:
|
|
148
|
+
"""Item 6 — heuristic: does the codebase look like an AI-tool that influences HR decisions?"""
|
|
149
|
+
risk_keywords = re.compile(
|
|
150
|
+
r"\b(?:promotion|retention|hr_decision|performance_review|workforce|hiring|firing|"
|
|
151
|
+
r"employee_score|developer_rating|promote|demote|terminate)\b",
|
|
152
|
+
re.IGNORECASE,
|
|
153
|
+
)
|
|
154
|
+
hits = 0
|
|
155
|
+
sample = 0
|
|
156
|
+
for path in project_root.rglob("*.py"):
|
|
157
|
+
if "test" in str(path).lower():
|
|
158
|
+
continue
|
|
159
|
+
try:
|
|
160
|
+
text = path.read_text(encoding="utf-8", errors="replace")
|
|
161
|
+
except OSError:
|
|
162
|
+
continue
|
|
163
|
+
sample += 1
|
|
164
|
+
if risk_keywords.search(text):
|
|
165
|
+
hits += 1
|
|
166
|
+
if sample > 200:
|
|
167
|
+
break
|
|
168
|
+
is_high_risk = hits > 0
|
|
169
|
+
return {
|
|
170
|
+
"item": "High-risk classification likelihood (Annex III)",
|
|
171
|
+
"article": "Annex III (high-risk system definitions)",
|
|
172
|
+
"passed": not is_high_risk,
|
|
173
|
+
"evidence": (
|
|
174
|
+
f"NOT high-risk — no HR/employment keywords matched across {sample} files scanned"
|
|
175
|
+
if not is_high_risk
|
|
176
|
+
else f"REVIEW — {hits} file(s) reference HR/employment workflows; consult counsel"
|
|
177
|
+
),
|
|
178
|
+
"fix": (
|
|
179
|
+
"Document the non-applicability in compliance/eu-ai-act-assessment.md"
|
|
180
|
+
if not is_high_risk
|
|
181
|
+
else "Engage DPO immediately; this codebase MAY be high-risk under Annex III"
|
|
182
|
+
),
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
_CHECKS = [
|
|
187
|
+
_check_logs_directory_exists,
|
|
188
|
+
_check_audit_trail_has_records,
|
|
189
|
+
_check_retention_documented,
|
|
190
|
+
_check_technical_documentation,
|
|
191
|
+
_check_attestation_artifacts,
|
|
192
|
+
_classify_high_risk_likelihood,
|
|
193
|
+
]
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
# ---------------------------------------------------------------------------
|
|
197
|
+
# Report rendering
|
|
198
|
+
# ---------------------------------------------------------------------------
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _render_markdown_report(results: list[dict], project_root: Path) -> str:
|
|
202
|
+
passed = sum(1 for r in results if r["passed"])
|
|
203
|
+
total = len(results)
|
|
204
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
|
|
205
|
+
repo = git_origin_url() or str(project_root)
|
|
206
|
+
lines: list[str] = [
|
|
207
|
+
"# EU AI Act — Article 12 Readiness Assessment",
|
|
208
|
+
"",
|
|
209
|
+
f"**Generated**: {timestamp}",
|
|
210
|
+
f"**Repository**: {repo}",
|
|
211
|
+
f"**Score**: {passed} / {total} items passing",
|
|
212
|
+
"",
|
|
213
|
+
"## Background",
|
|
214
|
+
"",
|
|
215
|
+
"EU AI Act Article 12 takes effect **August 2, 2026** for high-risk AI",
|
|
216
|
+
"systems (Annex III). It requires automatic event logging built into",
|
|
217
|
+
"the system. Penalties for non-compliance: **€15M or 3% of global",
|
|
218
|
+
"annual turnover**, whichever is higher. Article 19 requires deployers",
|
|
219
|
+
"to retain logs for at least 6 months. Article 18 requires providers",
|
|
220
|
+
"to retain technical documentation for 10 years.",
|
|
221
|
+
"",
|
|
222
|
+
"Most coding tools are NOT classified as high-risk under Annex III.",
|
|
223
|
+
"However, they BECOME high-risk if telemetry feeds into HR /",
|
|
224
|
+
"promotion / retention decisions. **Even the non-applicability",
|
|
225
|
+
"assessment is a deliverable** that DPOs need on file.",
|
|
226
|
+
"",
|
|
227
|
+
"## Checklist",
|
|
228
|
+
"",
|
|
229
|
+
]
|
|
230
|
+
for r in results:
|
|
231
|
+
mark = "✅ PASS" if r["passed"] else "⚠️ REVIEW"
|
|
232
|
+
lines.append(f"### {mark} — {r['item']}")
|
|
233
|
+
lines.append(f"_Article {r['article']}_")
|
|
234
|
+
lines.append("")
|
|
235
|
+
lines.append(f"**Evidence**: {r['evidence']}")
|
|
236
|
+
lines.append("")
|
|
237
|
+
if not r["passed"]:
|
|
238
|
+
lines.append(f"**Fix**: {r['fix']}")
|
|
239
|
+
lines.append("")
|
|
240
|
+
lines.append("")
|
|
241
|
+
|
|
242
|
+
lines.extend(
|
|
243
|
+
[
|
|
244
|
+
"---",
|
|
245
|
+
"",
|
|
246
|
+
"## Next steps",
|
|
247
|
+
"",
|
|
248
|
+
"1. Address any ⚠️ REVIEW items above.",
|
|
249
|
+
"2. If you suspect this codebase IS high-risk under Annex III,",
|
|
250
|
+
" consult counsel and your DPO immediately.",
|
|
251
|
+
"3. Run `roam audit-trail-export --since 2025-01-01` to capture",
|
|
252
|
+
" historical PR-analyze records into the chain.",
|
|
253
|
+
"4. Run `roam audit-trail-conformance-check` for a deeper",
|
|
254
|
+
" per-record audit.",
|
|
255
|
+
"",
|
|
256
|
+
"## Disclaimer",
|
|
257
|
+
"",
|
|
258
|
+
"This report is a tool-level readiness assessment generated by",
|
|
259
|
+
"`roam article-12-check`. It is NOT legal advice and does NOT",
|
|
260
|
+
"constitute a conformity assessment under the EU AI Act. For a",
|
|
261
|
+
"binding determination, consult qualified counsel and a notified",
|
|
262
|
+
"body where required.",
|
|
263
|
+
"",
|
|
264
|
+
"_Powered by [roam-code](https://github.com/Cranot/roam-code) — Apache 2.0_",
|
|
265
|
+
"",
|
|
266
|
+
]
|
|
267
|
+
)
|
|
268
|
+
return "\n".join(lines)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def _render_pdf_report(markdown_text: str, output_path: Path) -> bool:
|
|
272
|
+
"""Best-effort PDF emission via reportlab (optional)."""
|
|
273
|
+
try:
|
|
274
|
+
from reportlab.lib.pagesizes import A4
|
|
275
|
+
from reportlab.lib.styles import getSampleStyleSheet
|
|
276
|
+
from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer
|
|
277
|
+
except ImportError:
|
|
278
|
+
return False
|
|
279
|
+
doc = SimpleDocTemplate(str(output_path), pagesize=A4)
|
|
280
|
+
styles = getSampleStyleSheet()
|
|
281
|
+
flowables = []
|
|
282
|
+
for line in markdown_text.split("\n"):
|
|
283
|
+
if not line.strip():
|
|
284
|
+
flowables.append(Spacer(1, 6))
|
|
285
|
+
continue
|
|
286
|
+
if line.startswith("# "):
|
|
287
|
+
flowables.append(Paragraph(line[2:], styles["Heading1"]))
|
|
288
|
+
elif line.startswith("## "):
|
|
289
|
+
flowables.append(Paragraph(line[3:], styles["Heading2"]))
|
|
290
|
+
elif line.startswith("### "):
|
|
291
|
+
flowables.append(Paragraph(line[4:], styles["Heading3"]))
|
|
292
|
+
else:
|
|
293
|
+
flowables.append(Paragraph(line, styles["BodyText"]))
|
|
294
|
+
doc.build(flowables)
|
|
295
|
+
return True
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
@click.command(name="article-12-check")
|
|
299
|
+
@click.option(
|
|
300
|
+
"--output",
|
|
301
|
+
"output_path",
|
|
302
|
+
type=click.Path(),
|
|
303
|
+
default=None,
|
|
304
|
+
help="Write the markdown report to PATH (default: stdout).",
|
|
305
|
+
)
|
|
306
|
+
@click.option(
|
|
307
|
+
"--pdf",
|
|
308
|
+
"pdf_path",
|
|
309
|
+
type=click.Path(),
|
|
310
|
+
default=None,
|
|
311
|
+
help="Also write a PDF to PATH (requires reportlab; pip install reportlab).",
|
|
312
|
+
)
|
|
313
|
+
@click.pass_context
|
|
314
|
+
def article_12_check_cmd(ctx, output_path: str | None, pdf_path: str | None):
|
|
315
|
+
"""EU AI Act Article 12 readiness assessment for the indexed repo.
|
|
316
|
+
|
|
317
|
+
Runs a 6-item checklist (audit trail, retention policy, technical
|
|
318
|
+
docs, attestation surface, high-risk classification heuristic) and
|
|
319
|
+
emits a 1-page markdown report. Optional PDF via reportlab.
|
|
320
|
+
|
|
321
|
+
\b
|
|
322
|
+
Examples:
|
|
323
|
+
roam article-12-check # markdown to stdout
|
|
324
|
+
roam article-12-check --output report.md
|
|
325
|
+
roam article-12-check --pdf assessment.pdf
|
|
326
|
+
roam --json article-12-check > envelope.json
|
|
327
|
+
|
|
328
|
+
Phase 0.4 of the v2 monetization plan — captures Article-12-curious
|
|
329
|
+
leads before they pick another vendor.
|
|
330
|
+
"""
|
|
331
|
+
json_mode = ctx.obj.get("json") if ctx.obj else False
|
|
332
|
+
ensure_index()
|
|
333
|
+
|
|
334
|
+
project_root = Path.cwd()
|
|
335
|
+
results = [check(project_root) for check in _CHECKS]
|
|
336
|
+
passed = sum(1 for r in results if r["passed"])
|
|
337
|
+
total = len(results)
|
|
338
|
+
|
|
339
|
+
markdown_text = _render_markdown_report(results, project_root)
|
|
340
|
+
|
|
341
|
+
if output_path:
|
|
342
|
+
Path(output_path).write_text(markdown_text, encoding="utf-8")
|
|
343
|
+
|
|
344
|
+
pdf_written = False
|
|
345
|
+
if pdf_path:
|
|
346
|
+
pdf_written = _render_pdf_report(markdown_text, Path(pdf_path))
|
|
347
|
+
|
|
348
|
+
if json_mode:
|
|
349
|
+
click.echo(
|
|
350
|
+
to_json(
|
|
351
|
+
json_envelope(
|
|
352
|
+
"article-12-check",
|
|
353
|
+
summary={
|
|
354
|
+
"verdict": f"{passed}/{total} items passing",
|
|
355
|
+
"passed": passed,
|
|
356
|
+
"total": total,
|
|
357
|
+
"high_risk_classification": next(
|
|
358
|
+
(r["evidence"] for r in results if "high-risk" in r["item"].lower()),
|
|
359
|
+
"unknown",
|
|
360
|
+
),
|
|
361
|
+
"output_path": output_path,
|
|
362
|
+
"pdf_path": pdf_path if pdf_written else None,
|
|
363
|
+
"pdf_skipped_reason": ("reportlab not installed" if (pdf_path and not pdf_written) else None),
|
|
364
|
+
},
|
|
365
|
+
items=results,
|
|
366
|
+
)
|
|
367
|
+
)
|
|
368
|
+
)
|
|
369
|
+
ctx.exit(EXIT_SUCCESS)
|
|
370
|
+
return
|
|
371
|
+
|
|
372
|
+
if output_path:
|
|
373
|
+
click.echo(f"VERDICT: {passed}/{total} items passing — written to {output_path}")
|
|
374
|
+
if pdf_path and pdf_written:
|
|
375
|
+
click.echo(f" PDF: {pdf_path}")
|
|
376
|
+
elif pdf_path and not pdf_written:
|
|
377
|
+
click.echo(" PDF skipped: reportlab not installed (pip install reportlab)", err=True)
|
|
378
|
+
else:
|
|
379
|
+
click.echo(markdown_text)
|
|
380
|
+
|
|
381
|
+
ctx.exit(EXIT_SUCCESS)
|
|
@@ -429,8 +429,8 @@ def check_rules(ctx, rule_filter, severity_filter, config_path, profile_name, do
|
|
|
429
429
|
try:
|
|
430
430
|
profile_overrides = resolve_profile(effective_profile)
|
|
431
431
|
except ValueError as e:
|
|
432
|
-
click.echo("Error: {}"
|
|
433
|
-
raise SystemExit(1)
|
|
432
|
+
click.echo(f"Error: {e}")
|
|
433
|
+
raise SystemExit(1) from None
|
|
434
434
|
# Profile overrides are the base; user overrides (from rules: section) layer on top
|
|
435
435
|
merged = {ov.get("id"): ov for ov in profile_overrides}
|
|
436
436
|
for ov in user_overrides:
|