DocsReview profiles (personas)
Review profiles (personas)
A profile tells the reviewer which perspective to take: a security reviewer, a smart contract auditor, the engineer who runs the deployment. Each profile is one Markdown file in .desk/profiles/ of the repository. A review runs with one profile. To get more perspectives, run one review for each profile.
The rules do not change with the profile. Every review loads the rule files whose paths match a changed file: the rules from the repository's review history, and the rule packs from published guidance. The profile decides what the reviewer looks for first, and how it judges severity.
The profiles that desk init writes
| Profile | Perspective | Suggested for |
|---|---|---|
full |
The default review: correctness, the repository rules, tests and docs | Every change |
security |
Trust boundaries, authorization, signatures and replay, encryption and keys, secrets, denial of service | Auth, crypto, signing, attestation, contracts, protocol messages |
architecture |
Layers and ownership, interfaces and schemas, duplication, the match with specs, whether the PR is one unit | Interfaces, protocol messages, specs, schemas |
smart-contract |
Access control, signed digests, storage and upgrades, external calls and reentrancy, events, deploy scripts, gas | *.sol, contracts/** |
devops |
CI/CD, build scripts, images, Kubernetes and Terraform, deploy configuration, secrets, observability, modularity of the infrastructure code. Uses the rule packs. | .github/**, Makefiles, Dockerfiles, scripts, charts, Terraform, deploy, dashboards and alert files |
reliability |
Errors and fail-closed handling, retries and idempotency, ordering, concurrency, reorgs, timeouts, recovery | Set the service paths of each repository |
Why these profiles
The first set came from the human review history of two repositories: 3,401 first comments of human review threads, by people other than the PR author, in 1,647 PRs. A keyword and path count gives this share of the comments:
| Concern | Share of the comments | Profile |
|---|---|---|
Contract code (comments on *.sol files) |
21% | smart-contract |
| Security, cryptography and trust | about 25% | security |
| Docs, comments and names | about 24% | full |
| Tests (comments on test files) | 9% | full |
| Design, duplication and abstraction | about 8% | architecture |
| Concurrency, retries, ordering and crashes | about 7% | reliability |
| Build, CI and deploy (comments on those files) | 7% | devops |
| Performance | 2.4% (82 comments, most about gas) | none: gas is in smart-contract, denial of service is in security |
A comment can count for more than one concern. The numbers show the order of size. They are not exact.
A separate performance profile had too little evidence: few reviewers asked for it, and most of those comments were about gas. Add one when your repository has a hot path that reviewers check often (see below).
When to add a profile
Add a profile when all of these are true:
- Reviewers in your repository ask for this perspective again and again. Count it: search the review comments of the last months, or the rule files, for the topic.
- The perspective needs its own checklist. If a few rules cover it, add the rules to a rule file. Each review loads them by path.
- A person can tell from the files of a change when the perspective applies. Write those files as the profile's
paths.
Do not add a profile for a style preference. A linter or a formatter checks style.
How to add a profile
Create
.desk/profiles/<name>.md. Use a short name in lower case with hyphens, for exampleperformanceorfrontend.Start the file with front matter:
--- description: One line that says what this review looks at. `desk profiles` prints it. paths: ['src/hot/**', '**/*.sql'] ---descriptionis required in practice: the skills read it to choose a profile.pathsis optional. When a changed file matches a glob,desk profilessuggests the profile. With nopaths, the profile runs only on request.- The globs follow gitignore rules:
**crosses folders,*stays in one folder,{a,b}is a choice, and a glob with no/matches the file name in any folder. A leading/anchors it at the root, so/package.jsonis the one at the root and notui/package.json.
Write the checklist below the front matter. Follow the form of the existing profiles:
- First sentence: the perspective, as a person ("Review the change as the engineer who…").
- Numbered checks, each one a thing the reviewer can verify in the diff and the code around it.
- The proof that a finding needs, and what makes a finding a blocker.
- Rule ids from
.desk/rules/where a check comes from a rule. - No more than about 10 checks. A long list gets a shallow review.
Add the profile to
review.profilesin.desk/config.json:"profiles": { "full": "profiles/full.md", "performance": "profiles/performance.md" }Check it:
desk doctor # the profile file exists desk profiles --pr <n> # the profile is suggested for a PR that touches its paths desk review --pr <n> --profile <name>Run it on two or three past PRs that had human comments on this topic. Compare the report with those comments. Keep the profile only if it finds what the people found, with few false findings. For a measured answer, run the back-test on the hold-out PRs with the new profile.
Open a PR with the profile file and the config change. A profile changes how every review of the repository behaves, so a person reviews it like code.
Example: a performance profile
---
description: Performance review of hot paths - complexity, allocations, I/O in loops, database queries and caching with measurements.
paths: ['src/indexer/**', 'src/api/handlers/**']
---
Review the change as the engineer who owns the latency and the cost of this service.
1. Find the hot paths that the change touches: request handlers, loops over chain data, indexer steps.
2. Check complexity: no linear scan or nested loop over data that grows, where an index or a map exists.
3. Check I/O: no network call or query inside a loop that can be batched. Each query uses an index.
4. Check allocations: no copy of a large buffer per item, no unbounded cache.
5. A cache needs a measurement and an invalidation rule. Do not suggest a cache without both.
6. Give each finding the cost: the input size, the number of calls, or the measured time.
Report a blocker only for a change that makes a hot path grow faster than its input (for example from linear to quadratic).
Use a profile
- Say it to the AI: "review PR 123 as a smart contract auditor", "devops review of this branch", "review PR 123 with all relevant profiles". The
pr-reviewskill maps the request to a profile. - Or run the CLI:
desk review --pr 123 --profile smart-contract. - A headless run:
desk review --pr 123 --profile devops --engine claude --repo-access(add--model <m>, or setreview.modelsinconfig.json).
Each run writes its own report in .desk/out/<target>/<time>-<profile>/report.md.