Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when starting any security review in code_review - risk-tier each changed file, read the repo's own security patterns, compare, then trace source to sink, including removed guards and blast radius
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
You are reviewing a change, not auditing a repository. The question is: what can an attacker do after this diff that they could not do before? Every finding answers it with a source you can point at, a sink you can point at, and the diff line that connects them.
Core principle: risk first, then evidence. Spend your reading on the files that can hurt someone; trace one real data flow end to end rather than skimming ten.
The injected diff starts with git diff --stat — every file it lists is under review. Get the base once and reuse it:
base=$(git merge-base HEAD origin/HEAD 2>/dev/null || git merge-base HEAD origin/main)
git diff --stat "$base"
git diff "$base" -- path/to/file # each file the 24,000-byte cut left out
Tier every file before reading any of them closely:
| Tier | What lands here | Depth |
|---|---|---|
| HIGH | auth/session, access checks, crypto, secrets, deserialization, file paths, outbound URLs, shell/exec, SQL/templates, payments, dependency manifests and lockfiles, CI workflows, Dockerfiles, IaC, agent/MCP configs, anything an LLM with tools reads | full source → sink trace |
| MEDIUM | business logic, state changes, new public endpoints or exported functions, new config | trace the inputs it accepts |
| LOW | comments, copy, styling, tests, logging that carries no secret | scan for secrets only |
A refactor is HIGH until you have shown it is LOW: moved code is where a guard silently stays behind.
Then pick the attack-class skills each HIGH and MEDIUM file needs (coverage-and-variant-pass §1) and load them before tracing.
Before judging new code, learn how this repository already defends itself. A finding is strongest when it says "every neighbour does X, this one does not".
@PreAuthorize/@RolesAllowed convention, the "load for owner" repository method, the tenant filter.get_project_brief — a public multi-tenant service, an internal tool and a local desktop app have different attackers. It changes severity, never whether you trace.search_memory (scope=project) for this repository's security facts — which proxy strips which header, how tenants are scoped, which IMDS version runs. Save a new one with save_memory only when you read it in the base branch's source or config; never save a claim the change under review makes about itself.grep_code "RequireAuth|authMiddleware|@PreAuthorize|@RolesAllowed|ownerID|tenant_id"
Ask how the new code deviates from the established secure pattern. The most common real finding is an asymmetry: one path validates, its sibling does not.
// ❌ the new route is registered on the bare app, outside the authenticated group its neighbours use
api := app.Group("/api", authMW)
api.Get("/invoices/:id", h.GetInvoice)
app.Delete("/api/invoices/:id", h.DeleteInvoice)
// ✅ same group, same middleware chain as its siblings
api.Delete("/invoices/:id", h.DeleteInvoice)
Other asymmetries worth a second look: the create handler checks ownership and the update handler does not; the JSON endpoint escapes output and the CSV export does not; the web route is guarded and the new gRPC/GraphQL/WebSocket entry to the same service is not; the API validates and the background job consuming the same payload does not.
List the sources the diff touches, then follow each one to where it is used.
github.event.*), and model output.expand_symbol_context and grep_code — a sanitiser in a helper you did not open is the most common false positive; a sanitiser applied on one branch only is the most common miss.source (file:line) → transform (file:line) → sink (file:line). It becomes the evidence line of the finding, or it shows you there is no finding.A sink that looks dangerous is where you start reading, not what you report. Every candidate is a broken invariant, and writing it as one keeps the trace honest:
If you cannot fill in 1–3, there is no finding yet; if 4 shows the control holds, mark the surface covered and move on.
Happy-path code is the most reviewed. For each value the diff accepts, check only the cases its interface really admits: absent, empty, zero, negative, maximum, over the limit, duplicated, mixed encoding or case, stale, revoked, reordered, concurrent, half-migrated, after a dependency failed, during rollback.
At every handoff between components — parser to validator, validator to handler, API to queue to worker, service to cache — compare what the first side guarantees with what the second side assumes: truncation, normalization, Unicode case-folding, type coercion, units, tenant scope. Most real findings are one disagreement in that table.
The - lines can be the vulnerability: a removed check, a dropped middleware, a loosened regex, a private that became public, a default flipped from deny to allow, verify=True deleted.
When a removed line looks protective, find out why it was there:
git blame "$base" -L 40,60 -- internal/files/handler.go # who added the removed lines
git log -S 'filepath.EvalSymlinks' --oneline -- internal/files/ # when the guard came and went
git show <sha> --stat # read the commit that added it
A removed line that came from a commit mentioning a CVE, a security fix or an incident is a red flag; removal without a replacement guard is a finding when the input is still reachable.
A changed shared function changes every caller. When the diff touches a validator, an auth helper, a sanitiser, a default value or a base class, count the callers (grep_code the symbol) and check whether any of them now passes attacker input through a weaker path. Name the caller's file:line in the finding — "might affect callers" is not evidence.
Run the coverage and variant pass once (coverage-and-variant-pass): every risky surface has a disposition, the critic questions are asked, every HIGH/CRITICAL root cause has had its variants searched, and the obvious-things sweep is done. Then put each survivor through the false-positive gate.
if on the auth or validation path and no replacement.git blame points at a security fix.아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.