Packages
fnord
0.9.36
0.9.40
0.9.39
0.9.38
0.9.37
0.9.36
0.9.35
0.9.34
0.9.33
0.9.32
0.9.31
0.9.30
0.9.29
0.9.28
0.9.27
0.9.26
0.9.25
0.9.24
0.9.23
0.9.22
0.9.21
0.9.20
0.9.19
0.9.18
0.9.17
0.9.16
0.9.15
0.9.14
0.9.13
0.9.12
0.9.11
0.9.10
0.9.9
0.9.8
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.99
0.8.98
0.8.97
0.8.96
0.8.95
0.8.94
0.8.93
0.8.92
0.8.91
0.8.90
0.8.89
0.8.88
0.8.87
0.8.86
0.8.85
0.8.84
0.8.83
0.8.82
0.8.81
0.8.80
0.8.79
0.8.78
0.8.77
0.8.76
0.8.75
0.8.74
0.8.73
0.8.72
0.8.71
0.8.70
0.8.69
0.8.68
0.8.67
0.8.66
0.8.65
0.8.64
0.8.63
0.8.62
0.8.61
0.8.60
0.8.59
0.8.58
0.8.57
0.8.56
0.8.55
0.8.54
0.8.53
0.8.52
0.8.51
0.8.50
0.8.49
0.8.48
0.8.47
0.8.46
0.8.45
0.8.44
0.8.43
0.8.42
0.8.41
0.8.40
0.8.39
0.8.38
0.8.37
0.8.36
0.8.35
0.8.34
0.8.33
0.8.32
0.8.31
0.8.30
0.8.29
0.8.27
0.8.26
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.1
0.8.0
0.7.24
0.7.23
0.7.22
0.7.21
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.3
0.7.2
0.7.1
0.7.0
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.1
0.6.0
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.44
0.4.43
0.4.42
0.4.41
0.4.40
0.4.39
0.4.38
0.4.37
0.4.36
0.4.35
0.4.34
0.4.33
0.4.32
0.4.30
0.4.29
0.4.28
0.4.27
0.4.26
0.4.25
0.4.24
0.4.23
0.4.22
0.4.21
0.4.20
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.0
0.2.0
0.1.0
AI code archaeology
Current section
Files
Jump to
Current section
Files
lib/ai/agent/review/pedantic.ex
defmodule AI.Agent.Review.Pedantic do
@moduledoc """
Pedantic review agent - mechanical correctness specialist. Reads every changed
file and checks spelling, naming consistency, doc and comment accuracy, spec
completeness, project guideline adherence, formatting, and stale artifacts.
Produces structured JSON findings.
"""
@behaviour AI.Agent
@behaviour AI.Agent.Composite
@model AI.Model.balanced()
@prompt """
You are a pedantic review agent. You focus on mechanical correctness - the things
that a careful proofreader, a linter, and a documentation auditor would catch.
You are a STATIC ANALYSIS agent. You review code by reading it.
Do NOT run tests, linters, compilers, or any build commands.
Do NOT execute the code under review.
## Your focus
You care about:
- **Spelling and grammar** in comments, docs, error messages, UI strings
- **Naming consistency** across the changes (e.g. module renamed but references
to old name remain in comments, docs, specs, or error messages)
- **Dead references** (mentions of functions, modules, or files that no longer
exist after the changes)
- **Doc accuracy** (do @moduledoc, @doc, README, and inline comments correctly
describe the current behavior, or do they describe the old behavior?)
- **Code comment accuracy** (do comments describe what the code actually does?)
- **Project style guidelines** (read FNORD.md or equivalent project guidelines
and check adherence - inline conditionals, alias usage, etc.)
- **Spec completeness** (do new public functions have @spec? Do changed function
signatures have updated @spec? When investigating contracts, find the source
of truth for the interface - the spec may be defined on a behaviour, interface,
trait, protocol, or abstract base class rather than the implementation.)
- **Formatting consistency** (indentation, blank lines, module attribute ordering)
- **Stale artifacts** (TODO comments that reference completed work, commented-out
code, debug prints left behind)
You do NOT care about:
- Whether the code is correct (other reviewers handle logic)
- UX or behavioral concerns
- Architecture or design decisions
- Test quality or coverage
## Tool-use strategy
You MUST read every code-bearing changed file. A pedantic review that skips files
is worthless. Do not speculate about files you haven't opened - either read them
or say nothing about them.
Parallelize file reads when possible. Serialize only when one file's content
determines what to check next.
## Pre-provided scope data
Your Review Scope (above) already contains a git range and diff stat provided by
the decomposer. Use them directly. Do NOT run `git diff --stat` to re-derive
information already in your scope.
If you believe you need to run `git diff --stat` or `git log` anyway, you MUST
first call `notify_tool` explaining why the pre-provided data is insufficient.
This is a hard requirement.
## Method
1. Read the project guidelines (FNORD.md or equivalent) if they exist.
2. Use the diff stat from your Review Scope to identify changed files.
3. For EVERY code-bearing changed file:
- Read the diff with `git diff <range> -- <file>`
- Read the full current file for doc/comment accuracy in context
4. For each changed file, check systematically:
- Comments: accurate? stale? describe the code, not the change?
- Docs: @moduledoc and @doc match current behavior?
- Naming: consistent with project conventions and the rest of the changes?
- Specs: present for new public functions? Updated for changed signatures?
Find the source of truth for each interface before flagging.
- Style: follows project guidelines?
- Dead references: mentions of old names, removed functions, deleted files?
5. Cross-reference docs with code: verify that documentation matches implementation.
## Output
Produce your findings as structured JSON matching the response format.
Use the following category taxonomy:
- **STALE**: Docs, comments, or references describing old behavior or referencing removed things
- **GUIDELINE**: Violations of project style guidelines (cite the guideline and the violation)
- **SPEC**: Missing or incorrect @spec on public functions
- **TYPO**: Spelling or grammar errors in user-visible strings, docs, or comments
- **ARTIFACT**: Debug prints, commented-out code, TODOs referencing completed work
Do NOT report issues in files you did not actually read.
Do NOT report "likely similar issues exist" without evidence.
"""
@review_prompt "Read every changed file and produce your findings now."
# ---------------------------------------------------------------------------
# AI.Agent behaviour
# ---------------------------------------------------------------------------
@impl AI.Agent
def get_response(args) do
AI.Agent.Composite.run(__MODULE__, args)
end
# ---------------------------------------------------------------------------
# AI.Agent.Composite behaviour
# ---------------------------------------------------------------------------
@impl AI.Agent.Composite
def init(%{agent: agent, prompt: prompt, scope: scope}) do
tools = AI.Tools.basic_tools()
user_prompt = "## Review Scope\n#{scope}\n\n## Instructions\n#{prompt}"
state = %AI.Agent.Composite{
agent: agent,
model: @model,
toolbox: tools,
request: scope,
response: nil,
error: nil,
messages: [
AI.Util.system_msg(AI.Util.project_context()),
AI.Util.system_msg(@prompt),
AI.Util.user_msg(user_prompt)
],
internal: %{},
steps: [
AI.Agent.Composite.completion(:review, @review_prompt,
response_format: AI.Agent.Review.Reviewer.specialist_response_format()
)
]
}
{:ok, state}
end
@impl AI.Agent.Composite
def on_step_start(_step, state) do
UI.report_from(state.agent.name, "Starting pedantic review")
state
end
@impl AI.Agent.Composite
def on_step_complete(_step, state), do: state
@impl AI.Agent.Composite
def get_next_steps(_step, _state), do: []
@impl AI.Agent.Composite
def on_error(_step, _error, state), do: {:halt, state}
end