diff --git a/CHANGELOG.md b/CHANGELOG.md index 46390a9..e38d247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,13 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Changed - -- **Documented what the hardcoded-secret check flags and its one known limit** (all-letter unquoted YAML values), and closed that item as not planned (#625, #635). - -### Fixed - -- **A `rules_engine:` section without `enabled: true` no longer disables the built-in rules.** `enabled` now defaults to `true` when the section is present, so `rules_engine: { max_findings: 0 }` only changes the cap; set `enabled: false` to turn the engine off (#638). +## [0.18.0] - 2026-10-09 ### Security @@ -21,12 +15,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **Documented what the hardcoded-secret check flags and its one known limit** (all-letter unquoted YAML values), and closed that item as not planned (#625, #635). + - **Scanners take file lines instead of diffs (#610).** New `engine::scan_input::ScanFile` (`path`, `language`, `(line number, text)` pairs) is the one input shape for `secrets_scanner::scan_secrets_in`, `security_scanner::scan_security_in`, `rules::run_rules_in` and `inline_suppress::apply_lines`. Diff chunks and whole files are thin adapters (`ScanFile::added_lines`, `ScanFile::post_image`, `ScanFile::from_entry`); `scan_secrets`/`scan_security`/`run_rules`/`inline_suppress::apply` keep their signatures. The `files_as_chunks` workaround and the MCP fake diff are gone. Findings are byte-identical for diffs and scans. Unit tests that open an index session now use a per-test temp database instead of the shared global one. ### Fixed +- **A `rules_engine:` section without `enabled: true` no longer disables the built-in rules.** `enabled` now defaults to `true` when the section is present, so `rules_engine: { max_findings: 0 }` only changes the cap; set `enabled: false` to turn the engine off (#638). + - **`cora.check_snippet` (MCP) now honors `ignore.rules`, inline `cora-ignore:` markers and the false-positive filters, and `rules_engine.max_findings` (#610).** The tool used to run the secrets and security scanners on a fake diff with a fixed cap of 10 per scanner and no filtering, so a snippet could report findings that `cora scan` suppresses. It now goes through the shared post-processing pipeline as a synthetic `snippet.` file (so path-aware classification applies), loads the project config like the other MCP tools (and fails with the same "Failed to load config" error), and mentions how many findings the cap dropped. Output format is unchanged. + - **Secret-detection edge cases (#625, #628, #629, #630).** A string literal inside a constructor wrapper is now a literal: Java `new String("..")`, `Cow::Owned`, `Box::from`, `Secret::new`, Python `str("..")` (plain calls such as `get_password()` stay quiet) (#630). A literal default in the default position of an env read is flagged in code files: `os.environ.get("X", "lit")`, `os.getenv`, `process.env.X || "lit"` / `?? "lit"`, Rust `env::var("X").unwrap_or("lit".into())` / `unwrap_or_else(|_| "lit".to_string())`, Ruby `ENV.fetch`, PHP `getenv() ?:`; the env var name and name-only reads stay quiet (#628). Shell `${VAR:-literal}` / `${VAR:=literal}` is flagged, while `${VAR}`, `${VAR:-}` and `${VAR:?msg}` stay quiet (#629). The unquoted-YAML rule no longer applies to source code (`secret: Secret1Type` in `.ts`/`.py`), YAML flow-style `{ password: hunter2hunter2 }` is flagged, unspaced `password:=os.Getenv("X")` is no longer matched, and SQL `PASSWORD "..."` with double quotes is detected (#625). All-alphabetic unquoted YAML values (`password: correcthorsebattery`) remain undetected, tracked in #635. The LLM secret cross-check uses the same classification. + - **`rules_engine.max_findings` is applied after suppression and truncation is reported (#624).** The cap (default 5) used to be applied inside each scanner, before `ignore.rules` / `cora-ignore`, so suppressed findings consumed slots and pushed real findings out, and the rest were dropped silently. Scanners now run uncapped and the cap is enforced once in post-processing on deterministic findings only (LLM issues are never capped), highest severity first. `cora scan` and `cora review` print `⚠ N more deterministic findings not shown (...)` on stderr when findings are cut, and the `cora scan` summary mentions it; stdout formats are unchanged. `max_findings: 0` or `null` now means unlimited (previously `0` hid every finding). ## [0.17.2] - 2026-10-09 @@ -1008,7 +1008,8 @@ Benchmarked on the cora-code repository (1,864 symbols, 115 Rust files, x86_64): - **Cross-platform** — Linux (x86_64, ARM64), macOS (Apple Silicon), Windows (x86_64) - **MIT License** — fully open source -[Unreleased]: https://github.com/codecoradev/cora-code/compare/v0.17.2...develop +[Unreleased]: https://github.com/codecoradev/cora-code/compare/v0.18.0...develop +[0.18.0]: https://github.com/codecoradev/cora-code/compare/v0.17.2...v0.18.0 [0.17.2]: https://github.com/codecoradev/cora-code/compare/v0.17.1...v0.17.2 [0.17.1]: https://github.com/codecoradev/cora-code/compare/v0.17.0...v0.17.1 [0.17.0]: https://github.com/codecoradev/cora-code/compare/v0.16.1...v0.17.0 diff --git a/Cargo.lock b/Cargo.lock index 9287b14..91402f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -303,7 +303,7 @@ dependencies = [ [[package]] name = "cora-code" -version = "0.17.2" +version = "0.18.0" dependencies = [ "anyhow", "assert_cmd", diff --git a/Cargo.toml b/Cargo.toml index c6048c9..ea391c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cora-code" -version = "0.17.2" +version = "0.18.0" edition = "2024" description = "CLI-first AI code review — BYOK, diff/scan/branch, pre-commit hooks" license = "Apache-2.0"