consensus-agent-action-guard

AdvisoryAudited by Static analysis on Apr 30, 2026.

Overview

No suspicious patterns detected.

Findings (0)

Artifact-based informational review of SKILL.md, metadata, install specs, static scan signals, and capability signals. ClawScan does not execute the skill or run runtime probes.

What this means

If this is used as a final safety gate, an untrusted or poorly controlled caller could supply favorable external votes and get ALLOW for a risky action that should require confirmation or blocking.

Why it was flagged

In external_agent mode, the code only checks that external_votes is an array and then lets those caller-supplied votes determine the guard decision; the local constraint and hard-block vote generation path is skipped.

Skill content
if(input.external_votes!==undefined && !Array.isArray(input.external_votes)) return 'external_votes must be array'; ... const votes = externalMode ? input.external_votes : makeVotes(personaSet, input.proposed_action, input.constraints || {}); const ag = aggregateVotes(votes, { method:'WEIGHTED_APPROVAL_VOTE', approve_threshold:0.7 }); const final_decision = mapDecision(ag.final_decision);
Recommendation

Apply hard-block and human-confirmation constraints in every mode, validate the vote schema and allowed voters, and only accept external_agent votes from authenticated, trusted sources.

What this means

A stale or previously primed ALLOW/BLOCK decision could carry forward into later runs, affecting high-risk action gating across retries or sessions.

Why it was flagged

The persisted decision lookup key excludes mode and external_votes even though those values can affect the decision, so an older decision can be reused when the vote source or vote contents have changed.

Skill content
const idem = makeIdempotencyKey({ board_id, proposed_action: input.proposed_action, constraints: input.constraints||{}, persona_set_id: input.persona_set_id||null }); const prior = await getDecisionByKey(board_id, idem, statePath); if (prior?.response) return prior.response; ... const votes = externalMode ? input.external_votes : makeVotes(personaSet, input.proposed_action, input.constraints || {});
Recommendation

Include all decision-changing inputs in the idempotency key, add expiration or explicit revalidation for high-risk actions, and avoid replaying external-vote decisions unless the same authenticated votes are present.

What this means

Local audit files may reveal planned actions, voting rationale, or other workflow details, and prior stored decisions may be reused later.

Why it was flagged

The skill writes decision artifacts, votes, and aggregation details into persistent state. This is expected for auditability, but those artifacts can influence future idempotent lookups and may contain sensitive operational context.

Skill content
const d = await writeArtifact(board_id, 'decision', { idempotency_key: idem, decision_id, final_decision, votes, aggregation: ag, response }, statePath);
Recommendation

Store the consensus state in a protected, project-scoped location; limit who can edit it; and treat decision artifacts as sensitive audit records.

What this means

Future installs could resolve to newer dependency versions unless the lockfile is enforced, which matters for a safety-gating component.

Why it was flagged

The install depends on npm packages with caret version ranges, allowing semver-compatible updates. This is common npm behavior, but it is not an exact pin by itself.

Skill content
"dependencies": { "consensus-guard-core": "^1.1.15", "tsx": "^4.20.3" }
Recommendation

Install with a trusted lockfile or exact pinned versions, and review dependency updates before deploying this guard in production automation.