feat(cli): disposition set — manual human verdict (#4)#42
Conversation
A person can record true_positive/false_positive on a finding through the same channel the Ollama verifier uses (set_finding_disposition → global FINDING_STATE + STATE_EVENT ledger), with actor=human / source=manual. Because finding_id is branch/commit-stable, a cleared finding stays cleared on re-detection, so future re-asks are suppressed. - cli/commands/disposition.py: `disposition set --finding-id --verdict [--reason --repo --rule-id]`; reuses disposition_status_for_verdict (false_positive→FALSE_POSITIVE, true_positive→OPEN); reads repo/ruleId from the finding's stored state unless overridden; dynamodb-only (exit 2), unknown finding → exit 2. - app.py: register the command. Out of scope: notification/endpoint (design exclusion) and IGNORED status (not a Verdict value) — possible follow-up. Spec: docs/workbench/specs/human-disposition/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a new disposition CLI subcommand (disposition set) that allows analysts to manually record human verdicts (true_positive or false_positive) on findings. The command integrates with the existing DynamoDB-compatible finding store to persist these manual triages, which are then used to suppress future re-detections. Design and requirements specifications, CLI command implementation, and comprehensive unit tests have been added. No review comments were provided, so there is no feedback to address.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
What
Add
disposition set— a CLI for a person/analyst to record atrue_positive/false_positiveverdict on a finding, through the same channel the Ollamaverifier uses (
set_finding_disposition→ globalFINDING_STATE+append-only
STATE_EVENTledger), taggedactor=human/source=manual.Why
Today only the AI verifier auto-dispositions; there was no way for a human to
record a verdict. Because
finding_idis branch/commit-stable, a cleared findingstays cleared on re-detection (global state), so a manual verdict suppresses
future re-asks — exactly the human-triage feedback loop that was missing.
Changes
cli/commands/disposition.py:disposition set --finding-id --verdict [--reason --repo --rule-id]. Reusesdisposition_status_for_verdict(
false_positive→FALSE_POSITIVE,true_positive→OPEN); takes repo/ruleIdfrom the finding's stored state unless overridden;
dynamodb-only (exit 2);unknown finding → exit 2.
app.py: register the command (+ registration-order lock updated).docs/workbench/specs/human-disposition/(research-grounded self-Q&A).Test
uv run pytest— 690 passed (false/true positive mapping + recordedactor/source/reason/repo/rule, unknown-finding exit 2, repo/rule override,
missing repo/rule exit 2, jsonl exit 2).
governance.public_safetyclean.Out of scope
IGNOREDstatus (not aVerdictvalue) — possible follow-up.Related to #23 follow-on residual work.