What this review found
No material or immediate-danger item was identified.
Minor cautions
zizmor reported unpinned-uses
Minor caution · high confidence
The build pipeline uses a version label for a Gradle setup tool instead of locking it to a specific, unchangeable version. This is a minor hardening gap, not an active problem.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The composite action references gradle/actions/setup-gradle using a major version tag rather than a full commit SHA. Mutable tags introduce a supply-chain risk if the upstream tag is moved. This is a widely used action maintained by the Gradle team, so practical exploitation is unlikely, but SHA pinning is the recommended practice.
Impact: low · Exploitability: unlikely
Developer action: Pin the action reference to a full commit SHA and optionally record the version in a comment.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- production
- Source
- .ci-cd/android/action.yml:24
zizmor reported unpinned-uses
Minor caution · high confidence
The build pipeline uses a version label for an artifact upload tool instead of locking it to a specific, unchangeable version. This is a minor hardening gap, not an active problem.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The composite action references actions/upload-artifact a second time using a major version tag rather than a full commit SHA. The same mutable-tag supply-chain consideration applies as for the other unpinned references in this file.
Impact: low · Exploitability: unlikely
Developer action: Pin the action reference to a full commit SHA and optionally record the version in a comment.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- production
- Source
- .ci-cd/android/action.yml:46
zizmor reported excessive-permissions
Minor caution · medium confidence
The automated test workflow does not explicitly limit what permissions it has, so it may inherit more access than necessary. Since the workflow only checks out code and runs tests, this is a minor hygiene issue rather than a real danger.
Technical evidence
Scanner reason: zizmor matched workflow-security rule excessive-permissions in this repository.
Contextual assessment: The test job does not declare an explicit permissions block. Without it, the workflow token inherits the repository default permissions, which may be broader than needed. The job only checks out code and runs a local test action, so no sensitive operation is performed with the token. Adding a minimal permissions declaration is best practice but the absence does not create a concrete exploit path here.
Impact: low · Exploitability: unlikely
Developer action: Add a top-level or job-level permissions block with read-only contents permission to follow least-privilege best practice.
- Scanner
- zizmor 1.28.0
- Rule
- excessive-permissions
- File role
- test
- Source
- .github/workflows/test.yml:12-21
zizmor reported unpinned-uses
Minor caution · high confidence
The build pipeline uses a version label for a standard GitHub tool instead of locking it to a specific snapshot. If someone managed to reassign that label to malicious code, the build could run that code. This is a common best-practice gap with very low real-world risk for an official action.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The workflow references actions/checkout by a mutable major-version tag rather than a commit SHA pin. If the tag were ever moved to a compromised revision, arbitrary code would execute in CI with contents:write permissions. This is a standard hardening gap, not an active vulnerability; the action is an official GitHub-maintained action and tag compromise is unlikely.
Impact: low · Exploitability: unlikely
Developer action: Pin actions/checkout to a full commit SHA for reproducibility and supply-chain hardening.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- tooling
- Source
- .github/workflows/build-apk.yml:18
zizmor reported unpinned-uses
Minor caution · medium confidence
The workflow uses a version label for a standard checkout tool instead of locking it to an exact code snapshot. If someone moved that label to bad code, the workflow would use it. This is a common shortcut and the tool is official, so the risk is low, but locking to an exact version is safer.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The checkout step references actions/checkout@v4, a major-version tag rather than a commit SHA. If the tag were moved to a compromised version, the workflow would pull the new code. This is a widely accepted convention for the official checkout action, and the workflow only uses it to clone the repository for testing. SHA-pinning is the stronger practice but the practical risk is low given the action's maintainer and usage pattern.
Impact: low · Exploitability: plausible
Developer action: Pin actions/checkout to a full commit SHA instead of a floating major-version tag for stronger supply-chain integrity.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- test
- Source
- .github/workflows/test.yml:17
zizmor reported unpinned-uses
Minor caution · high confidence
The build pipeline uses a version label for an artifact upload tool instead of locking it to a specific, unchangeable version. This is a minor hardening gap, not an active problem.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The composite action references actions/upload-artifact using a major version tag rather than a full commit SHA. Mutable tags introduce a supply-chain risk if the upstream tag is moved. This is a first-party GitHub action, so practical exploitation is unlikely, but SHA pinning is the recommended practice.
Impact: low · Exploitability: unlikely
Developer action: Pin the action reference to a full commit SHA and optionally record the version in a comment.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- production
- Source
- .ci-cd/android/action.yml:40
zizmor reported artipacked
Minor caution · high confidence
The workflow's checkout step leaves a temporary access token saved in the local git configuration by default. This is a common practice and the token is limited in scope and short-lived, but it is cleaner to disable that persistence.
Technical evidence
Scanner reason: zizmor matched workflow-security rule artipacked in this repository.
Contextual assessment: The checkout step uses the default settings of actions/checkout, which persists a scoped GITHUB_TOKEN into the local .git/config for subsequent steps. The workflow explicitly scopes permissions to contents:read and packages:write, and the only subsequent step is a local composite action from the same repository. Token persistence is a known default behavior; exploitation would require a compromised or malicious step reading .git/config, which is not present here. Setting persist-credentials: false would eliminate the residual exposure.
Impact: low · Exploitability: unlikely
Developer action: Add persist-credentials: false to the checkout step to avoid leaving the token in .git/config.
- Scanner
- zizmor 1.28.0
- Rule
- artipacked
- File role
- tooling
- Source
- .github/workflows/docker-publish.yml:16-17
zizmor reported unpinned-uses
Minor caution · high confidence
The build pipeline uses a version label for a build tool instead of locking it to a specific, unchangeable version. If someone managed to swap what that label points to, the build could run altered code. This is a minor hardening gap, not an active problem.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The composite action references actions/setup-java using a major version tag rather than a full commit SHA. Major version tags are mutable: if the upstream repository's tag were moved to a malicious commit, the build would execute untrusted code. This is a first-party GitHub action, so tag compromise is unlikely, but SHA pinning is the recommended hardening practice for CI supply-chain integrity.
Impact: low · Exploitability: unlikely
Developer action: Pin the action reference to a full commit SHA and optionally record the version in a comment.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- production
- Source
- .ci-cd/android/action.yml:13
zizmor reported unpinned-uses
Minor caution · high confidence
The CI workflow uses a version label for a login helper instead of locking it to a specific release. If someone hijacked that helper's label, they could intercept the login token. This is a common shortcut, not a sign of foul play, but pinning to an exact release would be safer.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The composite action references docker/login-action@v3, a major-version tag that is mutable. If the upstream tag were moved to a compromised release, the workflow would execute untrusted code with access to the GitHub token passed as the registry password. This is a supply-chain hardening gap, not evidence of malicious intent; the action is the official Docker login action used for its stated purpose of authenticating to ghcr.io.
Impact: medium · Exploitability: unlikely
Developer action: Pin docker/login-action to a full commit SHA with a recorded digest instead of the mutable @v3 tag.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- production
- Source
- .ci-cd/docker/action.yml:21
zizmor reported unpinned-uses
Minor caution · high confidence
The test workflow uses a version label for a helper tool instead of locking it to a specific snapshot. If someone moved that label to different code later, tests could run different code. Locking to an exact snapshot removes that risk.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The composite test action references astral-sh/setup-uv by a floating major-version tag rather than a commit SHA. A tag can be moved by the upstream maintainer, so a compromised or hijacked tag could substitute different code in future CI runs. This is a supply-chain hardening gap, not an active vulnerability in the current repository state, and the action is a well-known tool used for its stated purpose of installing the uv toolchain.
Impact: low · Exploitability: unlikely
Developer action: Pin the action reference to a specific commit SHA with an integrity comment for reproducible and tamper-resistant CI.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- test
- Source
- .ci-cd/test/action.yml:8
zizmor reported unpinned-uses
Minor caution · high confidence
The build pipeline uses a version label for a Python setup tool instead of locking it to a specific, unchangeable version. This is a minor hardening gap, not an active problem.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The composite action references actions/setup-python using a major version tag rather than a full commit SHA. Mutable tags introduce a supply-chain risk if the upstream tag is moved. This is a first-party GitHub action, so practical exploitation is unlikely, but SHA pinning is the recommended practice.
Impact: low · Exploitability: unlikely
Developer action: Pin the action reference to a full commit SHA and optionally record the version in a comment.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- production
- Source
- .ci-cd/android/action.yml:19
zizmor reported unpinned-uses
Minor caution · high confidence
The workflow uses a version label for a metadata helper instead of locking it to a specific release. A hijacked label could run bad code during the build. It is a standard helper used normally, but exact pinning would remove the risk.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The composite action references docker/metadata-action@v5, a mutable major-version tag. The action receives repository context to derive image tags and labels but is not handed secrets directly. A tag-swap attack could still execute arbitrary code in the workflow runner. The usage matches the stated build-and-publish purpose and shows no malicious data flow.
Impact: medium · Exploitability: unlikely
Developer action: Pin docker/metadata-action to a full commit SHA with a recorded digest instead of the mutable @v5 tag.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- production
- Source
- .ci-cd/docker/action.yml:29
zizmor reported unpinned-uses
Minor caution · high confidence
The test workflow uses a version label for the official Python setup helper instead of locking it to a specific snapshot. Locking to an exact snapshot makes the tests more tamper-resistant.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The composite test action references actions/setup-python by a floating major-version tag rather than a commit SHA. The same supply-chain consideration applies: a moved tag could alter future CI behavior. The action is the official GitHub Python setup tool used for its stated purpose, and no malicious behavior is present in the current reference.
Impact: low · Exploitability: unlikely
Developer action: Pin the action reference to a specific commit SHA with an integrity comment for reproducible and tamper-resistant CI.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- test
- Source
- .ci-cd/test/action.yml:13
zizmor reported artipacked
Minor caution · low confidence
The scanner flagged a possible credential-leakage pattern, but this workflow does not save or upload any files that could carry credentials. The concern does not match what the workflow actually does.
Technical evidence
Scanner reason: zizmor matched workflow-security rule artipacked in this repository.
Contextual assessment: The artipacked pattern concerns credentials persisting in artifacts or cache. This workflow performs a checkout and then runs a local test action; it does not upload artifacts, save caches, or otherwise persist the GitHub token beyond the ephemeral runner workspace. The scanner confidence is low and the data flow does not show a credential persistence path.
Impact: low · Exploitability: unlikely
Developer action: none
- Scanner
- zizmor 1.28.0
- Rule
- artipacked
- File role
- test
- Source
- .github/workflows/test.yml:16-17
zizmor reported artipacked
Minor caution · low confidence
The checkout step leaves a temporary access token inside the downloaded code folder. If a later step packages that folder and shares it, the token could leak. No packaging step is visible here, so this is a precautionary note rather than a confirmed problem.
Technical evidence
Scanner reason: zizmor matched workflow-security rule artipacked in this repository.
Contextual assessment: The default behavior of actions/checkout persists the GITHUB_TOKEN into the local .git/config of the workspace. If a downstream step or the local composite action uploads workspace contents (including .git) as an artifact, that token could be exposed in the artifact. No artifact-upload step is visible in this workflow file, and the local action's contents are not supplied, so runtime reachability cannot be confirmed.
Impact: low · Exploitability: unlikely
Developer action: Set persist-credentials: false on actions/checkout if the token is not needed for subsequent git operations, or ensure no artifact upload includes the .git directory.
- Scanner
- zizmor 1.28.0
- Rule
- artipacked
- File role
- tooling
- Source
- .github/workflows/build-apk.yml:17-18
zizmor reported unpinned-uses
Minor caution · high confidence
The workflow uses a version tag instead of an exact commit hash for the checkout tool. This is standard practice for GitHub's own actions, but pinning to a specific hash is a stronger safeguard against tampering.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The checkout action is referenced by tag (v4) rather than a commit SHA. If the v4 tag were moved to a malicious version, the workflow would execute it. However, actions/checkout is GitHub's first-party action, the tag is widely monitored, and the second action reference (./.ci-cd/docker) is a local composite action pinned to repository content. The supply-chain surface is limited to the single first-party action reference.
Impact: low · Exploitability: unlikely
Developer action: Pin actions/checkout to a specific commit SHA for stronger supply-chain integrity.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- tooling
- Source
- .github/workflows/docker-publish.yml:17
zizmor reported unpinned-uses
Minor caution · high confidence
The workflow uses a version label for the image build helper instead of locking it to a specific release. If that label were hijacked, bad code could run during the build and could alter the published image. It is a normal helper used as intended, but exact pinning would be safer.
Technical evidence
Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.
Contextual assessment: The composite action references docker/build-push-action@v5, a mutable major-version tag. This step performs the actual image build and push using derived tags and labels. A compromised tag would execute arbitrary code with workflow permissions and could tamper with the published image. The action is the official Docker build-push action used for its intended purpose, with no concealed exfiltration or unexpected destinations.
Impact: medium · Exploitability: unlikely
Developer action: Pin docker/build-push-action to a full commit SHA with a recorded digest instead of the mutable @v5 tag.
- Scanner
- zizmor 1.28.0
- Rule
- unpinned-uses
- File role
- production
- Source
- .ci-cd/docker/action.yml:13
Expected scanner matches (2)
Gitleaks reported generic-api-key
Expected behavior · high confidence
This is a made-up marker string used only inside a test to check that private character thoughts reach the intended agent and nobody else. It is not a real password or API key and is never used to log in to anything.
Technical evidence
Scanner reason: Gitleaks matched secret-detection rule generic-api-key in this repository.
Contextual assessment: The flagged value is a synthetic canary token defined in a test file and deliberately embedded into a fake character thought record. It is never a real credential: it is not loaded from environment or config, never sent to any external service, and exists only so assertions can confirm which agent prompts contain or exclude it. The test file imports only local project modules and pytest, constructs in-memory fixtures, and performs string membership checks. No network, filesystem credential, or provider API is involved.
Impact: none · Exploitability: unlikely
Developer action: none
- Scanner
- gitleaks 8.30.1
- Rule
- generic-api-key
- File role
- test
- Source
- tests/test_thought_containment.py:40
Gitleaks reported generic-api-key
Expected behavior · high confidence
This is a fake, made-up label used inside a test to check that private character thoughts stay private. It is not a real password or key, and it never leaves the test file.
Technical evidence
Scanner reason: Gitleaks matched secret-detection rule generic-api-key in this repository.
Contextual assessment: The matched value is a deliberately fabricated test token assigned to a constant named SECRET in a test file. The surrounding code and comments explain it is a nonsense string chosen so that any prompt carrying it must be carrying the planted private thought. It is used only in assertions that verify thought-containment boundaries between agents. It is not a real API key, is not sent to any external service, and is not loaded as configuration. The gitleaks generic-api-key rule matched on the word SECRET and the bracketed token shape, but the data flow is purely local test logic.
Impact: none · Exploitability: unlikely
Developer action: none
- Scanner
- gitleaks 8.30.1
- Rule
- generic-api-key
- File role
- test
- Source
- tests/test_thought_containment.py:40