controlzero 1.13.4__tar.gz → 1.13.5__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.
- {controlzero-1.13.4 → controlzero-1.13.5}/PKG-INFO +1 -1
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/__init__.py +1 -1
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/hosts/codex_cli.py +15 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/kiro_adapter.py +10 -2
- controlzero-1.13.5/controlzero/cli/templates/kiro/ide-pre-tool-use.kiro.hook +15 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/client.py +8 -2
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/hitl/secret_leak_guard.py +5 -1
- {controlzero-1.13.4 → controlzero-1.13.5}/pyproject.toml +1 -1
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_6a_request_approval.py +1 -1
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_6a_secret_leak_guard.py +8 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_phase2b_protocol.py +54 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hosts_adapter.py +43 -0
- controlzero-1.13.4/controlzero/cli/templates/kiro/ide-pre-tool-use.kiro.hook +0 -15
- {controlzero-1.13.4 → controlzero-1.13.5}/.gitignore +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/CHANGELOG.md +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/Dockerfile.test +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/LICENSE +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/README.md +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/__main__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/_messages.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/action_aliases.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/action_validator.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/bundle.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/condition_ops.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/credential_hook.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/credential_scanner.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/credentials_data/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/credentials_data/built_in.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/dlp_scanner.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/enforcer.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/hook_extractors.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/io_capture_producer.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/source_labels.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/tool_extractors.json +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/types.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/audit_local.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/audit_remote.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/canonical.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/__main__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/_secrets.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/agent_config.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/console.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/debug_bundle.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/doctor.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/enforcement.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/exec_cmd.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/hook_entry.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/hosts/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/hosts/antigravity.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/hosts/base.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/hosts/claude_code.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/hosts/cursor.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/hosts/cursor_cli.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/hosts/gemini_cli.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/hosts/kiro.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/hosts/unknown.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/main.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/migrate.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/output.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/spool_cmd.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/telemetry_consent.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/antigravity/hooks.json +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/antigravity.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/autogen.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/claude-code.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/codex-cli.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/cost-cap.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/crewai.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/cursor.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/gemini-cli.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/generic.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/kiro/ide-file-save.kiro.hook +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/kiro/ide-prompt-submit.kiro.hook +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/kiro/kiro.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/langchain.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/mcp.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/rag.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/update_cmd.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/device.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/enrollment.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/error_codes.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/error_codes.yaml +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/errors.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/hitl/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/hitl/grant_protocol.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/hitl/mock.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/hitl/pending_approval.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/hitl/status.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/hook_integrity.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/hooks/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/hooks/tool_output_handler.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/hosted_policy.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/anthropic.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/autogen.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/braintrust.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/crewai/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/crewai/agent.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/crewai/crew.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/crewai/task.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/crewai/tool.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/google.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/google_adk/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/google_adk/agent.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/google_adk/tool.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/langchain/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/langchain/agent.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/langchain/callbacks.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/langchain/chain.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/langchain/graph.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/langchain/modern.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/langchain/tool.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/langfuse.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/litellm.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/openai.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/pydantic_ai.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/integrations/vercel_ai.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/layout_migration.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/policy_loader.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/secrets/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/secrets/reference.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/secrets/resolver.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/secrets/secretstr.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/_compress.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/_constants.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/_crc32c.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/_crypto.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/_frame.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/_keyring.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/_metrics.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/_spool.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/_state.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/_uploader.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/spool/cz-audit-v1.dict +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/tamper.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/controlzero/tracecontext.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/examples/hello_world.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/_fixtures/antigravity-envelope-expected.json +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/_fixtures/jcs_args_hash_vectors.json +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/conftest.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/fixtures/adapter-contracts/antigravity.json +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/fixtures/adapter-contracts/claude_code.json +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/fixtures/adapter-contracts/codex_cli.json +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/fixtures/adapter-contracts/cursor.json +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/fixtures/adapter-contracts/gemini_cli.json +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/fixtures/adapter-contracts/kiro.json +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/integrations/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/integrations/test_google.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/parity/action_aliases.json +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/__init__.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/conftest.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/test_spool_cli.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/test_spool_concurrency.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/test_spool_conformance.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/test_spool_core.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/test_spool_crash.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/test_spool_diskfull.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/test_spool_durable_default_tamper.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/test_spool_keychain_dek.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/test_spool_sink_wiring.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/test_spool_transcript_localack.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/spool/test_spool_uploader.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_action_aliases.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_action_canonicalization.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_action_validator_t86.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_adapter_contracts.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_adapter_interface.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_agent_name_env.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_agy_docs_no_exit2_1373.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_antigravity_adapter.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_antigravity_envelope_parity.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_antigravity_ga_blockers_1248.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_antigravity_hook_check.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_antigravity_install.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_antigravity_posttooluse_observe_58.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_antigravity_tool_vocab_1303.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_api_key_mask.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_audit_project_id_attribution_pr2.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_audit_remote.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_audit_remote_io_capture.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_audit_remote_sdk_version.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_audit_sink_isolation.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_bundle_cache_freshness_1303.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_bundle_parser.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_bundle_translate.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_canonical_phase1a.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_capability_matrix_doc.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cli_carve_out.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cli_debug_bundle.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cli_extractor_integration.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cli_hook.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cli_hook_entry.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cli_hosted_refresh.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cli_init.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cli_init_templates.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cli_tail.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cli_test.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cli_validate.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_coding_agent_hooks.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_condition_operators_1495.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_conditions.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_config_format_parity_1303.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_conformance.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_console.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_credential_hook.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cross_adapter_shell_enforcement.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_cursor_adapter.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_default_action.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_deny_rule_reconciliation_1011.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_deny_wins_default_catchall_1620.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_device.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_dlp_mask.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_dlp_scanner.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_doctor.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_engine_version_consistency.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_enrollment.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_env_dump_438.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_epic_1247_bryan_acceptance.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_error_codes.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_errors_e_codes.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_fail_closed_eval.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_failopen_1303.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_glob_matching.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_5d_email_install.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_6a_cli_flag.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_6a_exceptions.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_6a_get_secret_hitl.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_6a_mock_backend.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_6a_pending_approval.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_6a_wait.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_conformance.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_reason_codes.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hitl_validator_keys.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hook_extractors.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hook_integrity.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hook_mask_failclosed.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hosted_local_audit_1247.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hosted_local_shadow_warn_1265.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hosted_policy_e2e.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hybrid_mode_strict.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_hybrid_mode_warn.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_install_hook_command.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_install_hooks.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_io_capture_producer.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_kiro_adapter.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_kiro_cli_e2e.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_kiro_cli_hook_pin_1265.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_kiro_cli_v210_hooks.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_kiro_hook_templates.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_kiro_install.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_kiro_install_standardisation.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_layout_migration_t101.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_layout_parity_t102.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_local_mode_dict.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_local_mode_file_json.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_local_mode_file_yaml.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_localized_reason.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_log_fallback_stderr.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_log_options_ignored_hosted.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_log_rotation.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_migrate.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_min_sdk_version_gate.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_multi_client_per_project_175.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_no_policy_no_key.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_observe_mode_1247.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_package_rename_shim.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_part3_active_policy_count_1303.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_per_client_isolation_1011.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_policy_engine_version_phase1b.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_policy_freshness.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_policy_load_failclosed_f3.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_policy_settings.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_policy_source_audit.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_pr4_install_messaging.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_pr4_output.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_pr4_status.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_probe_audit_isolation.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_quarantine.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_reason_code.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_refresh.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_secrets.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_secrets_reference_resolver.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_shell_semantic_class.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_source_labels.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_sql_semantic_class.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_synthetic_policy_id_t79.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_t103_precedence.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_t104_cache_gc.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_t108_local_override_audit.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_t96_single_audit_log.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_t99_install_prefetch_bundle.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_tamper.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_tamper_behavior.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_tamper_hook.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_telemetry_consent.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_tracecontext.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_unsafe_int_boundary.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_update_cmd.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_upgrade_nudge.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tests/test_version_aware_fail_closed.py +0 -0
- {controlzero-1.13.4 → controlzero-1.13.5}/tools/cz-kiro-adapter +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: controlzero
|
|
3
|
-
Version: 1.13.
|
|
3
|
+
Version: 1.13.5
|
|
4
4
|
Summary: AI agent governance: policies, audit, and observability for tool calls. Works locally with no signup.
|
|
5
5
|
Project-URL: Homepage, https://controlzero.ai
|
|
6
6
|
Project-URL: Documentation, https://docs.controlzero.ai
|
|
@@ -35,6 +35,15 @@ from controlzero.cli.hosts.base import CoverageDecl, CZDecision, HostAdapter
|
|
|
35
35
|
# fail-open backstop).
|
|
36
36
|
_CODEX_CLI_CLIENTS = ("codex-cli", "codex_cli", "codex")
|
|
37
37
|
|
|
38
|
+
# Kiro CLI v3 is built on the Codex codebase and exports CODEX_HOME/CODEX_CLI.
|
|
39
|
+
# Its hooks send camelCase hook_event_name values (preToolUse, postToolUse,
|
|
40
|
+
# userPromptSubmit) -- byte-disjoint from Codex's PascalCase (PreToolUse).
|
|
41
|
+
# When we see a camelCase event, defer to KiroCLIAdapter rather than claiming
|
|
42
|
+
# the call based on CODEX_HOME/CODEX_CLI env hints alone (Bug #1655).
|
|
43
|
+
_KIRO_CLI_CAMEL_EVENTS = frozenset(
|
|
44
|
+
{"preToolUse", "postToolUse", "userPromptSubmit", "agentSpawn", "stop"}
|
|
45
|
+
)
|
|
46
|
+
|
|
38
47
|
|
|
39
48
|
class CodexCLIAdapter(HostAdapter):
|
|
40
49
|
name = "codex_cli"
|
|
@@ -66,6 +75,12 @@ class CodexCLIAdapter(HostAdapter):
|
|
|
66
75
|
# pinned host's adapter (not this one) claims the call.
|
|
67
76
|
if self._pinned_elsewhere(env, _CODEX_CLI_CLIENTS):
|
|
68
77
|
return False
|
|
78
|
+
# Kiro CLI exports CODEX_HOME/CODEX_CLI (built on Codex codebase) but
|
|
79
|
+
# sends camelCase hook_event_name values (preToolUse vs Codex's
|
|
80
|
+
# PascalCase PreToolUse). Defer to KiroCLIAdapter when we see a
|
|
81
|
+
# camelCase Kiro event so audit logs show "kiro_cli" not "codex_cli".
|
|
82
|
+
if isinstance(payload, dict) and payload.get("hook_event_name") in _KIRO_CLI_CAMEL_EVENTS:
|
|
83
|
+
return False
|
|
69
84
|
for hint in self._ENV_HINTS:
|
|
70
85
|
if env.get(hint):
|
|
71
86
|
return True
|
|
@@ -134,9 +134,17 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
134
134
|
file=sys.stderr,
|
|
135
135
|
)
|
|
136
136
|
return 0
|
|
137
|
+
# Upstream Kiro IDE bug #7375/#7408/#7500: preToolUse hooks receive
|
|
138
|
+
# USER_PROMPT={} with no tool context. The 'Control Zero - Pre Tool Use'
|
|
139
|
+
# hook in Kiro IDE settings ships DISABLED to prevent this. If you are
|
|
140
|
+
# seeing this message, you have enabled that hook. Disable it in Kiro
|
|
141
|
+
# IDE Settings > Hooks to restore normal tool execution.
|
|
137
142
|
print(
|
|
138
|
-
"controlzero(kiro): empty
|
|
139
|
-
"(
|
|
143
|
+
f"controlzero(kiro): {event} hook received empty payload "
|
|
144
|
+
"(upstream Kiro IDE bug #7375/#7408/#7500 -- preToolUse delivers "
|
|
145
|
+
"USER_PROMPT={}). Failing closed. FIX: disable the "
|
|
146
|
+
"'Control Zero - Pre Tool Use' hook in Kiro IDE Settings > Hooks. "
|
|
147
|
+
"Set CZ_KIRO_UNKNOWN_PAYLOAD=open in the hook env to allow instead.",
|
|
140
148
|
file=sys.stderr,
|
|
141
149
|
)
|
|
142
150
|
return 2
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"enabled": false,
|
|
3
|
+
"name": "Control Zero - Pre Tool Use [DO NOT ENABLE: blocks all tool calls]",
|
|
4
|
+
"description": "WARNING: DO NOT ENABLE THIS HOOK. Upstream Kiro IDE bug #7375/#7408/#7500: preToolUse hooks receive empty tool context (USER_PROMPT={}). With no context this hook fails closed and blocks EVERY tool call. If you enabled this hook and Kiro is now blocking all tools, disable it here immediately. The 'Pre Tool Use' event type is correct for pre-tool governance -- this hook is disabled until Kiro ships the fix. The Kiro CLI preToolUse surface works correctly and governs tool calls by default. Re-enable only after Kiro IDE delivers tool args to preToolUse hooks (or set CZ_KIRO_UNKNOWN_PAYLOAD=open in the hook environment to accept reduced governance). See docs/integrations/kiro.md.",
|
|
5
|
+
"version": "1",
|
|
6
|
+
"when": {
|
|
7
|
+
"type": "preToolUse",
|
|
8
|
+
"toolTypes": ["*"]
|
|
9
|
+
},
|
|
10
|
+
"then": {
|
|
11
|
+
"type": "runCommand",
|
|
12
|
+
"command": "cz-kiro-adapter preToolUse",
|
|
13
|
+
"timeout": 5
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -59,6 +59,7 @@ from controlzero.errors import (
|
|
|
59
59
|
HybridModeError,
|
|
60
60
|
PolicyLoadError,
|
|
61
61
|
PolicyValidationError,
|
|
62
|
+
SecretValueLeakInPayload,
|
|
62
63
|
)
|
|
63
64
|
from controlzero.hitl import raise_on_leak
|
|
64
65
|
from controlzero.policy_loader import load_policy, PolicySettings
|
|
@@ -709,7 +710,7 @@ class Client:
|
|
|
709
710
|
"X-CZ-Requestor-Email": email,
|
|
710
711
|
}
|
|
711
712
|
|
|
712
|
-
url = f"{get_api_url()}/
|
|
713
|
+
url = f"{get_api_url()}/v1/sdk/approval-requests"
|
|
713
714
|
|
|
714
715
|
try:
|
|
715
716
|
resp = httpx.post(url, json=body, headers=headers, timeout=10.0)
|
|
@@ -1051,7 +1052,7 @@ class Client:
|
|
|
1051
1052
|
"get_secret_poll_fn requires an API key"
|
|
1052
1053
|
)
|
|
1053
1054
|
|
|
1054
|
-
url = f"{get_api_url()}/
|
|
1055
|
+
url = f"{get_api_url()}/v1/sdk/approval-requests/{request_id}"
|
|
1055
1056
|
headers = {
|
|
1056
1057
|
"Authorization": f"Bearer {self._api_key}",
|
|
1057
1058
|
"Accept": "application/json",
|
|
@@ -1401,6 +1402,11 @@ class Client:
|
|
|
1401
1402
|
except GrantProtocolError as exc:
|
|
1402
1403
|
# denied / expired / revoked / timeout / backend-unreachable
|
|
1403
1404
|
return self._synthetic_grant_deny(exc.reason_code, str(exc))
|
|
1405
|
+
except SecretValueLeakInPayload:
|
|
1406
|
+
# A secret-shaped value in the grant reason/payload is a caller/security
|
|
1407
|
+
# error, NOT a backend outage. Surface E1709 clearly instead of a synthetic
|
|
1408
|
+
# DENY mislabeled HITL_BACKEND_UNREACHABLE.
|
|
1409
|
+
raise
|
|
1404
1410
|
except Exception: # noqa: BLE001
|
|
1405
1411
|
# Defense-in-depth: any unanticipated error still fails
|
|
1406
1412
|
# closed rather than leaking an allow.
|
|
@@ -141,7 +141,11 @@ def is_likely_secret_value(value: str) -> bool:
|
|
|
141
141
|
return True
|
|
142
142
|
|
|
143
143
|
# Length + entropy floor.
|
|
144
|
-
|
|
144
|
+
# A real credential is a single contiguous token. Natural-language reason/message
|
|
145
|
+
# text contains whitespace and must NOT trip the value-leak scan (E1709 false
|
|
146
|
+
# positive on e.g. the default reason "function requires approval"). Genuine secrets
|
|
147
|
+
# embedded in an arg value are contiguous, so this keeps recall on real credentials.
|
|
148
|
+
if len(value) >= _ENTROPY_LEN_FLOOR and not any(ch.isspace() for ch in value):
|
|
145
149
|
if _shannon_entropy(value) > _ENTROPY_BITS_PER_CHAR_FLOOR:
|
|
146
150
|
return True
|
|
147
151
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "controlzero"
|
|
7
|
-
version = "1.13.
|
|
7
|
+
version = "1.13.5"
|
|
8
8
|
description = "AI agent governance: policies, audit, and observability for tool calls. Works locally with no signup."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "Apache-2.0"}
|
|
@@ -207,7 +207,7 @@ class TestHappyPath:
|
|
|
207
207
|
assert kwargs["headers"]["X-CZ-Requestor-Email"] == "alice@example.com"
|
|
208
208
|
assert kwargs["headers"]["Content-Type"] == "application/json"
|
|
209
209
|
assert post.call_args[0][0] == (
|
|
210
|
-
"https://api.fake.test/
|
|
210
|
+
"https://api.fake.test/v1/sdk/approval-requests"
|
|
211
211
|
)
|
|
212
212
|
|
|
213
213
|
body = kwargs["json"]
|
|
@@ -65,6 +65,14 @@ class TestIsLikelySecretValue:
|
|
|
65
65
|
assert len(value) == 32
|
|
66
66
|
assert is_likely_secret_value(value) is True
|
|
67
67
|
|
|
68
|
+
def test_natural_language_reasons_return_false(self):
|
|
69
|
+
for value in (
|
|
70
|
+
"function requires approval",
|
|
71
|
+
"requested by SDK",
|
|
72
|
+
"please approve deploying the billing service to production",
|
|
73
|
+
):
|
|
74
|
+
assert is_likely_secret_value(value) is False
|
|
75
|
+
|
|
68
76
|
def test_sk_prefix_returns_true(self):
|
|
69
77
|
# Short on purpose: prefix check must fire even when the
|
|
70
78
|
# entropy floor wouldn't.
|
|
@@ -33,6 +33,8 @@ import httpx
|
|
|
33
33
|
import pytest
|
|
34
34
|
import respx
|
|
35
35
|
|
|
36
|
+
from controlzero.errors import SecretValueLeakInPayload
|
|
37
|
+
|
|
36
38
|
import controlzero.audit_remote as audit_remote_module
|
|
37
39
|
from controlzero import Client
|
|
38
40
|
from controlzero.hitl import grant_protocol as gp
|
|
@@ -319,6 +321,23 @@ def _approval_decision(client, monkeypatch):
|
|
|
319
321
|
monkeypatch.setattr(client, "guard", _fake_guard)
|
|
320
322
|
|
|
321
323
|
|
|
324
|
+
def _approval_decision_with_reason(client, monkeypatch, reason):
|
|
325
|
+
from controlzero._internal.enforcer import PolicyDecision
|
|
326
|
+
|
|
327
|
+
def _fake_guard(tool, args=None, method="*", raise_on_deny=False, context=None):
|
|
328
|
+
d = PolicyDecision(
|
|
329
|
+
effect="deny",
|
|
330
|
+
policy_id="rule:hitl:1",
|
|
331
|
+
reason=reason,
|
|
332
|
+
reason_code="HITL_REQUIRES_APPROVAL",
|
|
333
|
+
)
|
|
334
|
+
d.requires_approval = True
|
|
335
|
+
d.approval_action = "delete_file"
|
|
336
|
+
return d
|
|
337
|
+
|
|
338
|
+
monkeypatch.setattr(client, "guard", _fake_guard)
|
|
339
|
+
|
|
340
|
+
|
|
322
341
|
@pytest.mark.asyncio
|
|
323
342
|
async def test_guard_with_approval_backward_compat_no_hitl(monkeypatch, tmp_path):
|
|
324
343
|
# When guard() returns no requires_approval, the result is the
|
|
@@ -339,6 +358,41 @@ async def test_guard_with_approval_post_fails_denies(monkeypatch, tmp_path):
|
|
|
339
358
|
assert decision.reason_code == "HITL_BACKEND_UNREACHABLE"
|
|
340
359
|
|
|
341
360
|
|
|
361
|
+
@pytest.mark.asyncio
|
|
362
|
+
async def test_guard_with_approval_default_reason_does_not_raise_e1709(monkeypatch, tmp_path):
|
|
363
|
+
client = _make_client(monkeypatch, tmp_path)
|
|
364
|
+
_approval_decision_with_reason(client, monkeypatch, "function requires approval")
|
|
365
|
+
with respx.mock(base_url=_API_URL) as mock:
|
|
366
|
+
mock.post("/api/grants").mock(
|
|
367
|
+
return_value=httpx.Response(200, json={"grant_id": "g1"})
|
|
368
|
+
)
|
|
369
|
+
mock.get("/api/grants/g1").mock(
|
|
370
|
+
return_value=httpx.Response(200, json={"state": "approved"})
|
|
371
|
+
)
|
|
372
|
+
decision = await client.guard_with_approval(
|
|
373
|
+
"delete_file", {"p": 1}, retry_guard=False
|
|
374
|
+
)
|
|
375
|
+
assert decision.effect == "allow"
|
|
376
|
+
assert decision.reason_code == "HITL_GRANT_APPROVED"
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
@pytest.mark.asyncio
|
|
380
|
+
async def test_guard_with_approval_secret_leak_raises_e1709(monkeypatch, tmp_path):
|
|
381
|
+
client = _make_client(monkeypatch, tmp_path)
|
|
382
|
+
_approval_decision_with_reason(
|
|
383
|
+
client,
|
|
384
|
+
monkeypatch,
|
|
385
|
+
"0123456789abcdef0123456789abcdef",
|
|
386
|
+
)
|
|
387
|
+
with respx.mock(base_url=_API_URL, assert_all_called=False) as mock:
|
|
388
|
+
post = mock.post("/api/grants").mock(
|
|
389
|
+
return_value=httpx.Response(200, json={"grant_id": "g1"})
|
|
390
|
+
)
|
|
391
|
+
with pytest.raises(SecretValueLeakInPayload):
|
|
392
|
+
await client.guard_with_approval("delete_file", {"p": 1})
|
|
393
|
+
assert post.call_count == 0
|
|
394
|
+
|
|
395
|
+
|
|
342
396
|
@pytest.mark.asyncio
|
|
343
397
|
async def test_guard_with_approval_denied(monkeypatch, tmp_path):
|
|
344
398
|
client = _make_client(monkeypatch, tmp_path)
|
|
@@ -124,6 +124,49 @@ class TestCodexCLIClaim:
|
|
|
124
124
|
def test_claims_via_codex_home_env(self):
|
|
125
125
|
assert CodexCLIAdapter().claim({}, env={"CODEX_HOME": "/x"})
|
|
126
126
|
|
|
127
|
+
def test_claims_via_codex_cli_env(self):
|
|
128
|
+
assert CodexCLIAdapter().claim({}, env={"CODEX_CLI": "1"})
|
|
129
|
+
|
|
130
|
+
def test_does_NOT_claim_kiro_camel_pretooluse_even_with_codex_home(self):
|
|
131
|
+
# Bug #1655 regression: Kiro CLI exports CODEX_HOME (built on Codex)
|
|
132
|
+
# but sends camelCase preToolUse. CodexCLI must defer so KiroCLI claims
|
|
133
|
+
# and audit logs show "kiro_cli" not "codex_cli".
|
|
134
|
+
kiro_payload = {
|
|
135
|
+
"hook_event_name": "preToolUse",
|
|
136
|
+
"tool_name": "execute_bash",
|
|
137
|
+
"tool_input": {"command": "ls"},
|
|
138
|
+
}
|
|
139
|
+
assert not CodexCLIAdapter().claim(kiro_payload, env={"CODEX_HOME": "/home/x/.kiro/kiro-cli"})
|
|
140
|
+
|
|
141
|
+
def test_does_NOT_claim_kiro_camel_posttooluse_even_with_codex_home(self):
|
|
142
|
+
kiro_payload = {"hook_event_name": "postToolUse", "tool_name": "execute_bash"}
|
|
143
|
+
assert not CodexCLIAdapter().claim(kiro_payload, env={"CODEX_HOME": "/x"})
|
|
144
|
+
|
|
145
|
+
def test_does_NOT_claim_kiro_user_prompt_submit_even_with_codex_home(self):
|
|
146
|
+
kiro_payload = {"hook_event_name": "userPromptSubmit", "prompt": "hi"}
|
|
147
|
+
assert not CodexCLIAdapter().claim(kiro_payload, env={"CODEX_HOME": "/x"})
|
|
148
|
+
|
|
149
|
+
def test_kiro_camel_payload_picks_kiro_adapter_not_codex(self):
|
|
150
|
+
# Integration: select_adapter must pick KiroCLIAdapter for a camelCase
|
|
151
|
+
# Kiro payload even when CODEX_HOME is present in env.
|
|
152
|
+
kiro_payload = {
|
|
153
|
+
"hook_event_name": "preToolUse",
|
|
154
|
+
"tool_name": "execute_bash",
|
|
155
|
+
"tool_input": {"command": "rm -rf /"},
|
|
156
|
+
}
|
|
157
|
+
adapter = select_adapter(kiro_payload, env={"CODEX_HOME": "/home/x/.kiro"})
|
|
158
|
+
assert isinstance(adapter, KiroCLIAdapter)
|
|
159
|
+
assert adapter.canonical_source == "kiro_cli"
|
|
160
|
+
|
|
161
|
+
def test_codex_pascal_pretooluse_still_claims_with_codex_home(self):
|
|
162
|
+
# PascalCase PreToolUse is Codex's own event shape -- must still claim.
|
|
163
|
+
codex_payload = {
|
|
164
|
+
"hook_event_name": "PreToolUse",
|
|
165
|
+
"tool_name": "Bash",
|
|
166
|
+
"tool_input": {"command": "ls"},
|
|
167
|
+
}
|
|
168
|
+
assert CodexCLIAdapter().claim(codex_payload, env={"CODEX_HOME": "/x"})
|
|
169
|
+
|
|
127
170
|
|
|
128
171
|
class TestUnknownClaim:
|
|
129
172
|
def test_always_claims(self):
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"enabled": false,
|
|
3
|
-
"name": "Control Zero - Pre Tool Use (disabled: upstream Kiro IDE bug)",
|
|
4
|
-
"description": "Control Zero governance: evaluate every Kiro tool call against your policy BEFORE it runs. SHIPPED DISABLED on the IDE surface because upstream Kiro (#7375/#7408/#7500, IDE v0.11) delivers an empty USER_PROMPT={} to IDE preToolUse runCommand hooks -- with no tool context the adapter cannot make an informed allow decision and, fail-closed (CZ_KIRO_UNKNOWN_PAYLOAD=closed), would block EVERY tool call. Enable this hook ONLY after upstream ships the tool-context fix (or set CZ_KIRO_UNKNOWN_PAYLOAD=open to accept the loss of pre-tool policy). The Kiro CLI preToolUse surface is full-fidelity and is wired by default. See docs/integrations/kiro.md.",
|
|
5
|
-
"version": "1",
|
|
6
|
-
"when": {
|
|
7
|
-
"type": "preToolUse",
|
|
8
|
-
"toolTypes": ["*"]
|
|
9
|
-
},
|
|
10
|
-
"then": {
|
|
11
|
-
"type": "runCommand",
|
|
12
|
-
"command": "cz-kiro-adapter preToolUse",
|
|
13
|
-
"timeout": 5
|
|
14
|
-
}
|
|
15
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/credentials_data/__init__.py
RENAMED
|
File without changes
|
{controlzero-1.13.4 → controlzero-1.13.5}/controlzero/_internal/credentials_data/built_in.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/kiro/ide-file-save.kiro.hook
RENAMED
|
File without changes
|
{controlzero-1.13.4 → controlzero-1.13.5}/controlzero/cli/templates/kiro/ide-prompt-submit.kiro.hook
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|