diff --git a/CHANGELOG.md b/CHANGELOG.md index da00ab1..7d7fc9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,20 @@ project uses [Semantic Versioning](https://semver.org/). ## [Unreleased] +## [0.6.3] - 2026-10-30 + +The Action is listed on GitHub Marketplace as "ControlLoop Security". The +CLI is unchanged. + +### Changed + +- **The Action's name is `ControlLoop Security`**, which is what + Marketplace shows, instead of `ControlLoop gate`. Plain `ControlLoop` + isn't available: Marketplace refuses a name that matches another + account, and the `controlloop` organization is not this project's. + Workflows reference the Action by repository and tag, so nothing that + uses it changes. + ### Added - **`controlloop mcp`, a local MCP server.** An agent host that speaks MCP diff --git a/README.md b/README.md index 1e5ea9d..b9d38d7 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ In a container, with no network: ```bash docker run --rm --network none -v "$PWD:/work:ro" \ - ghcr.io/controlloop-security/controlloop:0.6.2 scan /work + ghcr.io/controlloop-security/controlloop:0.6.3 scan /work ``` Every install path, with its verification step, is in @@ -162,7 +162,7 @@ uv run controlloop --version ``` ```text -ControlLoop 0.6.2 +ControlLoop 0.6.3 Supported OASF versions: none yet Agent host key sets (documentation read on): claude-code 2026-10-17, codex 2026-10-17, cursor 2026-10-17, gemini-cli 2026-10-17, kiro 2026-10-17, roo-code 2026-10-29 Rule pack: controlloop-community 0.9.0 (24 rules) @@ -523,7 +523,7 @@ controlloop rules - uses: actions/checkout@v7.0.1 with: fetch-depth: 0 # gate needs real history for a baseline -- uses: controlloop-security/controlloop@v0.6.2 # a release tag or commit SHA +- uses: controlloop-security/controlloop@v0.6.3 # a release tag or commit SHA with: path: ${{ github.workspace }} ``` diff --git a/action.yml b/action.yml index 37604e0..48c64aa 100644 --- a/action.yml +++ b/action.yml @@ -12,7 +12,7 @@ # `description` is what GitHub Marketplace lists, and Marketplace refuses # one of 125 characters or more; tests/test_action_metadata.py holds it # under that. -name: ControlLoop gate +name: ControlLoop Security description: >- Block pull requests that widen what an AI agent can do, from agent configs, MCP servers and framework code. diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index 6e31a96..71ff83d 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -61,7 +61,7 @@ controlloop --version ``` ```text -ControlLoop 0.6.2 +ControlLoop 0.6.3 Supported OASF versions: none yet Agent host key sets (documentation read on): claude-code 2026-10-17, codex 2026-10-17, cursor 2026-10-17, gemini-cli 2026-10-17, kiro 2026-10-17, roo-code 2026-10-29 Rule pack: controlloop-community 0.9.0 (24 rules) @@ -162,7 +162,7 @@ docker run --rm --network none -v "$PWD:/work:ro" \ Verify by running it with `--version` in place of `scan /work`. The image is published for every tagged release, tagged by exact version only -(`0.6.2`, not `latest`); the release notes record +(`0.6.3`, not `latest`); the release notes record its digest, and `gh attestation verify oci://ghcr.io/controlloop-security/controlloop: --repo controlloop-security/controlloop` checks its provenance. What is in the diff --git a/docs/reference/marketplace-listing.md b/docs/reference/marketplace-listing.md index 57166d6..79b54cd 100644 --- a/docs/reference/marketplace-listing.md +++ b/docs/reference/marketplace-listing.md @@ -12,9 +12,9 @@ updated: 2026-10-30 # Action marketplace listing **The GitHub Action is listed on GitHub Marketplace** as -[ControlLoop gate](https://github.com/marketplace/actions/controlloop-gate), -from release `v0.6.2`. It works from any workflow -(`uses: controlloop-security/controlloop@v0.6.2`); the listing makes it +[ControlLoop Security](https://github.com/marketplace/actions/controlloop-gate), +from release `v0.6.3`. It works from any workflow +(`uses: controlloop-security/controlloop@v0.6.3`); the listing makes it discoverable from Marketplace search. This page records what is prepared and the steps a maintainer takes to publish it. @@ -26,7 +26,7 @@ From GitHub's [publishing guide](https://docs.github.com/en/actions/how-tos/crea | --- | --- | | The repository is public | Yes | | One action metadata file, at the root | `action.yml` | -| A unique `name` that matches no existing action, category, user, or organization | `ControlLoop gate` | +| A unique `name` that matches no existing action, category, user, or organization | `ControlLoop Security`. Plain `ControlLoop` is refused: it matches the `controlloop` organization, which is not this project's. | | A `description` shorter than 125 characters | 107 characters, held under the limit by `tests/test_action_metadata.py` | | The owning account accepts the GitHub Marketplace Developer Agreement | A maintainer does this once, in the publish form | | Two-factor authentication on the publishing account | Required when the release is published | @@ -45,7 +45,7 @@ releases for `controlloop-security/controlloop`. It is public, and the listing stays up until a maintainer removes it. 1. Open the release to list, for example - `https://github.com/controlloop-security/controlloop/releases/tag/v0.6.2`, + `https://github.com/controlloop-security/controlloop/releases/tag/v0.6.3`, and choose **Edit** (for a new release, start from **Draft a new release**). 2. Under **Release action**, check **Publish this Action to the GitHub @@ -82,7 +82,7 @@ own. (A `vMAJOR` tag like `v1` has no dot, so it could never match this workflow's own `v*.*.*` trigger glob and re-trigger a release -- but the invariant is broader than self-triggering risk, so it is kept intact.) -Release tags `v0.1.1` through `v0.6.2` exist (`v0.6.1` was tagged but +Release tags `v0.1.1` through `v0.6.3` exist (`v0.6.1` was tagged but never published). No floating tag exists yet, and none is needed before 1.0: during `0.x` every minor release may change behavior, so consumers should pin an exact tag. From `v1.0.0` on, diff --git a/docs/reference/pre-commit-hook.md b/docs/reference/pre-commit-hook.md index f6c8b5e..f1f06de 100644 --- a/docs/reference/pre-commit-hook.md +++ b/docs/reference/pre-commit-hook.md @@ -21,14 +21,14 @@ stays in verdict-parity with CI. against [pre-commit](https://pre-commit.com)'s own official manifest schema and was exercised end to end with `pre-commit try-repo` while this page was written. Pin `rev:` to a release tag (`v0.1.1` through -`v0.6.2` exist) or a commit SHA. +`v0.6.3` exist) or a commit SHA. ## Minimal usage ```yaml repos: - repo: https://github.com/controlloop-security/controlloop - rev: v0.6.2 # a release tag or commit SHA, never an unpinned/"latest" ref + rev: v0.6.3 # a release tag or commit SHA, never an unpinned/"latest" ref hooks: - id: controlloop-gate ``` diff --git a/pyproject.toml b/pyproject.toml index 8e934f4..0cc6093 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "controlloop" -version = "0.6.2" +version = "0.6.3" description = "Local-first security scanner and deterministic CI gate for AI agents" license = "Apache-2.0" license-files = ["LICENSE", "NOTICE"] diff --git a/tests/fixtures/golden/agent-with-ceiling-breach/acbom.json b/tests/fixtures/golden/agent-with-ceiling-breach/acbom.json index da32807..4ee17d6 100644 --- a/tests/fixtures/golden/agent-with-ceiling-breach/acbom.json +++ b/tests/fixtures/golden/agent-with-ceiling-breach/acbom.json @@ -1 +1 @@ -{"diagnostics":[],"digest":"sha256:b5134f82db04f012df942b2cbe8f9ef0350f2413e057db6c5ea933f9633fa51b","edges":[{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:edge:sha256:d6141860d347281ceeb951eef4be8481c1c50ce2e4c9345bdb0858a4c40b938b","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"source":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","status":"direct","target":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","type":"invokes"}],"generator":{"name":"controlloop","version":"0.6.2"},"nodes":[{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","name":"refund-agent","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"standards_identifiers":[],"subtype":"a2a-agent-card","type":"agent"},{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","name":"delete-database","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"standards_identifiers":[],"subtype":"a2a-skill","type":"tool"}],"repository":{"commit":"unknown","root_digest":"sha256:894ae1959cd35ccc1a3be5b96d4867df4db18c16e6f4b5d4b6ef495fba7d1db9"},"schema_url":"https://schemas.controlloop.ai/acbom/1.2.0/acbom.schema.json","schema_version":"1.2.0"} +{"diagnostics":[],"digest":"sha256:7062c91c59b61d8ad8030003e580cd9a58e64c2e4ae820140a31f53284e1e2b4","edges":[{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:edge:sha256:d6141860d347281ceeb951eef4be8481c1c50ce2e4c9345bdb0858a4c40b938b","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"source":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","status":"direct","target":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","type":"invokes"}],"generator":{"name":"controlloop","version":"0.6.3"},"nodes":[{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","name":"refund-agent","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"standards_identifiers":[],"subtype":"a2a-agent-card","type":"agent"},{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","name":"delete-database","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"standards_identifiers":[],"subtype":"a2a-skill","type":"tool"}],"repository":{"commit":"unknown","root_digest":"sha256:894ae1959cd35ccc1a3be5b96d4867df4db18c16e6f4b5d4b6ef495fba7d1db9"},"schema_url":"https://schemas.controlloop.ai/acbom/1.2.0/acbom.schema.json","schema_version":"1.2.0"} diff --git a/tests/fixtures/golden/agent-with-ceiling-breach/report.json b/tests/fixtures/golden/agent-with-ceiling-breach/report.json index 593c0a9..7714e4d 100644 --- a/tests/fixtures/golden/agent-with-ceiling-breach/report.json +++ b/tests/fixtures/golden/agent-with-ceiling-breach/report.json @@ -1 +1 @@ -{"schema_version":"1.2.0","verdict":"deployment_blocked","blast_radius":null,"material_changes":null,"findings":[{"schema_version":"1.1.0","id":"clp:finding:sha256:3935140e086b822efa69acf29b22d5c050493d7076aaf9c528a9e61fa24fd85b","rule_id":"policy.capability-ceiling","rule_version":"1.0.0","message":"agent 'refund-agent' reaches 'delete-database', which is a prohibited resource or external destination under its capability ceiling","severity":"critical","confidence":"high","affected_agent":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","evidence":[{"adapter":"a2a","path":"agent-card.json","line_start":null,"line_end":null,"parser":null,"schema_id":null,"document_digest":null}],"capability_path":{"schema_version":"1.0.0","agent_id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","target_id":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","target_type":"tool","hops":[{"edge_id":"clp:edge:sha256:d6141860d347281ceeb951eef4be8481c1c50ce2e4c9345bdb0858a4c40b938b","edge_type":"invokes","source_id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","target_id":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","evidence":[{"adapter":"a2a","path":"agent-card.json","line_start":null,"line_end":null,"parser":null,"schema_id":null,"document_digest":null}]}],"confidence":"high"},"change_state":"not-compared","remediation":"narrow the discovered capability, or update the declared capability ceiling in controlloop.yaml if this authority is intended","documentation_url":"https://docs.controlloop.ai/reference/policy-rules#capability-ceiling"},{"schema_version":"1.1.0","id":"clp:finding:sha256:a86cb3610b02da19fc10d433fe4416d4161e0c529da47d146a8081f6f7de9e71","rule_id":"policy.undeclared-tools","rule_version":"1.0.0","message":"Tool 'delete-database' is reachable but not declared in controlloop.yaml.","severity":"medium","confidence":"high","affected_agent":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","evidence":[{"adapter":"a2a","path":"agent-card.json","line_start":null,"line_end":null,"parser":null,"schema_id":null,"document_digest":null}],"capability_path":{"schema_version":"1.0.0","agent_id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","target_id":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","target_type":"tool","hops":[{"edge_id":"clp:edge:sha256:d6141860d347281ceeb951eef4be8481c1c50ce2e4c9345bdb0858a4c40b938b","edge_type":"invokes","source_id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","target_id":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","evidence":[{"adapter":"a2a","path":"agent-card.json","line_start":null,"line_end":null,"parser":null,"schema_id":null,"document_digest":null}]}],"confidence":"high"},"change_state":"not-compared","remediation":"Declare this tool in controlloop.yaml (for example, an approvals entry naming its capability), or remove the agent's access to it if it was not intentional.","documentation_url":"https://docs.controlloop.ai/reference/policy-rules#undeclared-tools"}],"diagnostics":[],"suppressions":[],"versions":{"scanner":{"name":"controlloop","version":"0.6.2"},"acbom_schema_version":"1.2.0","report_schema_version":"1.2.0","policy_version":"0.9.0"}} +{"schema_version":"1.2.0","verdict":"deployment_blocked","blast_radius":null,"material_changes":null,"findings":[{"schema_version":"1.1.0","id":"clp:finding:sha256:3935140e086b822efa69acf29b22d5c050493d7076aaf9c528a9e61fa24fd85b","rule_id":"policy.capability-ceiling","rule_version":"1.0.0","message":"agent 'refund-agent' reaches 'delete-database', which is a prohibited resource or external destination under its capability ceiling","severity":"critical","confidence":"high","affected_agent":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","evidence":[{"adapter":"a2a","path":"agent-card.json","line_start":null,"line_end":null,"parser":null,"schema_id":null,"document_digest":null}],"capability_path":{"schema_version":"1.0.0","agent_id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","target_id":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","target_type":"tool","hops":[{"edge_id":"clp:edge:sha256:d6141860d347281ceeb951eef4be8481c1c50ce2e4c9345bdb0858a4c40b938b","edge_type":"invokes","source_id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","target_id":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","evidence":[{"adapter":"a2a","path":"agent-card.json","line_start":null,"line_end":null,"parser":null,"schema_id":null,"document_digest":null}]}],"confidence":"high"},"change_state":"not-compared","remediation":"narrow the discovered capability, or update the declared capability ceiling in controlloop.yaml if this authority is intended","documentation_url":"https://docs.controlloop.ai/reference/policy-rules#capability-ceiling"},{"schema_version":"1.1.0","id":"clp:finding:sha256:a86cb3610b02da19fc10d433fe4416d4161e0c529da47d146a8081f6f7de9e71","rule_id":"policy.undeclared-tools","rule_version":"1.0.0","message":"Tool 'delete-database' is reachable but not declared in controlloop.yaml.","severity":"medium","confidence":"high","affected_agent":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","evidence":[{"adapter":"a2a","path":"agent-card.json","line_start":null,"line_end":null,"parser":null,"schema_id":null,"document_digest":null}],"capability_path":{"schema_version":"1.0.0","agent_id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","target_id":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","target_type":"tool","hops":[{"edge_id":"clp:edge:sha256:d6141860d347281ceeb951eef4be8481c1c50ce2e4c9345bdb0858a4c40b938b","edge_type":"invokes","source_id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","target_id":"clp:tool:sha256:f7824d54df66d9cf3b619974e61d0c003c85cafe2e1e019b2f960ab4f6844771","evidence":[{"adapter":"a2a","path":"agent-card.json","line_start":null,"line_end":null,"parser":null,"schema_id":null,"document_digest":null}]}],"confidence":"high"},"change_state":"not-compared","remediation":"Declare this tool in controlloop.yaml (for example, an approvals entry naming its capability), or remove the agent's access to it if it was not intentional.","documentation_url":"https://docs.controlloop.ai/reference/policy-rules#undeclared-tools"}],"diagnostics":[],"suppressions":[],"versions":{"scanner":{"name":"controlloop","version":"0.6.3"},"acbom_schema_version":"1.2.0","report_schema_version":"1.2.0","policy_version":"0.9.0"}} diff --git a/tests/fixtures/golden/empty/acbom.json b/tests/fixtures/golden/empty/acbom.json index 7b37e10..e0c7c65 100644 --- a/tests/fixtures/golden/empty/acbom.json +++ b/tests/fixtures/golden/empty/acbom.json @@ -1 +1 @@ -{"diagnostics":[],"digest":"sha256:bec64aca873343c93a3eb62772629b3e9fd2e5deba575c6a99a52e740da25465","edges":[],"generator":{"name":"controlloop","version":"0.6.2"},"nodes":[],"repository":{"commit":"unknown","root_digest":"sha256:b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5"},"schema_url":"https://schemas.controlloop.ai/acbom/1.2.0/acbom.schema.json","schema_version":"1.2.0"} +{"diagnostics":[],"digest":"sha256:67edd7e34fcfe9f0354561ede6247fe8126492237e83ea60e43f9d58b23e657a","edges":[],"generator":{"name":"controlloop","version":"0.6.3"},"nodes":[],"repository":{"commit":"unknown","root_digest":"sha256:b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5"},"schema_url":"https://schemas.controlloop.ai/acbom/1.2.0/acbom.schema.json","schema_version":"1.2.0"} diff --git a/tests/fixtures/golden/empty/report.json b/tests/fixtures/golden/empty/report.json index 7575e80..1770f44 100644 --- a/tests/fixtures/golden/empty/report.json +++ b/tests/fixtures/golden/empty/report.json @@ -1 +1 @@ -{"schema_version":"1.2.0","verdict":"passed","blast_radius":null,"material_changes":null,"findings":[],"diagnostics":[],"suppressions":[],"versions":{"scanner":{"name":"controlloop","version":"0.6.2"},"acbom_schema_version":"1.2.0","report_schema_version":"1.2.0","policy_version":"0.9.0"}} +{"schema_version":"1.2.0","verdict":"passed","blast_radius":null,"material_changes":null,"findings":[],"diagnostics":[],"suppressions":[],"versions":{"scanner":{"name":"controlloop","version":"0.6.3"},"acbom_schema_version":"1.2.0","report_schema_version":"1.2.0","policy_version":"0.9.0"}} diff --git a/tests/fixtures/golden/single-agent/acbom.json b/tests/fixtures/golden/single-agent/acbom.json index 9b72d2d..6f105a0 100644 --- a/tests/fixtures/golden/single-agent/acbom.json +++ b/tests/fixtures/golden/single-agent/acbom.json @@ -1 +1 @@ -{"diagnostics":[],"digest":"sha256:8e9f5aa498be9ffb8a9a084c54338115c20adc482c67277cf7c133a9359978c8","edges":[{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:edge:sha256:1e647ca1e3230f61420ca74f32c82a744624d4e9a458d939e0597b1f9c06b911","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"source":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","status":"direct","target":"clp:tool:sha256:a8f98a1f311be1470ece2ab461946b0d7429a57e1ab8d6da3d87195e7b6d379b","type":"invokes"}],"generator":{"name":"controlloop","version":"0.6.2"},"nodes":[{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","name":"librarian","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"standards_identifiers":[],"subtype":"a2a-agent-card","type":"agent"},{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:tool:sha256:a8f98a1f311be1470ece2ab461946b0d7429a57e1ab8d6da3d87195e7b6d379b","name":"search-catalog","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"standards_identifiers":[],"subtype":"a2a-skill","type":"tool"}],"repository":{"commit":"unknown","root_digest":"sha256:ae3be7cb2590e86355334c34b65958487f8888ab712982528a18ae49fd4733a4"},"schema_url":"https://schemas.controlloop.ai/acbom/1.2.0/acbom.schema.json","schema_version":"1.2.0"} +{"diagnostics":[],"digest":"sha256:1d71c5c0600803c7a0b1bb740e843a29b000dac1c2f7fc7e9f7260c8cbdfbf3a","edges":[{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:edge:sha256:1e647ca1e3230f61420ca74f32c82a744624d4e9a458d939e0597b1f9c06b911","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"source":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","status":"direct","target":"clp:tool:sha256:a8f98a1f311be1470ece2ab461946b0d7429a57e1ab8d6da3d87195e7b6d379b","type":"invokes"}],"generator":{"name":"controlloop","version":"0.6.3"},"nodes":[{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:agent:sha256:2321fe51daefbeccc66dac2ae3e63aa0237216db27510216a9f61c3faf760cf9","name":"librarian","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"standards_identifiers":[],"subtype":"a2a-agent-card","type":"agent"},{"confidence":"high","evidence":[{"adapter":"a2a","document_digest":null,"line_end":null,"line_start":null,"parser":null,"path":"agent-card.json","schema_id":null}],"id":"clp:tool:sha256:a8f98a1f311be1470ece2ab461946b0d7429a57e1ab8d6da3d87195e7b6d379b","name":"search-catalog","security_attributes":{"approval_present":null,"code_execution":null,"data_classifications":[],"destructive":null,"external_communication":null,"financial_action":null,"permission_scopes":[],"privileged":null,"read_only":null,"requires_approval":null,"sensitivity":null,"trusted":null},"standards_identifiers":[],"subtype":"a2a-skill","type":"tool"}],"repository":{"commit":"unknown","root_digest":"sha256:ae3be7cb2590e86355334c34b65958487f8888ab712982528a18ae49fd4733a4"},"schema_url":"https://schemas.controlloop.ai/acbom/1.2.0/acbom.schema.json","schema_version":"1.2.0"} diff --git a/tests/fixtures/golden/single-agent/report.json b/tests/fixtures/golden/single-agent/report.json index 7575e80..1770f44 100644 --- a/tests/fixtures/golden/single-agent/report.json +++ b/tests/fixtures/golden/single-agent/report.json @@ -1 +1 @@ -{"schema_version":"1.2.0","verdict":"passed","blast_radius":null,"material_changes":null,"findings":[],"diagnostics":[],"suppressions":[],"versions":{"scanner":{"name":"controlloop","version":"0.6.2"},"acbom_schema_version":"1.2.0","report_schema_version":"1.2.0","policy_version":"0.9.0"}} +{"schema_version":"1.2.0","verdict":"passed","blast_radius":null,"material_changes":null,"findings":[],"diagnostics":[],"suppressions":[],"versions":{"scanner":{"name":"controlloop","version":"0.6.3"},"acbom_schema_version":"1.2.0","report_schema_version":"1.2.0","policy_version":"0.9.0"}} diff --git a/tests/test_action_metadata.py b/tests/test_action_metadata.py index 2ca183e..9893227 100644 --- a/tests/test_action_metadata.py +++ b/tests/test_action_metadata.py @@ -29,5 +29,5 @@ def test_the_description_is_short_enough_for_marketplace() -> None: def test_the_listing_has_a_name_and_branding() -> None: metadata = _metadata() - assert metadata["name"] == "ControlLoop gate" + assert metadata["name"] == "ControlLoop Security" assert metadata["branding"] == {"icon": "shield", "color": "blue"} diff --git a/tests/test_gate_determinism_regression.py b/tests/test_gate_determinism_regression.py index 2d81a23..50cf4f3 100644 --- a/tests/test_gate_determinism_regression.py +++ b/tests/test_gate_determinism_regression.py @@ -64,9 +64,10 @@ # And for 0.5.0 -> 0.6.0. # And for 0.6.0 -> 0.6.1. # And for 0.6.1 -> 0.6.2. +# And for 0.6.2 -> 0.6.3. # Stable across 3 repeated local runs before being recorded. _GOLDEN_DIGEST = ( - "sha256:2eeef5b0c188b8d868434218004d2e90d777824d356ff36ddc39eadd887f7774" + "sha256:cc02a7654685fa5b953fb1f72d852c40fe7d861c0de431784198d7222678d5d0" ) diff --git a/uv.lock b/uv.lock index 8e34864..e398ba5 100644 --- a/uv.lock +++ b/uv.lock @@ -58,7 +58,7 @@ wheels = [ [[package]] name = "controlloop" -version = "0.6.2" +version = "0.6.3" source = { editable = "." } dependencies = [ { name = "pathspec" },