anima-cli 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- anima_cli-0.1.0/.agents/commands/audit.md +146 -0
- anima_cli-0.1.0/.agents/commands/guard.md +83 -0
- anima_cli-0.1.0/.agents/instructions.md +103 -0
- anima_cli-0.1.0/.agents/mcp.json +9 -0
- anima_cli-0.1.0/.github/workflows/publish.yml +28 -0
- anima_cli-0.1.0/.github/workflows/waterline-gate.yml +34 -0
- anima_cli-0.1.0/.gitignore +67 -0
- anima_cli-0.1.0/.pre-commit-config.yaml +29 -0
- anima_cli-0.1.0/CHANGELOG.md +40 -0
- anima_cli-0.1.0/INVAR.md +112 -0
- anima_cli-0.1.0/LICENSE +661 -0
- anima_cli-0.1.0/PKG-INFO +23 -0
- anima_cli-0.1.0/README.md +162 -0
- anima_cli-0.1.0/config.toml.example +151 -0
- anima_cli-0.1.0/contracts/capability_token.schema.json +46 -0
- anima_cli-0.1.0/contracts/context_bundle.schema.json +81 -0
- anima_cli-0.1.0/contracts/errors.yaml +122 -0
- anima_cli-0.1.0/contracts/job_spec.schema.json +77 -0
- anima_cli-0.1.0/contracts/meta.schema.json +30 -0
- anima_cli-0.1.0/contracts/persona_spec.schema.json +86 -0
- anima_cli-0.1.0/docs/DESIGN.md +341 -0
- anima_cli-0.1.0/docs/INTERFACES.md +1942 -0
- anima_cli-0.1.0/docs/archives/cli-refactor-verification-protocol.md +443 -0
- anima_cli-0.1.0/docs/archives/evidence/guard-dead-code-triage-gate-fix-evidence.md +260 -0
- anima_cli-0.1.0/docs/archives/evidence/invar-remediation-2026-03-09-fix-gate-evidence-blockers.md +131 -0
- anima_cli-0.1.0/docs/archives/gate-2026-03-04-warning-budget.md +203 -0
- anima_cli-0.1.0/docs/archives/incidents/vectl-plan-divergence-2026-03-07.md +425 -0
- anima_cli-0.1.0/docs/archives/repro-coverage.md +62 -0
- anima_cli-0.1.0/docs/guides/cli-guide.md +1414 -0
- anima_cli-0.1.0/docs/guides/persona-switch.md +162 -0
- anima_cli-0.1.0/docs/operations/gate-cleanliness.md +179 -0
- anima_cli-0.1.0/docs/operations/verifier-environment-spec.md +211 -0
- anima_cli-0.1.0/docs/operations/verify-only-gate-worktree-policy.md +400 -0
- anima_cli-0.1.0/docs/operations/waterline-checklist.md +337 -0
- anima_cli-0.1.0/docs/operations/waterline-freeze-policy.md +319 -0
- anima_cli-0.1.0/docs/proposals/context-compaction-context-limit-sourcing.md +28 -0
- anima_cli-0.1.0/docs/proposals/execution-architecture-refactor.md +564 -0
- anima_cli-0.1.0/docs/proposals/sandbox-design.md +392 -0
- anima_cli-0.1.0/docs/proposals/schema-module-split-contract.md +137 -0
- anima_cli-0.1.0/docs/proposals/serve-mode-security-decision.md +176 -0
- anima_cli-0.1.0/docs/proposals/serve-stream-bridge.md +153 -0
- anima_cli-0.1.0/docs/proposals/subagent-coordination.md +474 -0
- anima_cli-0.1.0/docs/proposals/talk-streaming-transport.md +211 -0
- anima_cli-0.1.0/docs/proposals/tool-output-governance-contract.md +424 -0
- anima_cli-0.1.0/plan.yaml +93524 -0
- anima_cli-0.1.0/pyproject.toml +63 -0
- anima_cli-0.1.0/scripts/cli-refactor-verify.sh +601 -0
- anima_cli-0.1.0/scripts/gate-cleanliness-check.sh +418 -0
- anima_cli-0.1.0/scripts/waterline_guard_gate.py +269 -0
- anima_cli-0.1.0/src/anima/__init__.py +3 -0
- anima_cli-0.1.0/src/anima/__main__.py +7 -0
- anima_cli-0.1.0/src/anima/app/__init__.py +95 -0
- anima_cli-0.1.0/src/anima/app/context_service.py +141 -0
- anima_cli-0.1.0/src/anima/app/control_service.py +694 -0
- anima_cli-0.1.0/src/anima/app/launch_service.py +294 -0
- anima_cli-0.1.0/src/anima/app/result_service.py +107 -0
- anima_cli-0.1.0/src/anima/app/session_service.py +327 -0
- anima_cli-0.1.0/src/anima/core/__init__.py +1 -0
- anima_cli-0.1.0/src/anima/core/budget.py +268 -0
- anima_cli-0.1.0/src/anima/core/compaction.py +380 -0
- anima_cli-0.1.0/src/anima/core/contracts/__init__.py +69 -0
- anima_cli-0.1.0/src/anima/core/contracts/execution.py +158 -0
- anima_cli-0.1.0/src/anima/core/contracts/specs.py +65 -0
- anima_cli-0.1.0/src/anima/core/conversation/__init__.py +33 -0
- anima_cli-0.1.0/src/anima/core/conversation/contracts.py +83 -0
- anima_cli-0.1.0/src/anima/core/execution/__init__.py +75 -0
- anima_cli-0.1.0/src/anima/core/execution/contracts.py +250 -0
- anima_cli-0.1.0/src/anima/core/execution/resolver.py +478 -0
- anima_cli-0.1.0/src/anima/core/execution/state.py +86 -0
- anima_cli-0.1.0/src/anima/core/ids.py +157 -0
- anima_cli-0.1.0/src/anima/core/lifecycle.py +442 -0
- anima_cli-0.1.0/src/anima/core/model_precedence.py +87 -0
- anima_cli-0.1.0/src/anima/core/model_registry.py +206 -0
- anima_cli-0.1.0/src/anima/core/persona_factory.py +81 -0
- anima_cli-0.1.0/src/anima/core/persona_import.py +254 -0
- anima_cli-0.1.0/src/anima/core/prune.py +418 -0
- anima_cli-0.1.0/src/anima/core/sandbox.py +490 -0
- anima_cli-0.1.0/src/anima/core/schemas/__init__.py +108 -0
- anima_cli-0.1.0/src/anima/core/schemas/enums.py +149 -0
- anima_cli-0.1.0/src/anima/core/schemas/errors.py +601 -0
- anima_cli-0.1.0/src/anima/core/schemas/models.py +1848 -0
- anima_cli-0.1.0/src/anima/core/talk_commands.py +47 -0
- anima_cli-0.1.0/src/anima/core/talk_history.py +274 -0
- anima_cli-0.1.0/src/anima/core/timeout_parser.py +120 -0
- anima_cli-0.1.0/src/anima/core/tool_namespace.py +133 -0
- anima_cli-0.1.0/src/anima/core/tool_policy.py +494 -0
- anima_cli-0.1.0/src/anima/core/tool_resolver.py +489 -0
- anima_cli-0.1.0/src/anima/core/tracker.py +371 -0
- anima_cli-0.1.0/src/anima/data/__init__.py +0 -0
- anima_cli-0.1.0/src/anima/shell/__init__.py +1 -0
- anima_cli-0.1.0/src/anima/shell/agent.py +1275 -0
- anima_cli-0.1.0/src/anima/shell/agent_budget.py +282 -0
- anima_cli-0.1.0/src/anima/shell/agent_compaction.py +111 -0
- anima_cli-0.1.0/src/anima/shell/agent_factory.py +282 -0
- anima_cli-0.1.0/src/anima/shell/agent_helpers.py +303 -0
- anima_cli-0.1.0/src/anima/shell/agent_interact.py +612 -0
- anima_cli-0.1.0/src/anima/shell/agent_kill.py +157 -0
- anima_cli-0.1.0/src/anima/shell/agent_launcher.py +124 -0
- anima_cli-0.1.0/src/anima/shell/agent_lifecycle.py +264 -0
- anima_cli-0.1.0/src/anima/shell/agent_response.py +112 -0
- anima_cli-0.1.0/src/anima/shell/agent_runner.py +425 -0
- anima_cli-0.1.0/src/anima/shell/agent_sync.py +189 -0
- anima_cli-0.1.0/src/anima/shell/cli.py +703 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/__init__.py +5 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/_shared.py +98 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/chat_cmd.py +484 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/cleanup_cmds.py +665 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/inspect_collect.py +680 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/kill_cmd.py +389 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/lifecycle_cmds.py +390 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/monitor_serve.py +402 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/persona_cmd.py +468 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/query.py +296 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/run_spawn.py +1260 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/talk_cmd.py +647 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/talk_deps.py +199 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/talk_display.py +288 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/talk_helpers.py +64 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/talk_input.py +102 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/talk_markdown.py +241 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/talk_runtime.py +900 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/talk_runtime_support.py +208 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/talk_session.py +1000 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/talk_streaming.py +519 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/talk_task_indicators.py +214 -0
- anima_cli-0.1.0/src/anima/shell/cli_commands/tools_cmd.py +683 -0
- anima_cli-0.1.0/src/anima/shell/cli_params.py +189 -0
- anima_cli-0.1.0/src/anima/shell/cli_utils.py +396 -0
- anima_cli-0.1.0/src/anima/shell/context_bundle.py +363 -0
- anima_cli-0.1.0/src/anima/shell/contract_compat.py +219 -0
- anima_cli-0.1.0/src/anima/shell/control_service_adapter.py +140 -0
- anima_cli-0.1.0/src/anima/shell/ctl.py +238 -0
- anima_cli-0.1.0/src/anima/shell/ctl_approval.py +169 -0
- anima_cli-0.1.0/src/anima/shell/ctl_child.py +254 -0
- anima_cli-0.1.0/src/anima/shell/ctl_delegate.py +521 -0
- anima_cli-0.1.0/src/anima/shell/ctl_spawn.py +671 -0
- anima_cli-0.1.0/src/anima/shell/ctl_tools.py +512 -0
- anima_cli-0.1.0/src/anima/shell/larva_persona_resolver.py +222 -0
- anima_cli-0.1.0/src/anima/shell/mcp_agent.py +1402 -0
- anima_cli-0.1.0/src/anima/shell/mcp_bridge.py +437 -0
- anima_cli-0.1.0/src/anima/shell/mcp_serve.py +1442 -0
- anima_cli-0.1.0/src/anima/shell/mcp_servers.py +332 -0
- anima_cli-0.1.0/src/anima/shell/mcp_toolset_policy.py +578 -0
- anima_cli-0.1.0/src/anima/shell/meta.py +119 -0
- anima_cli-0.1.0/src/anima/shell/meta_injection.py +230 -0
- anima_cli-0.1.0/src/anima/shell/model_config.py +635 -0
- anima_cli-0.1.0/src/anima/shell/sandbox_check.py +54 -0
- anima_cli-0.1.0/src/anima/shell/state.py +1629 -0
- anima_cli-0.1.0/src/anima/shell/timeout_watchdog.py +425 -0
- anima_cli-0.1.0/src/anima/shell/tool_output_telemetry.py +120 -0
- anima_cli-0.1.0/src/anima/shell/tool_policy.py +150 -0
- anima_cli-0.1.0/tests/__init__.py +1 -0
- anima_cli-0.1.0/tests/conftest.py +514 -0
- anima_cli-0.1.0/tests/execution_contract_fixtures.py +169 -0
- anima_cli-0.1.0/tests/fixtures/__init__.py +138 -0
- anima_cli-0.1.0/tests/fixtures/claude-code-agent.md +6 -0
- anima_cli-0.1.0/tests/fixtures/conversation_types.py +565 -0
- anima_cli-0.1.0/tests/fixtures/execution_contract_resolution.py +502 -0
- anima_cli-0.1.0/tests/fixtures/launch_control_services.py +442 -0
- anima_cli-0.1.0/tests/fixtures/opencode-agent.md +4 -0
- anima_cli-0.1.0/tests/fixtures/persona_demo.json +7 -0
- anima_cli-0.1.0/tests/fixtures/persona_openrouter.json +7 -0
- anima_cli-0.1.0/tests/fixtures/session_attach.py +188 -0
- anima_cli-0.1.0/tests/helpers/__init__.py +1 -0
- anima_cli-0.1.0/tests/helpers/mcp_fakes.py +386 -0
- anima_cli-0.1.0/tests/integration/test_context_mode_bundle_loading.py +206 -0
- anima_cli-0.1.0/tests/integration_helpers.py +504 -0
- anima_cli-0.1.0/tests/prototype_prompt_toolkit_compat.py +257 -0
- anima_cli-0.1.0/tests/repro/__init__.py +0 -0
- anima_cli-0.1.0/tests/repro/assert_new_label_style.py +62 -0
- anima_cli-0.1.0/tests/repro/crash_cleanup_verify.py +90 -0
- anima_cli-0.1.0/tests/repro/issue_approve_help_exit_code.py +36 -0
- anima_cli-0.1.0/tests/repro/issue_error_codes_registry_stale.py +41 -0
- anima_cli-0.1.0/tests/repro/issue_lifecycle_enforcement_verify.py +220 -0
- anima_cli-0.1.0/tests/repro/issue_spec_compliance_verify_meta_and_interact.py +159 -0
- anima_cli-0.1.0/tests/repro/issue_spec_compliance_verify_spawn.py +241 -0
- anima_cli-0.1.0/tests/repro/issue_talk_streaming_path_verify.py +566 -0
- anima_cli-0.1.0/tests/repro/stale_ls_detection.py +146 -0
- anima_cli-0.1.0/tests/repro/test_spec_compliance_verify_meta_and_interact.py +15 -0
- anima_cli-0.1.0/tests/repro/test_spec_compliance_verify_spawn.py +13 -0
- anima_cli-0.1.0/tests/test-cli-refactor-verify-atomicity.sh +202 -0
- anima_cli-0.1.0/tests/test_agent_compaction.py +221 -0
- anima_cli-0.1.0/tests/test_agent_ctl_integration.py +765 -0
- anima_cli-0.1.0/tests/test_agent_runner_paths.py +1301 -0
- anima_cli-0.1.0/tests/test_auto_rm_blackbox.py +553 -0
- anima_cli-0.1.0/tests/test_budget.py +407 -0
- anima_cli-0.1.0/tests/test_budget_exhaustion_paths.py +337 -0
- anima_cli-0.1.0/tests/test_budget_profiles_history_degradation.py +658 -0
- anima_cli-0.1.0/tests/test_child_approval_propagation.py +799 -0
- anima_cli-0.1.0/tests/test_cli.py +4924 -0
- anima_cli-0.1.0/tests/test_cli_collect_auto_read.py +118 -0
- anima_cli-0.1.0/tests/test_cli_extracted_helpers.py +174 -0
- anima_cli-0.1.0/tests/test_cli_utils_persona.py +407 -0
- anima_cli-0.1.0/tests/test_compaction.py +309 -0
- anima_cli-0.1.0/tests/test_compaction_integration.py +290 -0
- anima_cli-0.1.0/tests/test_component_cli_boundary_seams.py +513 -0
- anima_cli-0.1.0/tests/test_component_mcp_handlers.py +1161 -0
- anima_cli-0.1.0/tests/test_component_persona_wiring.py +425 -0
- anima_cli-0.1.0/tests/test_context_bundle.py +364 -0
- anima_cli-0.1.0/tests/test_context_bundle_wiring.py +340 -0
- anima_cli-0.1.0/tests/test_context_service.py +396 -0
- anima_cli-0.1.0/tests/test_ctl.py +1976 -0
- anima_cli-0.1.0/tests/test_ctl_approval.py +80 -0
- anima_cli-0.1.0/tests/test_ctl_child.py +353 -0
- anima_cli-0.1.0/tests/test_ctl_delegate.py +664 -0
- anima_cli-0.1.0/tests/test_ctl_tools_invocation.py +376 -0
- anima_cli-0.1.0/tests/test_e2e_agent_lifecycle.py +396 -0
- anima_cli-0.1.0/tests/test_e2e_budget_ctl.py +1296 -0
- anima_cli-0.1.0/tests/test_e2e_cli.py +633 -0
- anima_cli-0.1.0/tests/test_e2e_crash_recovery.py +432 -0
- anima_cli-0.1.0/tests/test_e2e_mcp.py +109 -0
- anima_cli-0.1.0/tests/test_e2e_stale_state.py +386 -0
- anima_cli-0.1.0/tests/test_error_message_quality.py +152 -0
- anima_cli-0.1.0/tests/test_execution_contract.py +1170 -0
- anima_cli-0.1.0/tests/test_execution_contract_boundary.py +70 -0
- anima_cli-0.1.0/tests/test_execution_contract_import_compat.py +21 -0
- anima_cli-0.1.0/tests/test_execution_output_contract.py +1071 -0
- anima_cli-0.1.0/tests/test_extract_tool_arg_preview.py +123 -0
- anima_cli-0.1.0/tests/test_global_config.py +799 -0
- anima_cli-0.1.0/tests/test_instance_id_security.py +171 -0
- anima_cli-0.1.0/tests/test_integration_chat_cmd.py +138 -0
- anima_cli-0.1.0/tests/test_integration_ctl_spawn_subprocess.py +218 -0
- anima_cli-0.1.0/tests/test_integration_env.py +49 -0
- anima_cli-0.1.0/tests/test_integration_error_cleanup.py +173 -0
- anima_cli-0.1.0/tests/test_integration_full_path.py +254 -0
- anima_cli-0.1.0/tests/test_integration_l2.py +947 -0
- anima_cli-0.1.0/tests/test_integration_mcp_tool_policy_runtime.py +289 -0
- anima_cli-0.1.0/tests/test_integration_spawn_subprocess.py +523 -0
- anima_cli-0.1.0/tests/test_integration_state_seam_proofs.py +95 -0
- anima_cli-0.1.0/tests/test_interactive_smoke.py +127 -0
- anima_cli-0.1.0/tests/test_larva_persona_resolver.py +335 -0
- anima_cli-0.1.0/tests/test_launch_control_services.py +313 -0
- anima_cli-0.1.0/tests/test_lifecycle.py +444 -0
- anima_cli-0.1.0/tests/test_lifecycle_cmds.py +300 -0
- anima_cli-0.1.0/tests/test_llm_connection.py +111 -0
- anima_cli-0.1.0/tests/test_logs_tool.py +194 -0
- anima_cli-0.1.0/tests/test_max_turns_grace.py +162 -0
- anima_cli-0.1.0/tests/test_mcp_approval_tools.py +209 -0
- anima_cli-0.1.0/tests/test_mcp_bridge.py +343 -0
- anima_cli-0.1.0/tests/test_mcp_env_passthrough.py +283 -0
- anima_cli-0.1.0/tests/test_mcp_metadata.py +438 -0
- anima_cli-0.1.0/tests/test_mcp_serve_bridge.py +1539 -0
- anima_cli-0.1.0/tests/test_mcp_serve_logging.py +135 -0
- anima_cli-0.1.0/tests/test_mcp_socket_readiness.py +150 -0
- anima_cli-0.1.0/tests/test_mcp_wiring.py +550 -0
- anima_cli-0.1.0/tests/test_meta.py +81 -0
- anima_cli-0.1.0/tests/test_meta_injection.py +367 -0
- anima_cli-0.1.0/tests/test_model_config.py +203 -0
- anima_cli-0.1.0/tests/test_model_registry.py +200 -0
- anima_cli-0.1.0/tests/test_monitor_serve_table_layout.py +72 -0
- anima_cli-0.1.0/tests/test_monitor_serve_talk_coverage.py +1313 -0
- anima_cli-0.1.0/tests/test_proof_remediation.py +540 -0
- anima_cli-0.1.0/tests/test_rm_batch.py +353 -0
- anima_cli-0.1.0/tests/test_sandbox.py +369 -0
- anima_cli-0.1.0/tests/test_sandbox_check.py +92 -0
- anima_cli-0.1.0/tests/test_schema_package_cleanup.py +463 -0
- anima_cli-0.1.0/tests/test_schemas.py +1868 -0
- anima_cli-0.1.0/tests/test_session_attach.py +306 -0
- anima_cli-0.1.0/tests/test_spawn_anima_state_env.py +191 -0
- anima_cli-0.1.0/tests/test_spawn_model_override.py +182 -0
- anima_cli-0.1.0/tests/test_spawn_result_persistence.py +148 -0
- anima_cli-0.1.0/tests/test_state.py +905 -0
- anima_cli-0.1.0/tests/test_stream_endpoint.py +176 -0
- anima_cli-0.1.0/tests/test_talk_attach_regression.py +490 -0
- anima_cli-0.1.0/tests/test_talk_concurrent_input.py +809 -0
- anima_cli-0.1.0/tests/test_talk_ctrl_c_handling.py +279 -0
- anima_cli-0.1.0/tests/test_talk_display.py +167 -0
- anima_cli-0.1.0/tests/test_talk_history.py +709 -0
- anima_cli-0.1.0/tests/test_talk_io_visual.py +1919 -0
- anima_cli-0.1.0/tests/test_talk_markdown_streaming.py +131 -0
- anima_cli-0.1.0/tests/test_talk_prompt_toolkit_migration.py +257 -0
- anima_cli-0.1.0/tests/test_talk_sse_consume_no_duplicates.py +258 -0
- anima_cli-0.1.0/tests/test_talk_sse_parsing.py +190 -0
- anima_cli-0.1.0/tests/test_talk_streaming.py +213 -0
- anima_cli-0.1.0/tests/test_talk_streaming_probe.py +176 -0
- anima_cli-0.1.0/tests/test_task_indicators.py +158 -0
- anima_cli-0.1.0/tests/test_timeout_parser.py +176 -0
- anima_cli-0.1.0/tests/test_timeout_watchdog.py +379 -0
- anima_cli-0.1.0/tests/test_token_delta_tracking.py +156 -0
- anima_cli-0.1.0/tests/test_token_to_mcp.py +285 -0
- anima_cli-0.1.0/tests/test_tool_namespace.py +57 -0
- anima_cli-0.1.0/tests/test_tool_output_governance_adapters.py +926 -0
- anima_cli-0.1.0/tests/test_tool_output_governance_telemetry.py +1159 -0
- anima_cli-0.1.0/tests/test_tool_policy.py +508 -0
- anima_cli-0.1.0/tests/test_tool_resolver.py +537 -0
- anima_cli-0.1.0/tests/test_unit_chat_cleanup.py +105 -0
- anima_cli-0.1.0/tests/test_unit_mcp_toolset_policy.py +973 -0
- anima_cli-0.1.0/uv.lock +3948 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
_invar:
|
|
3
|
+
version: "5.0"
|
|
4
|
+
type: command
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Audit
|
|
8
|
+
|
|
9
|
+
Read-only code review. Reports issues without fixing them.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Behavior
|
|
14
|
+
|
|
15
|
+
1. Analyze code for issues (style, bugs, security, architecture)
|
|
16
|
+
2. Report findings with file:line references
|
|
17
|
+
3. **Do NOT make any changes** - report only
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Adversarial Reviewer Persona
|
|
22
|
+
|
|
23
|
+
You are an **adversarial code reviewer**. Your job is to FIND PROBLEMS.
|
|
24
|
+
|
|
25
|
+
### Your Mindset
|
|
26
|
+
|
|
27
|
+
Assume:
|
|
28
|
+
- The code has bugs until proven otherwise
|
|
29
|
+
- The contracts may be meaningless ceremony
|
|
30
|
+
- The implementer may have rationalized poor decisions
|
|
31
|
+
- Escape hatches may be abused
|
|
32
|
+
|
|
33
|
+
You are NOT here to:
|
|
34
|
+
- Validate that code works
|
|
35
|
+
- Confirm the implementer did a good job
|
|
36
|
+
- Be nice or diplomatic
|
|
37
|
+
|
|
38
|
+
You ARE here to:
|
|
39
|
+
- Find bugs, logic errors, edge cases
|
|
40
|
+
- Challenge whether contracts have semantic value
|
|
41
|
+
- Identify code smells and duplication
|
|
42
|
+
- Question every escape hatch
|
|
43
|
+
- Check if code matches contracts (not if code "seems right")
|
|
44
|
+
|
|
45
|
+
**Your success is measured by problems found, not code approved.**
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Review Checklist
|
|
50
|
+
|
|
51
|
+
> **Principle:** Only items requiring semantic judgment. Mechanical checks are excluded (see bottom).
|
|
52
|
+
|
|
53
|
+
### A. Contract Semantic Value
|
|
54
|
+
|
|
55
|
+
- [ ] Does @pre constrain inputs beyond type checking?
|
|
56
|
+
- Bad: `@pre(lambda x: isinstance(x, int))`
|
|
57
|
+
- Good: `@pre(lambda x: x > 0 and x < MAX_VALUE)`
|
|
58
|
+
- [ ] Does @post verify meaningful output properties?
|
|
59
|
+
- Bad: `@post(lambda result: result is not None)`
|
|
60
|
+
- Good: `@post(lambda result: len(result) == len(input))`
|
|
61
|
+
|
|
62
|
+
- [ ] Could someone implement correctly from contracts alone?
|
|
63
|
+
- [ ] Are boundary conditions explicit in contracts?
|
|
64
|
+
|
|
65
|
+
### B. Doctest Coverage
|
|
66
|
+
- [ ] Do doctests cover normal cases?
|
|
67
|
+
- [ ] Do doctests cover boundary cases?
|
|
68
|
+
- [ ] Do doctests cover error cases?
|
|
69
|
+
- [ ] Are doctests testing behavior, not just syntax?
|
|
70
|
+
|
|
71
|
+
### C. Code Quality
|
|
72
|
+
- [ ] Is duplicated code worth extracting?
|
|
73
|
+
- [ ] Is naming consistent and clear?
|
|
74
|
+
- [ ] Is complexity justified?
|
|
75
|
+
|
|
76
|
+
### D. Escape Hatch Audit
|
|
77
|
+
- [ ] Is each @invar:allow justification valid?
|
|
78
|
+
- [ ] Could refactoring eliminate the need?
|
|
79
|
+
- [ ] Is there a pattern suggesting systematic issues?
|
|
80
|
+
|
|
81
|
+
### E. Logic Verification
|
|
82
|
+
- [ ] Do contracts correctly capture intended behavior?
|
|
83
|
+
- [ ] Are there paths that bypass contract checks?
|
|
84
|
+
- [ ] Are there implicit assumptions not in contracts?
|
|
85
|
+
- [ ] What happens with unexpected inputs?
|
|
86
|
+
|
|
87
|
+
### F. Security
|
|
88
|
+
- [ ] Are inputs validated against security threats (injection, XSS)?
|
|
89
|
+
- [ ] No hardcoded secrets (API keys, passwords, tokens)?
|
|
90
|
+
- [ ] Are authentication/authorization checks correct?
|
|
91
|
+
- [ ] Is sensitive data properly protected?
|
|
92
|
+
|
|
93
|
+
### G. Error Handling & Observability
|
|
94
|
+
- [ ] Are exceptions caught at appropriate level?
|
|
95
|
+
- [ ] Are error messages clear without leaking sensitive info?
|
|
96
|
+
- [ ] Are critical operations logged for debugging?
|
|
97
|
+
- [ ] Is there graceful degradation on failure?
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Excluded (Covered by Guard)
|
|
102
|
+
|
|
103
|
+
These are checked by Guard or linters - don't duplicate:
|
|
104
|
+
- Core/Shell separation → Guard (forbidden_import, impure_call)
|
|
105
|
+
- Shell returns Result[T,E] → Guard (shell_result)
|
|
106
|
+
- Missing contracts → Guard (missing_contract)
|
|
107
|
+
- File/function size limits → Guard (file_size, function_size)
|
|
108
|
+
- Entry point thickness → Guard (entry_point_too_thick)
|
|
109
|
+
- Escape hatch count → Guard (review_suggested)
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Report Format
|
|
114
|
+
|
|
115
|
+
For each issue found, use severity levels:
|
|
116
|
+
|
|
117
|
+
| Severity | Meaning |
|
|
118
|
+
|----------|---------|
|
|
119
|
+
| **CRITICAL** | Must fix before completion |
|
|
120
|
+
| **MAJOR** | Fix or provide written justification |
|
|
121
|
+
| **MINOR** | Optional, can defer |
|
|
122
|
+
|
|
123
|
+
```markdown
|
|
124
|
+
### [CRITICAL/MAJOR/MINOR] Issue Title
|
|
125
|
+
|
|
126
|
+
**Location:** file.py:line_number
|
|
127
|
+
**Category:** contract_quality | logic_error | security | escape_hatch | code_smell
|
|
128
|
+
**Problem:** What's wrong
|
|
129
|
+
**Suggestion:** How to fix (but don't implement)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Instructions
|
|
135
|
+
|
|
136
|
+
1. Run `invar guard --changed` to see current state
|
|
137
|
+
2. Go through each checklist category
|
|
138
|
+
3. For each issue, determine severity (CRITICAL/MAJOR/MINOR)
|
|
139
|
+
4. Report with structured format above
|
|
140
|
+
5. Be thorough and adversarial
|
|
141
|
+
|
|
142
|
+
**Remember:** You are READ-ONLY. Report issues, don't fix them.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
Now review the recent changes or the files specified by the user.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
_invar:
|
|
3
|
+
version: "5.0"
|
|
4
|
+
type: command
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Guard
|
|
8
|
+
|
|
9
|
+
Run Invar verification on the project and report results.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Behavior
|
|
14
|
+
|
|
15
|
+
Execute `invar_guard()` and report:
|
|
16
|
+
- Pass/fail status
|
|
17
|
+
- Error count with details
|
|
18
|
+
- Warning count with details
|
|
19
|
+
|
|
20
|
+
**Do NOT fix issues** - just report verification results.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## When to Use
|
|
25
|
+
|
|
26
|
+
- Quick verification check
|
|
27
|
+
- Before committing changes
|
|
28
|
+
- After pulling changes
|
|
29
|
+
- To see current project health
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Execution
|
|
34
|
+
|
|
35
|
+
Run verification:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
invar_guard(changed=true)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Or for full project verification:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
invar_guard()
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Report Format
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
## Guard Results
|
|
53
|
+
|
|
54
|
+
**Status:** PASS / FAIL
|
|
55
|
+
**Errors:** N
|
|
56
|
+
**Warnings:** N
|
|
57
|
+
|
|
58
|
+
### Errors (if any)
|
|
59
|
+
|
|
60
|
+
| Rule | File | Line | Message |
|
|
61
|
+
|------|------|------|---------|
|
|
62
|
+
| missing_contract | src/foo.py | 42 | Function 'bar' has no @pre/@post |
|
|
63
|
+
|
|
64
|
+
### Warnings (if any)
|
|
65
|
+
|
|
66
|
+
| Rule | File | Line | Message |
|
|
67
|
+
|------|------|------|---------|
|
|
68
|
+
| function_size | src/baz.py | 15 | Function exceeds 50 lines |
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Next Steps
|
|
74
|
+
|
|
75
|
+
After reporting results:
|
|
76
|
+
- If PASS: No action needed
|
|
77
|
+
- If FAIL: User decides whether to fix issues
|
|
78
|
+
|
|
79
|
+
**Remember:** You are READ-ONLY. Report results, don't fix them.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
Now run verification on the current project.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<!--invar:begin-->
|
|
2
|
+
## Invar
|
|
3
|
+
|
|
4
|
+
**CRITICAL: Write `@pre`/`@post` contracts and at least one doctest BEFORE implementing a Core function. Guard rejects uncontracted Core code.**
|
|
5
|
+
|
|
6
|
+
### Architecture
|
|
7
|
+
|
|
8
|
+
| Zone | Path | Rules |
|
|
9
|
+
|------|------|-------|
|
|
10
|
+
| Core | `**/core/**` | `@pre` + `@post` + doctest, no I/O imports |
|
|
11
|
+
| Shell | `**/shell/**` | returns `Result[T, E]`, handles I/O |
|
|
12
|
+
|
|
13
|
+
If code touches files, network, env vars, time, randomness, or subprocesses, use Shell.
|
|
14
|
+
|
|
15
|
+
### Verification
|
|
16
|
+
|
|
17
|
+
Run `invar guard` after changes. Fix errors before committing.
|
|
18
|
+
|
|
19
|
+
### Tools
|
|
20
|
+
|
|
21
|
+
| Tool | Use |
|
|
22
|
+
|------|-----|
|
|
23
|
+
| `invar guard` | verify architecture and contracts |
|
|
24
|
+
| `invar sig <file>` | inspect signatures and contracts |
|
|
25
|
+
| `invar map [path]` | inspect entry points |
|
|
26
|
+
| `invar refs <file>::<symbol>` | inspect references |
|
|
27
|
+
|
|
28
|
+
### Contract Traps
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
# @pre must include all parameters, including defaults
|
|
32
|
+
@pre(lambda x, y=0: x >= 0)
|
|
33
|
+
def calc(x: int, y: int = 0): ...
|
|
34
|
+
|
|
35
|
+
# @post only receives result
|
|
36
|
+
@post(lambda result: result >= 0)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Escape Hatches
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
# @invar:allow dead_export: CLI entry point called by framework
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Exact syntax and repair patterns: `INVAR.md`
|
|
46
|
+
<!--invar:end-->
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
<!-- VECTL:AGENTS:BEGIN -->
|
|
51
|
+
## Plan Tracking (vectl)
|
|
52
|
+
|
|
53
|
+
vectl tracks this repo's implementation plan as a structured `plan.yaml`:
|
|
54
|
+
what to do next, who claimed it, and what counts as done (with verification evidence).
|
|
55
|
+
|
|
56
|
+
Full guide: `vectl_guide` (CLI fallback: `vectl guide`)
|
|
57
|
+
Quick view: `vectl_status` (CLI fallback: `vectl status`)
|
|
58
|
+
|
|
59
|
+
### MCP vs CLI
|
|
60
|
+
- Source of truth: `plan.yaml` (channel-agnostic).
|
|
61
|
+
- **Always prefer MCP tools** (`vectl_status`, `vectl_claim`, `vectl_complete`, etc.) when available.
|
|
62
|
+
- CLI fallback priority: `uv run vectl` > `vectl` > `uvx vectl`.
|
|
63
|
+
- Evidence requirements are identical across MCP and CLI.
|
|
64
|
+
|
|
65
|
+
### Claim-time Guidance
|
|
66
|
+
- `vectl claim` may emit a bounded Guidance block delimited by:
|
|
67
|
+
- `--- VECTL:GUIDANCE:BEGIN ---`
|
|
68
|
+
- `--- VECTL:GUIDANCE:END ---`
|
|
69
|
+
- For automation/CI: use `vectl claim --no-guidance` to keep stdout clean.
|
|
70
|
+
|
|
71
|
+
### plan.yaml — Managed File (DO NOT EDIT DIRECTLY)
|
|
72
|
+
|
|
73
|
+
`plan.yaml` is exclusively owned by vectl. Direct edits (Edit, Write, sed, or
|
|
74
|
+
any file tool) **will** corrupt plan state — vectl performs CAS writes, lock
|
|
75
|
+
recalculation, and schema validation on every save, none of which run on direct
|
|
76
|
+
edits.
|
|
77
|
+
|
|
78
|
+
**To modify plan state, ONLY use:**
|
|
79
|
+
- MCP (preferred): `vectl_claim`, `vectl_complete`, `vectl_mutate`, etc.
|
|
80
|
+
- CLI (fallback): `uv run vectl claim`, `vectl claim`, or `uvx vectl claim`, etc.
|
|
81
|
+
|
|
82
|
+
If a vectl command fails, report the error — do **not** edit `plan.yaml`
|
|
83
|
+
directly as a workaround. Use `vectl guide stuck` for troubleshooting.
|
|
84
|
+
|
|
85
|
+
### Rules
|
|
86
|
+
- One claimed step at a time.
|
|
87
|
+
- Evidence is mandatory when completing (commands run + outputs + gaps).
|
|
88
|
+
- Spec uncertainty: leave `# SPEC QUESTION: ...` in code, do not guess.
|
|
89
|
+
|
|
90
|
+
### Step ID Uniqueness
|
|
91
|
+
**Step IDs must be globally unique across ALL phases.**
|
|
92
|
+
- Example: `auth.login` and `api.login` are different step IDs.
|
|
93
|
+
- Example: Using just `login` in two phases creates a duplicate — not allowed.
|
|
94
|
+
- If you have legacy duplicate step IDs, use `vectl migrate-step-id --dry-run`
|
|
95
|
+
to preview and `--yes` to repair.
|
|
96
|
+
|
|
97
|
+
### For Architects / Planners
|
|
98
|
+
- **Design Mode**: Run `vectl_guide` (CLI fallback: `vectl guide --on planning`) to learn the Architect Protocol.
|
|
99
|
+
- **Ambiguity = Failure**: Workers will hallucinate if steps are vague.
|
|
100
|
+
- **Constraint Tools**:
|
|
101
|
+
- `--evidence-template`: Force workers to provide specific proof (e.g., "Paste logs here").
|
|
102
|
+
- `--refs`: Pin specific files (e.g., "src/auth.py") to the worker's context.
|
|
103
|
+
<!-- VECTL:AGENTS:END -->
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
publish:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
environment: pypi
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install build tools
|
|
22
|
+
run: pip install build
|
|
23
|
+
|
|
24
|
+
- name: Build package
|
|
25
|
+
run: python -m build
|
|
26
|
+
|
|
27
|
+
- name: Publish to PyPI
|
|
28
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Waterline Gate
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
guard-waterline:
|
|
11
|
+
name: Guard Waterline Non-Regression
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
timeout-minutes: 20
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Setup Python
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.12"
|
|
23
|
+
|
|
24
|
+
- name: Setup uv
|
|
25
|
+
uses: astral-sh/setup-uv@v4
|
|
26
|
+
|
|
27
|
+
- name: Install project dependencies
|
|
28
|
+
run: uv sync --dev
|
|
29
|
+
|
|
30
|
+
- name: Run tests (including repro scripts)
|
|
31
|
+
run: uv run pytest tests/ -v --tb=short
|
|
32
|
+
|
|
33
|
+
- name: Enforce frozen waterline gate
|
|
34
|
+
run: uv run python scripts/waterline_guard_gate.py
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
*.egg
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
ENV/
|
|
16
|
+
|
|
17
|
+
# IDE
|
|
18
|
+
.idea/
|
|
19
|
+
.vscode/
|
|
20
|
+
*.swp
|
|
21
|
+
*.swo
|
|
22
|
+
*~
|
|
23
|
+
|
|
24
|
+
# Testing
|
|
25
|
+
.pytest_cache/
|
|
26
|
+
.coverage
|
|
27
|
+
htmlcov/
|
|
28
|
+
.mypy_cache/
|
|
29
|
+
|
|
30
|
+
# Test artifacts (hermetic)
|
|
31
|
+
.hypothesis/
|
|
32
|
+
.lattice/
|
|
33
|
+
|
|
34
|
+
# OS
|
|
35
|
+
.DS_Store
|
|
36
|
+
Thumbs.db
|
|
37
|
+
|
|
38
|
+
# Anima state (local dev)
|
|
39
|
+
.anima/
|
|
40
|
+
|
|
41
|
+
# Claude Code / MCP local config
|
|
42
|
+
.claude/
|
|
43
|
+
.mcp.json
|
|
44
|
+
.opencode/
|
|
45
|
+
CLAUDE.md
|
|
46
|
+
.invar/
|
|
47
|
+
.vectl/
|
|
48
|
+
|
|
49
|
+
.serena/
|
|
50
|
+
.gemini/
|
|
51
|
+
|
|
52
|
+
GEMINI.md
|
|
53
|
+
AGENTS.md
|
|
54
|
+
model_context_windows.json
|
|
55
|
+
|
|
56
|
+
.final_evidence.yaml
|
|
57
|
+
.gate-worktree*
|
|
58
|
+
.coverage.*
|
|
59
|
+
.final_evidence.yaml
|
|
60
|
+
coverage.xml
|
|
61
|
+
|
|
62
|
+
plan-api-*
|
|
63
|
+
plan-api-*
|
|
64
|
+
plan.yaml.lock
|
|
65
|
+
plan-dashboard.html
|
|
66
|
+
|
|
67
|
+
.evidence_spec_compliance_v2_max_turns_grace.yaml
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: local
|
|
3
|
+
hooks:
|
|
4
|
+
- id: invar-md-protected
|
|
5
|
+
name: INVAR.md Protection
|
|
6
|
+
entry: bash -c 'if git diff --cached --name-only | grep -q "^INVAR.md$"; then
|
|
7
|
+
echo "Warning - INVAR.md was modified directly. Use git commit --no-verify if
|
|
8
|
+
intentional."; exit 1; fi'
|
|
9
|
+
language: system
|
|
10
|
+
pass_filenames: false
|
|
11
|
+
stages:
|
|
12
|
+
- pre-commit
|
|
13
|
+
- id: invar-guard
|
|
14
|
+
name: Invar Guard
|
|
15
|
+
entry: bash
|
|
16
|
+
args:
|
|
17
|
+
- -c
|
|
18
|
+
- "RULE_FILES=\"rule_meta.py rules.py contracts.py purity.py pyproject.toml\"\n\
|
|
19
|
+
STAGED=$(git diff --cached --name-only)\nFULL=false\nfor f in $RULE_FILES; do\n\
|
|
20
|
+
\ if echo \"$STAGED\" | grep -qE \"(^|/)${f}$\"; then FULL=true; break; fi\n\
|
|
21
|
+
done\nif [ \"$FULL\" = true ]; then\n echo \"\u26A0\uFE0F Rule change detected\
|
|
22
|
+
\ - running FULL guard\"\n .venv/bin/invar guard\nelse\n .venv/bin/invar guard\
|
|
23
|
+
\ --changed\nfi\n"
|
|
24
|
+
language: system
|
|
25
|
+
pass_filenames: false
|
|
26
|
+
stages:
|
|
27
|
+
- pre-commit
|
|
28
|
+
types:
|
|
29
|
+
- python
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Planned
|
|
11
|
+
|
|
12
|
+
- **Persona Hot-Swap**: Planning for runtime persona switching capability. The `ctl_switch_persona` tool is planned to allow an agent to change its persona mid-session while preserving conversation history, turn counters, token accounting, and MCP server state. **Not yet implemented.**
|
|
13
|
+
|
|
14
|
+
**Planned behavior:**
|
|
15
|
+
- Persona would no longer be immutable for running daemon agents
|
|
16
|
+
- New control tool: `ctl_switch_persona(persona_ref)` (planned)
|
|
17
|
+
- Persona switch would be applied at the next turn boundary (cooperative, not immediate)
|
|
18
|
+
- Conversation history would be preserved across persona switches
|
|
19
|
+
- Only one pending persona switch would be allowed at a time
|
|
20
|
+
|
|
21
|
+
**Documentation:**
|
|
22
|
+
- See [docs/INTERFACES.md Section D.5](./docs/INTERFACES.md#d5-ctl_switch_personapersona_ref) for planned API reference
|
|
23
|
+
- See [docs/DESIGN.md Section 8](./docs/DESIGN.md#8-persona-runtime-switchability) for architecture planning
|
|
24
|
+
|
|
25
|
+
## [0.1.0] - 2026-03-01
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- Initial release of anima CLI agent runner
|
|
30
|
+
- Agent lifecycle management: run, spawn, chat, daemon modes
|
|
31
|
+
- MCP server interface for status, interaction, and interruption
|
|
32
|
+
- Built-in control tools: `ctl_finish`, `ctl_fail`, `ctl_request_approval`, `ctl_suspend_until`, `ctl_spawn_subagent`
|
|
33
|
+
- Budget enforcement with grace finalization
|
|
34
|
+
- State persistence in `$ANIMA_STATE` (default `~/.anima/`)
|
|
35
|
+
- Interactive `talk` command with SSE streaming support
|
|
36
|
+
- PersonaSpec JSON schema for agent configuration
|
|
37
|
+
- JobSpec JSON schema for job configuration
|
|
38
|
+
|
|
39
|
+
[Unreleased]: https://github.com/yourorg/anima/compare/v0.1.0...HEAD
|
|
40
|
+
[0.1.0]: https://github.com/yourorg/anima/releases/tag/v0.1.0
|
anima_cli-0.1.0/INVAR.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Invar Protocol
|
|
2
|
+
|
|
3
|
+
## Before Writing Code
|
|
4
|
+
|
|
5
|
+
1. If you are writing a Core function, write `@pre`, `@post`, and at least one doctest BEFORE implementation.
|
|
6
|
+
2. If you are unsure whether code belongs in Core or Shell, use Shell.
|
|
7
|
+
3. Run `invar guard` after changes. Fix errors before committing.
|
|
8
|
+
|
|
9
|
+
## Core vs Shell
|
|
10
|
+
|
|
11
|
+
Use Shell if the code does any of these:
|
|
12
|
+
- reads or writes files
|
|
13
|
+
- makes network requests
|
|
14
|
+
- reads environment variables
|
|
15
|
+
- uses current time or randomness without injection
|
|
16
|
+
- performs subprocess or system I/O
|
|
17
|
+
|
|
18
|
+
Use Core for pure logic that only transforms already-available data.
|
|
19
|
+
|
|
20
|
+
| Zone | Path | Rules |
|
|
21
|
+
|------|------|-------|
|
|
22
|
+
| Core | `**/core/**` | `@pre` + `@post` + doctest, no I/O imports |
|
|
23
|
+
| Shell | `**/shell/**` | returns `Result[T, E]`, performs I/O |
|
|
24
|
+
|
|
25
|
+
## Contract Syntax Traps
|
|
26
|
+
|
|
27
|
+
### `@pre` lambda must include all function parameters
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
# WRONG
|
|
31
|
+
@pre(lambda x: x >= 0)
|
|
32
|
+
def calc(x: int, y: int = 0): ...
|
|
33
|
+
|
|
34
|
+
# CORRECT
|
|
35
|
+
@pre(lambda x, y=0: x >= 0)
|
|
36
|
+
def calc(x: int, y: int = 0): ...
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### `@post` only receives `result`
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
# WRONG
|
|
43
|
+
@post(lambda result: result > x)
|
|
44
|
+
|
|
45
|
+
# CORRECT
|
|
46
|
+
@post(lambda result: result >= 0)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Contracts must be semantic, not just type checks
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
# WEAK
|
|
53
|
+
@pre(lambda x: isinstance(x, int))
|
|
54
|
+
|
|
55
|
+
# BETTER
|
|
56
|
+
@pre(lambda x: x > 0)
|
|
57
|
+
@pre(lambda start, end: start < end)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Canonical Core Example
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from invar_runtime import pre, post
|
|
64
|
+
|
|
65
|
+
@pre(lambda price, discount: price > 0 and 0 <= discount <= 1)
|
|
66
|
+
@post(lambda result: result >= 0)
|
|
67
|
+
def discounted_price(price: float, discount: float) -> float:
|
|
68
|
+
"""
|
|
69
|
+
>>> discounted_price(100, 0.2)
|
|
70
|
+
80.0
|
|
71
|
+
"""
|
|
72
|
+
return price * (1 - discount)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Canonical Shell Example
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from pathlib import Path
|
|
79
|
+
from returns.result import Result, Success, Failure
|
|
80
|
+
|
|
81
|
+
def read_config(path: Path) -> Result[str, str]:
|
|
82
|
+
try:
|
|
83
|
+
return Success(path.read_text())
|
|
84
|
+
except OSError as exc:
|
|
85
|
+
return Failure(str(exc))
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Escape Hatches
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
# @invar:allow dead_export: CLI entry point called by framework
|
|
92
|
+
# @invar:allow shell_complexity: orchestration requires many steps
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Use escape hatches rarely and always include a reason.
|
|
96
|
+
|
|
97
|
+
## Minimal Configuration
|
|
98
|
+
|
|
99
|
+
```toml
|
|
100
|
+
[tool.invar.guard]
|
|
101
|
+
core_paths = ["src/myapp/core"]
|
|
102
|
+
shell_paths = ["src/myapp/shell"]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Common Guard Repairs
|
|
106
|
+
|
|
107
|
+
| Error | Fix |
|
|
108
|
+
|------|-----|
|
|
109
|
+
| `missing_contract` | add `@pre`, `@post`, and a doctest before implementation |
|
|
110
|
+
| `param_mismatch` | include every function parameter in the `@pre` lambda |
|
|
111
|
+
| `shell_result` | return `Result[T, E]` from Shell functions |
|
|
112
|
+
| `forbidden_import` | move I/O out of Core or inject the value as a parameter |
|