원클릭으로
condukt-elixir-review
// Project-specific PR-review rules for the Condukt Elixir codebase. Focuses on command execution, cwd scoping, session restore precedence, session store safety, Mimic placement, and the repo's no-typespec convention.
// Project-specific PR-review rules for the Condukt Elixir codebase. Focuses on command execution, cwd scoping, session restore precedence, session store safety, Mimic placement, and the repo's no-typespec convention.
| name | condukt-elixir-review |
| description | Project-specific PR-review rules for the Condukt Elixir codebase. Focuses on command execution, cwd scoping, session restore precedence, session store safety, Mimic placement, and the repo's no-typespec convention. |
This skill is intentionally narrow. Generic Elixir style, naming,
formatting, and pipe-chain hygiene are already covered by mix format
and credo in CI, so do not flag those. Focus on the rules below.
For each finding, cite path:line and quote the relevant snippet.
The repo convention is to use MuonTrap for command execution so child
processes are cleaned up with the calling process.
System.cmd/3, Port.open/2, :os.cmd/1, or another direct OS
process primitive instead of MuonTrap. This breaks the repo's
shutdown guarantees. Severity: high.System.get_env/1, System.fetch_env!/1, System.monotonic_time/0,
and System.system_time/0.Built-in tools and session stores are designed to operate relative to
context[:cwd] or opts[:cwd], not the VM's process cwd. This matters
for multiple agents running concurrently against different directories.
lib/condukt/tools/ that reads or writes
files without first resolving relative paths against context[:cwd]
(or an explicit cwd argument). Severity: high.opts[:cwd] or uses a raw relative path. Severity:
medium.context[:cwd] || File.cwd!() or opts[:cwd]
with unconditional File.cwd!() for file access. Severity:
medium.File.cwd!/0 that are only used as a fallback when no
explicit cwd is available.Condukt.Session.start_link/2 tracks explicit keys and uses
restore_value/3 so persisted session settings never overwrite values
passed directly to start_link/1.
lib/condukt/session.ex that allow persisted snapshots or
application config to override explicit start_link/1 options for
:model, :thinking_level, :system_prompt, :cwd, or :api_key.
Severity: high.:agent_module, :cwd, or custom store options during option
merging. Severity: medium.Condukt.SessionStore.load/1 returns :not_found when no snapshot
exists. Condukt.SessionStore.Disk decodes snapshots with
:erlang.binary_to_term(binary, [:safe]).
nil,
{:error, :enoent}, or another shape instead of :not_found for
missing state. Severity: medium.[:safe] or otherwise deserializes
untrusted Erlang terms unsafely. Severity: high..condukt/session.store under the configured cwd when no explicit
path: was provided. Severity: medium.This repo forbids @spec, @type, @typep, and @opaque in production
Elixir code via the Credo check Condukt.Credo.Check.Readability.NoTypespecs,
whose @forbidden_attributes is exactly [:spec, :type, :typep, :opaque].
Notably, :callback is NOT included - typed @callback declarations are
the idiomatic mechanism for behaviour contracts and are permitted.
@spec, @type, @typep, or @opaque being added to
lib/ for the first time. Do not flag existing typespecs that appear
in a diff due to code movement, refactoring, or line shifts. Only flag
genuinely new type annotations. Severity: medium.@callback and @macrocallback declarations with typed signatures
(e.g., @callback decide(context :: Context.t(), opts :: keyword()) :: :allow | {:deny, term()}). These are the documented contract for
behaviour implementations and are intentionally permitted.@callback declarations that already exist and are only appearing in
diffs due to code movement.rescuePrefer functions and APIs that return tagged tuples, then handle them
with case, with, and pattern matching. Do not add rescue blocks
in lib/ just to normalize control flow. If a boundary truly must
observe non-local failures, keep it narrow and explicit.
rescue blocks in lib/ that are not at a clear system
boundary. Use tagged tuples and pattern matching instead.
Severity: medium.rescue around ordinary control
flow that could be handled with tagged tuples and matching.
Severity: medium.case, with, function heads, or
guards.lib/condukt/sandbox/virtual.ex or
lib/condukt/sandbox/local.ex that handles NIF initialization
failures, MuonTrap execution monitoring, or external library
instrumentation where return values alone cannot capture all failure
modes. Keep such exception handling as narrow as possible.try/catch or try/rescue in test files (outside lib/).test/test_helper.exsThis repo centralizes Mimic.copy(...) in test/test_helper.exs.
Mimic.copy(...) call outside test/test_helper.exs. Per-file
copies are a repo-specific test smell here. Severity: medium.use Mimicexpect/3, stub/3, reject/1set_mimic_from_contextverify_on_exit!/0