Changelog
View SourceAll notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Documentation
- README, QUICKSTART.md, STANDALONE.md, STANDALONE_SUMMARY.md, the
OeditusCredomoduledoc, the generated.credo.exs(OeditusCredo.CLI.default_config/0) and the ExDoc module groups now cover all 58 checks. - Documented that
ChangeRiskAntiPatternsandUnsafeMapAccessare the only two opt-in checks, somix oeditus_credoenables 56 of 58 checks.
[0.10.3] - 2026-08-07
Added
mix oeditus_assistant_skill- Generates AI assistant skills (SKILL.md) forclaude,openai, orgeminito run OeditusCredo checks in a lightweight local mode for shaping PRs.mix oeditus_assistant_gha- Generates GitHub Action workflow (.github/workflows/oeditus.yml) and composite action runner (.github/actions/oeditus/) to run automated AI PR reviews on Elixir diffs.
0.10.2 - 2026-08-07
Added
- 5 idiomatic refactoring checks:
PreferStringBoundariesOverRegex- DetectsRegex.match?for prefix/suffix checks instead ofString.starts_with?/2andString.ends_with?/2PreferFunctionCapture- Detectsfn x -> Module.func(x) endinstead of&Module.func/1PreferShortFieldAccessCapture- Detectsfn x -> x.field endinstead of& &1.fieldPreferMapMerge- Detects chainedMap.putcalls instead of a singleMap.merge/2AvoidUnawaitedTaskAsync- Detects fire-and-forgetTask.asyncwhose handle is discarded
0.10.0 - 2026-08-07
Added
- 9 idiomatic refactoring checks:
PreferDestructuring- Detectselem/2andMap.get/2with literal keys instead of pattern match destructuringPreferMultiHeadForNil- Detectsis_nil/1guards instead of multi-head clauses matchingnilPreferWithClause- Detects nestedcasestatements (pyramid of doom) instead ofwithPreferTaggedTuplesForErrors- Detectstry...rescueused as control flow instead of tagged tuplesPreferForComprehensionOverFilterMap- DetectsEnum.filter |> Enum.mapinstead of aforcomprehensionPreferListPrepend- Detects O(N)list ++ [item]appends instead of[item | list]PreferPatternMatchingForEmptiness- DetectsEnum.count(list) > 0instead of matching[_ | _]or[]PreferDotAccessForStructs- Detectsstruct[:field]bracket access instead ofstruct.fieldAvoidSinglePipe- Detects single-stage pipesx |> f()instead of a direct callf(x)
0.9.0 - 2026-08-07
Added
- 6 idiomatic refactoring checks:
PreferCasePatternMatching- Detectsif/condwherecasepattern matching is preferredPreferMultiHeadFunction- Detects parameter branching inside function body instead of multi-head clausesPreferPipelineOperator- Detects sequential assignments instead of pipe operator|>PreferInplaceMapMatching- Detectsis_map/1guard instead of inplace%{} = mappattern matchingPreferInplaceListMatching- Detects O(N)length/1calls in guards instead of[_ | _]or[]PreferInplaceBinaryMatching- Detectsis_binarynon-empty guards instead of<<_::utf8, _::binary>>
0.8.1 - 2026-06-29
Removed
MissingTelemetryInObanWorker- superseded by Oban's native telemetry instrumentation.
0.8.0 - 2026-06-28
Added
ChangeRiskAntiPatterns- Flags functions with a high CRAP (Change Risk Anti-Patterns) score by combining cyclomatic complexity with test coverage. Opt-in/disabled by default; requires runningmix test --cover --export-coverage defaultbeforemix credo. Ports the scoring, complexity, and coverage logic from ExCrap (MIT). See NOTICE.md for attribution.
Changed
- Licensing normalized to MIT; resolved all compiler warnings and Dialyzer findings.
0.6.4 - 2026-05-28
Added
UnnecessaryInterpolatingSigil- Detects~s/~c/~wwithout interpolation (suggests~S/~C/~W); the sigil set is configurable and backslash escapes are skipped.
Changed
SuggestFSMdetection accuracy improved (module attributes, sigil-defined state lists, struct-update transitions).
Removed
MissingTelemetryInLiveViewMount- the check never shipped; documentation references were dropped.
0.5.0 - 2026-05-07
Added
SuggestFSM- Detects imperative status/state management and suggestsFinitomataor:gen_statem.UnsafeMapAccess- Type-aware check for bracket access on maps; requires the optionaltypledependency and Elixir 1.20+.
Changed
- Tightened CWE-200 (
SensitiveDataExposure) detection and completed@moduledoccoverage.
0.4.0 - 2026-04-13
Added
mix oeditus_assistant_rules- Generates.aiassistant/rules/oeditus.mdcoding rules for AI assistants from the enabled checks.
0.3.3 - 2026-03-25
Added
- Support for the general Credo parameters
false(disable) andexit_status: Nacross all checks. exclude_test_filesparameter, backed by the sharedOeditusCredo.Helpers.test_file?/1.
0.3.0 - 2026-03-18
Added
- 17 CWE Top 25 security checks:
SQLInjection,OSCommandInjection,CodeInjection,XSSVulnerability,MissingAuthentication,MissingAuthorization,IncorrectAuthorization,InsecureDirectObjectReference,SensitiveDataExposure,HardcodedCredentials,UnsafeDeserialization,ImproperInputValidation,PathTraversal,UnrestrictedFileUpload,MissingCSRFProtection,SSRFVulnerability,TOCTOU.
Removed
HardcodedValue- superseded by the more preciseHardcodedCredentials.
0.2.0 - 2026-01-19
Added
- Standalone Escript - Build standalone executable with
mix escript.build - Hex Archive Support - Install globally with
mix archive.install - Mix Task -
mix oeditus_credocommand with all checks pre-enabled - CLI Module - Automatic configuration generation
- STANDALONE.md guide with detailed installation and usage instructions
- CI/CD integration examples for GitHub Actions and GitLab CI
Changed
- Updated README with standalone installation options
- Added escript configuration to mix.exs
0.1.0 - 2026-01-18
Added
Error Handling Checks (3)
MissingErrorHandling- Detects{:ok, x} =pattern without error handlingSilentErrorCase- Detects case statements missing error branchesSwallowingException- Detects try/rescue blocks without logging or re-raising
Database & Performance Checks (3)
InefficientFilter- DetectsRepo.allfollowed by Enum filteringNPlusOneQuery- Detects potential N+1 queries (Enum.map with Repo calls)MissingPreload- Detects Ecto queries without proper preloading
LiveView & Concurrency Checks (5)
UnmanagedTask- Detects unsupervisedTask.asynccallsSyncOverAsync- Detects blocking operations in LiveView/GenServer callbacksMissingHandleAsync- Detects blocking in handle_event without async patternMissingThrottle- Detects form inputs without phx-debounce/throttleInlineJavascript- Detects inline JS handlers instead of phx-* bindings
Code Quality Checks (4)
DirectStructUpdate- Detects direct struct updates instead of changesetsCallbackHell- Detects deeply nested case statements (suggestswith)BlockingInPlug- Detects blocking operations in Plug functions
Telemetry & Observability Checks (5)
MissingTelemetryInObanWorker- Detects Oban workers without telemetry instrumentation (removed in 0.8.1)MissingTelemetryInLiveViewMount- Detects LiveView mount/3 without telemetry events (removed in 0.6.4)TelemetryInRecursiveFunction- Detects telemetry inside recursive functions (anti-pattern)MissingTelemetryInAuthPlug- Detects auth/authz plugs without telemetryMissingTelemetryForExternalHttp- Detects HTTP client calls without telemetry wrapper
Documentation
- Comprehensive README with installation and usage instructions
- Detailed documentation for all 20 checks
- Configuration examples and best practices
Testing
- 60+ comprehensive tests covering all checks
- Positive and negative test cases for each check
- Test coverage reporting with ExCoveralls
Licensing
- Released under the MIT License