KogenCredo
View SourceCredo checks for recurring generated-code mistakes and verification integrity: error handling, test quality, global state, structural limits and query regressions.
Version 0.1.0. Source: KogenAI/kogen_credo.
Start here
- Check catalog: detectors, defaults, limits and source links.
- Explicit configuration example: select checks and supply project-specific parameters before enabling them in CI.
- Diff checks: compare changed functions with their base.
- Migration guide: names moved from OptimumCredo.
- Changelog: version history and release changes.
Installation
Add the Hex dependency:
{:kogen_credo, "~> 0.1.0", only: [:dev, :test], runtime: false}Requires Credo 1.7.19 or newer in the 1.x series. When adopting this version, update Credo together with it; an older locked Credo does not provide the token metadata these checks need, and older releases cannot lint Elixir 1.20 reliably.
For development with a sibling checkout:
defp deps do
[
{:kogen_credo, path: "../kogen_credo", only: [:dev, :test], runtime: false}
]
endEnable individual checks in .credo.exs:
%{
configs: [
%{
name: "default",
checks: %{
enabled: [
{KogenCredo.Check.Warning.SkippedTest, []},
{KogenCredo.Check.Readability.JustifiedCoverageIgnore, []},
{KogenCredo.Check.Warning.BroadRescue, []},
{KogenCredo.Check.Warning.RepoAllThenTrim, []}
]
}
}
]
}Run mix credo --strict to include low-priority advice. Neither installing this
library nor copying a package example establishes the right policy for an
application. Review actual findings and configure namespaces, codecs, domain
roots, allowed serial tests and resource groups where needed.
OptimumCredo remains independent and owns code-review preferences. Enable both libraries where useful, choosing between overlapping policies deliberately.
Integrity and static-analysis limits
KogenCredo.Integrity provides suppression scanning and comparison with a golden
Credo configuration. Parsing a configuration for comparison does not evaluate
arbitrary Elixir. Store golden policy in a location the code-writing agent cannot
change. The library cannot establish that trust boundary by itself.
NoCredoDisable is an advisory Credo detector, not a tamper-proof enforcement
mechanism: Credo can suppress its own checks. The separate integrity scan exists
for enforcement outside Credo's suppression pipeline.
mix kogen.unused_public reports public functions with no observed compiled
caller. It is advisory by default and needs compiled debug information. Callbacks,
entry points, external library consumers, dynamic dispatch and macros limit what
static analysis can establish; read the task/module documentation before acting.
Module names
Analysed code names modules, it does not load them. Aliases, imports, defmodule nesting,
__MODULE__ and module parameters are resolved to dotted names (MyApp.Repo; Erlang modules keep
their colon, :ets) and compared as strings, so code whose modules are not compiled, not loaded
or do not exist is analysed like any other, and no atom is created for a module the analysis only
reads. Module parameters keep the form they always had: atoms for broad_exceptions,
codec_modules, ForbiddenCall calls, stub_exceptions, shared and domain namespaces
(a string is still rejected, so a typo cannot look like "nothing configured"); full-name strings
for repo_modules. Repo names, function names and fields (including the diff CLI's
--sensitive-field, --cast-sensitive-field and --repo-name) are compared by name and are
never turned into atoms. Only mix kogen.unused_public handles real module atoms, because it
reads installed BEAM debug information. KogenCredo.Integrity.parse_config/1 returns modules
written in a config as KogenCredo.Integrity.ModuleRef structs for the same reason.
Framework boundaries and test scope
StringKeyAccess recognises literal Phoenix/Oban/Ecto callback boundaries,
connection fields, JSON query paths and directly encoded wire documents. Other
wire adapters still need codec_modules or codec_globs. Recognition is static;
it does not track values across arbitrary calls or variable shadowing.
The ForbiddenCall async-test preset uses only_async: true rules and checks
literal async: true modules. Explicit rules can inspect other scopes. SizeLimits
excludes ~H markup from function length; use count_template_lines: true to count it.
Checks that infer test state through custom case templates need a case_templates
map, for example %{"MyApp.DataCase" => :inherit, "MyAppWeb.ConnCase" => :inherit}.
Supply it to the relevant checks before treating zero findings as coverage of
those templates. Serial-case exemptions should describe reviewed shared resources.
Development
After mix deps.get, run make ci for formatting, compilation, tests,
strict Credo and documentation checks. The individual commands are:
mix deps.get
mix test
mix format --check-formatted
mix compile --warnings-as-errors
mix credo --strict
The checked-in self-lint policy (mix credo --strict) reports no findings. Passing it, like
test/format/compile success, says nothing about the precision of the detectors.
Test violations, valid lookalikes, parameter changes and lexical scope. Run the suite across supported Elixir versions before publication. New diff rules remain advisory until their precision is demonstrated on real history; unit tests alone are not that evidence.
Folder map: lib/kogen_credo/check/ owns Credo detectors;
lib/kogen_credo/diff/ owns function comparison and reporting;
lib/mix/tasks/ owns command entry points; remaining library modules own shared
analysis helpers and integrity checks; test/ owns regression coverage; docs/
owns the catalog and usage/migration details.
Origin and license
EmptySetupBlock, JustifiedCoverageIgnore, RuntimeEnvDevDefault and
SkippedTest originated in OptimumCredo and retain its copyright notice. Other
checks grow from the retained Kogen research prototypes and original
implementations. The two packages do not depend on one another.
MIT. See LICENSE.