Skip to content

chore: release - #193

Closed
QaidVoid wants to merge 2 commits into
mainfrom
release-plz-2026-08-10T11-04-26Z
Closed

chore: release#193
QaidVoid wants to merge 2 commits into
mainfrom
release-plz-2026-08-10T11-04-26Z

Conversation

@QaidVoid

@QaidVoid QaidVoid commented Aug 10, 2026

Copy link
Copy Markdown
Member

🤖 New release

  • soar-registry: 0.6.1 -> 0.6.2 (✓ API compatible changes)
  • soar-db: 0.6.1 -> 0.6.2 (✓ API compatible changes)
  • soar-events: 0.2.0 -> 0.3.0 (⚠ API breaking changes)
  • soar-operations: 0.4.1 -> 0.4.2 (✓ API compatible changes)
  • soar-cli: 0.13.1 -> 0.13.2
  • soar-core: 0.17.1 -> 0.17.2

soar-events breaking changes

--- failure enum_no_repr_variant_discriminant_changed: enum variant had its discriminant change value ---

Description:
The enum's variant had its discriminant value change. This breaks downstream code that used its value via a numeric cast like `as isize`.
        ref: https://doc.rust-lang.org/reference/items/enumerations.html#assigning-discriminant-values
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.48.0/src/lints/enum_no_repr_variant_discriminant_changed.ron

Failed in:
  variant SoarEvent::Log 19 -> 20 in /tmp/.tmpKsODG2/soar/crates/soar-events/src/event.rs:124

--- failure enum_variant_added: enum variant added on exhaustive enum ---

Description:
A publicly-visible enum without #[non_exhaustive] has a new variant.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#enum-variant-new
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.48.0/src/lints/enum_variant_added.ron

Failed in:
  variant SoarEvent:ApplyComplete in /tmp/.tmpKsODG2/soar/crates/soar-events/src/event.rs:117
Changelog

soar-registry

0.6.2 - 2026-08-10

⛰️ Features

  • (cli) Expose soar to frontends with JSON output and a plugin manifest (#192) - (1ea7f51)

soar-db

0.6.2 - 2026-08-10

⛰️ Features

  • (cli) Expose soar to frontends with JSON output and a plugin manifest (#192) - (1ea7f51)

soar-events

0.3.0 - 2026-08-10

⛰️ Features

  • (cli) Expose soar to frontends with JSON output and a plugin manifest (#192) - (1ea7f51)

soar-operations

0.4.2 - 2026-08-10

⛰️ Features

  • (cli) Expose soar to frontends with JSON output and a plugin manifest (#192) - (1ea7f51)

soar-cli

0.13.2 - 2026-08-10

⛰️ Features

  • (cli) Expose soar to frontends with JSON output and a plugin manifest (#192) - (1ea7f51)

soar-core

0.17.2 - 2026-08-10

⚙️ Miscellaneous Tasks

  • Updated the following local packages: soar-db, soar-events - (0000000)


This PR was generated with release-plz.

Summary by CodeRabbit

  • New Features

    • Added --json output for package searches, listings, details, repositories, environment information, updates, and apply results.
    • Added JSON Lines event streaming for progress and operation events.
    • Added the plugin-manifest command for frontend integrations.
    • Added update --check to preview pending updates without making changes.
    • Apply operations now report installed, updated, removed, and failed totals.
  • Bug Fixes

    • Improved package search results by including maintainer information when available.
    • Improved database connection reliability during concurrent access.

@QaidVoid QaidVoid added the release New Release (Probably Automated) label Aug 10, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 10, 2026

Copy link
Copy Markdown

Deploying soar-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: df2a2b3
Status: ✅  Deploy successful!
Preview URL: https://d9562c3a.soar-docs.pages.dev
Branch Preview URL: https://release-plz-2026-08-10t11-04.soar-docs.pages.dev

View logs

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The CLI now supports structured JSON output, JSON event streams, update checks, environment serialization, and a generated plugin manifest. Event serialization, database connection preparation, maintainer lookup, package versions, and release changelogs were also updated.

Changes

Frontend integration

Layer / File(s) Summary
JSON and event contracts
crates/soar-events/..., crates/soar-cli/src/json_output.rs
Added stable JSON models for CLI data and JSON-lines serialization for SoarEvent.
CLI JSON command flow
crates/soar-cli/src/{main.rs,apply.rs,list.rs,repo.rs,update.rs,logging.rs,utils.rs}
JSON mode now routes events and logs across streams and emits structured results for supported commands.
Plugin manifest generation
crates/soar-cli/src/{cli.rs,main.rs,plugin_manifest.rs}
Added the plugin-manifest command and generated TOML manifest with command mappings and profiles.
Operation and database support
crates/soar-operations/src/{apply.rs,search.rs}, crates/soar-db/src/connection.rs
Apply operations emit completion counts, searches populate maintainers, and database connections share busy-timeout and WAL preparation.
Release metadata and dependency alignment
CHANGELOG.md, Cargo.toml, crates/*/{Cargo.toml,CHANGELOG.md}, crates/soar-registry/src/package.rs
Updated workspace versions and changelogs. Removed the documentation claim that pkg_id is required.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Frontend
  participant SoarCLI
  participant SoarContext
  participant JsonLinesSink
  Frontend->>SoarCLI: invoke command with --json
  SoarCLI->>SoarContext: create context for document or event output
  SoarContext->>JsonLinesSink: route events to stdout or stderr
  SoarCLI-->>Frontend: emit JSON document or JSON listing
Loading

Possibly related PRs

  • pkgforge/soar#192: Contains the same frontend JSON-output and plugin-manifest changes.
  • pkgforge/soar#158: Introduced the shared SoarContext CLI flows extended here.
  • pkgforge/soar#157: Introduced operation APIs extended for apply diffs and event serialization.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately identifies this pull request as a release that bumps package versions and publishes the frontend integration changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release-plz-2026-08-10T11-04-26Z

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (2)
crates/soar-cli/src/plugin_manifest.rs (1)

260-283: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extend the test to check flags, not only subcommand names.

every_operation_names_a_real_subcommand validates the first non-flag argument only. The manifest also hardcodes flags such as --check, --dry-run, --prune, --yes and the global --json. If any of these flags is renamed or removed, the manifest silently breaks the frontend contract while the test still passes. Clap exposes get_arguments() per subcommand, so the same introspection can validate each long flag.

♻️ Sketch for flag validation
for (op, table) in parsed["ops"].as_table().expect("ops table") {
    let args: Vec<&str> = table["args"]
        .as_array()
        .expect("args array")
        .iter()
        .filter_map(|a| a.as_str())
        .collect();

    let subcommand = args
        .iter()
        .find(|a| !a.starts_with('-'))
        .unwrap_or_else(|| panic!("{op} names no subcommand"));

    let cmd = crate::cli::Args::command();
    let global: Vec<String> = cmd
        .get_arguments()
        .filter_map(|a| a.get_long().map(String::from))
        .collect();
    let sub = cmd
        .find_subcommand(subcommand)
        .unwrap_or_else(|| panic!("{op} runs `{subcommand}`, which this soar does not have"));
    let local: Vec<String> = sub
        .get_arguments()
        .filter_map(|a| a.get_long().map(String::from))
        .collect();

    for flag in args.iter().filter_map(|a| a.strip_prefix("--")) {
        assert!(
            global.iter().chain(local.iter()).any(|k| k == flag),
            "{op} passes `--{flag}`, which `{subcommand}` does not accept"
        );
    }
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/soar-cli/src/plugin_manifest.rs` around lines 260 - 283, Extend
every_operation_names_a_real_subcommand to collect each operation’s string
arguments, then validate every long flag against Clap’s global arguments from
Args::command().get_arguments() and the selected subcommand’s arguments from
find_subcommand(). Preserve the existing subcommand validation and report the
operation, flag, and subcommand when a manifest flag is unsupported.
crates/soar-operations/src/search.rs (1)

351-355: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy lift

Batch maintainer lookups by repository.

When a query returns many packages, Lines 353-355 execute one MetadataRepository::get_maintainers query for each package. The supplied implementation in crates/soar-db/src/repository/metadata.rs, Lines 414-426, loads maintainers for one package_id, so this adds an N+1 query pattern to query_package. Group package IDs by repository and load the mappings in one query per repository.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/soar-operations/src/search.rs` around lines 351 - 355, Replace the
per-package MetadataRepository::get_maintainers call in query_package with
repository-grouped batch lookups: collect package IDs by repo_name, execute one
maintainer query per repository, then apply each returned mapping to the
corresponding packages while preserving existing maintainer data behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/soar-cli/src/plugin_manifest.rs`:
- Around line 30-33: Update the generated manifest’s [detect] min_version value
instead of reusing `@version`@, setting it to the oldest soar release compatible
with this schema. Keep the version field tied to CARGO_PKG_VERSION while
ensuring independently upgraded soar versions remain accepted.
- Around line 235-246: The manifest function currently formats profile names
with Rust debug syntax, which can produce invalid TOML; serialize profiles using
TOML-compatible values or escaping before replacing `@profiles`@. Update the
profile-list construction in manifest while preserving the existing empty-list
and comma-separated template substitution behavior.

In `@crates/soar-core/CHANGELOG.md`:
- Line 6: Update the changelog entry for the local package updates to replace
the placeholder 0000000 link with the actual commit hash, or remove the commit
link if no valid hash is available.

In `@crates/soar-db/src/connection.rs`:
- Around line 33-38: Update the WAL setup in the connection initialization flow
to use get_result instead of execute, capture the returned journal-mode string,
and verify that it is WAL before emitting the success trace. If SQLite reports a
different mode, handle it as a connection error before migrations proceed.

In `@crates/soar-events/CHANGELOG.md`:
- Around line 2-6: Update the 0.3.0 entry in CHANGELOG.md to document the
breaking SoarEvent API changes: SoarEvent::Log now uses discriminant 20 instead
of 19, and SoarEvent::ApplyComplete is newly added. Explicitly state that
exhaustive matches and discriminant-based consumers must migrate before
upgrading.

In `@crates/soar-operations/src/apply.rs`:
- Around line 364-369: Update the package configuration update error paths in
the apply flow—each PackagesConfig::update_package failure around the
installation, update, and removal handling—to increment failed_count before
logging/continuing, then emit the resulting value through ApplyComplete.
Preserve existing handling for successful writes and other operation failures.

In `@crates/soar-operations/src/search.rs`:
- Around line 353-371: Handle errors from the maintainer lookup in the
enrichment flow around metadata_mgr.query_repo instead of discarding them
through if let Ok(Some(...)). Either propagate the query error, or if enrichment
remains best-effort, log it with package.repo_name and package.id while
preserving the existing handling for successful Some and None results.

---

Nitpick comments:
In `@crates/soar-cli/src/plugin_manifest.rs`:
- Around line 260-283: Extend every_operation_names_a_real_subcommand to collect
each operation’s string arguments, then validate every long flag against Clap’s
global arguments from Args::command().get_arguments() and the selected
subcommand’s arguments from find_subcommand(). Preserve the existing subcommand
validation and report the operation, flag, and subcommand when a manifest flag
is unsupported.

In `@crates/soar-operations/src/search.rs`:
- Around line 351-355: Replace the per-package
MetadataRepository::get_maintainers call in query_package with
repository-grouped batch lookups: collect package IDs by repo_name, execute one
maintainer query per repository, then apply each returned mapping to the
corresponding packages while preserving existing maintainer data behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2018967a-74c5-4642-911e-81895294b305

📥 Commits

Reviewing files that changed from the base of the PR and between ae017bd and df2a2b3.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (29)
  • CHANGELOG.md
  • Cargo.toml
  • crates/soar-cli/Cargo.toml
  • crates/soar-cli/src/apply.rs
  • crates/soar-cli/src/cli.rs
  • crates/soar-cli/src/json_output.rs
  • crates/soar-cli/src/list.rs
  • crates/soar-cli/src/logging.rs
  • crates/soar-cli/src/main.rs
  • crates/soar-cli/src/plugin_manifest.rs
  • crates/soar-cli/src/repo.rs
  • crates/soar-cli/src/update.rs
  • crates/soar-cli/src/utils.rs
  • crates/soar-core/CHANGELOG.md
  • crates/soar-core/Cargo.toml
  • crates/soar-db/CHANGELOG.md
  • crates/soar-db/Cargo.toml
  • crates/soar-db/src/connection.rs
  • crates/soar-events/CHANGELOG.md
  • crates/soar-events/Cargo.toml
  • crates/soar-events/src/event.rs
  • crates/soar-events/src/sink.rs
  • crates/soar-operations/CHANGELOG.md
  • crates/soar-operations/Cargo.toml
  • crates/soar-operations/src/apply.rs
  • crates/soar-operations/src/search.rs
  • crates/soar-registry/CHANGELOG.md
  • crates/soar-registry/Cargo.toml
  • crates/soar-registry/src/package.rs
💤 Files with no reviewable changes (1)
  • crates/soar-registry/src/package.rs

Comment on lines +30 to +33
[detect]
command = "soar"
version = ["--version"]
min_version = "@version@"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

min_version repeats the emitting binary version.

Line 17 sets version to CARGO_PKG_VERSION. Line 33 sets min_version to the same value. A frontend that compares its installed soar against min_version therefore accepts only that version or newer, which is stricter than the real requirement. State the oldest soar release that satisfies this schema instead, so the manifest stays usable when soar is upgraded independently of the frontend.

🐛 Proposed fix
+/// The oldest soar that answers the commands in this manifest.
+const MIN_VERSION: &str = "0.13.2";
+
 [detect]
 command = "soar"
 version = ["--version"]
-min_version = "`@version`@"
+min_version = "`@min_version`@"
     TEMPLATE
         .replace("`@schema_version`@", &SCHEMA_VERSION.to_string())
         .replace("`@version`@", env!("CARGO_PKG_VERSION"))
+        .replace("`@min_version`@", MIN_VERSION)
         .replace("`@profiles`@", &options)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/soar-cli/src/plugin_manifest.rs` around lines 30 - 33, Update the
generated manifest’s [detect] min_version value instead of reusing `@version`@,
setting it to the oldest soar release compatible with this schema. Keep the
version field tied to CARGO_PKG_VERSION while ensuring independently upgraded
soar versions remain accepted.

Comment on lines +235 to +246
pub fn manifest(profiles: &[String]) -> String {
let options = profiles
.iter()
.map(|profile| format!("{profile:?}"))
.collect::<Vec<_>>()
.join(", ");

TEMPLATE
.replace("@schema_version@", &SCHEMA_VERSION.to_string())
.replace("@version@", env!("CARGO_PKG_VERSION"))
.replace("@profiles@", &options)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Rust String Debug escaping rules versus TOML basic string escape sequences

💡 Result:

Rust's String Debug escaping and TOML's basic string escape sequences are distinct mechanisms with different purposes, resulting in notable differences in their implementation. Rust Debug Escaping Rust's str::escape_debug (used by the Debug trait) is intended for diagnostic output, aiming to make hidden characters visible [1]. Its primary rules are: - It escapes non-printable ASCII characters and most non-printable Unicode characters (including control characters, some separators, and unassigned characters) [2]. - It commonly represents these using either compact escape sequences (e.g., \t, \r, \n) or hexadecimal Unicode escapes (e.g., \u{XXXX}) [2]. - It does not strictly define a single standard across all versions, as implementation details—such as the handling of combining characters or single quotes—have evolved and occasionally been flagged as inconsistent [3][4]. - It is designed to be human-readable for debugging rather than as a strict data-interchange format [1]. TOML Basic String Escaping TOML v1.0.0 defines strict, interoperable rules for basic string escape sequences [5][6]. A TOML-compliant parser must handle the following specific sequences: - Compact escapes: \b (backspace, U+0008), \t (tab, U+0009), \n (linefeed, U+000A), \f (form feed, U+000C), \r (carriage return, U+000D), " (quote, U+0022), and \ (backslash, U+005C) [5][6]. - Unicode escapes: \uXXXX (4-digit hex) and \UXXXXXXXX (8-digit hex), which must represent valid Unicode scalar values [5][6]. - Any other escape sequence starting with a backslash is reserved and results in a parsing error [5][6]. Key Differences - Strictness: TOML is a formal specification where unknown backslash-escapes are errors [5][6]. Rust's escape_debug is an implementation detail for developer visibility, not a strict grammar [1][2]. - Compatibility: While there is some overlap (e.g., \t, \n, \r, \), they are not identical. Rust's escape_debug does not produce TOML-compliant output by default. For instance, Rust may output \u{XXXX} (braced), while TOML requires \uXXXX (unbraced) [3][5]. Furthermore, Rust's escape_debug may escape single quotes (depending on context), whereas TOML basic strings do not require or provide a standard escape for single quotes [3][5]. - Purpose: Rust's method prioritizes visibility of potentially problematic characters (like invisible separators), while TOML prioritizes data integrity and successful deserialization [1][5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files matching manifest/toml:"
fd -a 'manifest|Cargo' . | sed 's#^\./##' | head -80

echo
echo "Locate plugin_manifest.rs:"
fd -a 'plugin_manifest\.rs' . | sed 's#^\./##'

echo
echo "Relevant file outline/section:"
file="$(fd 'plugin_manifest\.rs' . | head -1)"
if [ -n "${file:-}" ]; then
  wc -l "$file"
  sed -n '200,260p' "$file" | nl -ba -v200
fi

echo
echo "Cargo toml dependency declarations:"
rg -n 'toml\s*=' Cargo.toml crates -g 'Cargo.toml' || true

echo
echo "Search for manifest/profile usage:"
rg -n 'profile|manifest\(|manifests|`@profiles`@' crates/soar-cli Cargo.toml -g '*.rs' -g 'Cargo.toml' || true

Repository: pkgforge/soar

Length of output: 986


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json, re, subprocess
# Read-only behavioral probe: determine whether this Rust repo has toml toolchain available
# and exercise serde_d2 if present; do not modify repository files.
PY

Repository: pkgforge/soar

Length of output: 151


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "plugin_manifest.rs relevant section:"
sed -n '200,270p' crates/soar-cli/src/plugin_manifest.rs

echo
echo "Cargo manifest dependencies mentioning toml:"
rg -n 'toml(\s+|\.|\|)|serde( |_toml)?|crate-type|dev-dependencies|build-dependencies' Cargo.toml crates -g 'Cargo.toml' || true

echo
echo "Check installed Rust tools:"
(command -v cargo && cargo --version) || true
(command -v rustc && rustc --version) || true

echo
echo "If cargo is available, compile a Rust Stdlib behavior probe for String Debug escaping:"
if [ "$(command -v cargo 2>/dev/null)" != "" ]; then
  tmp="$(mktemp -d)"
  cargo new --quiet "$tmp"
  cat > "$tmp/src/main.rs" <<'RS'
fn main() {
    for s in ["profile", "profile\n", "profile\t", "profile\u{A0}", "profile\u{200B}"] {
        let quote = format!("{:?}", s);
        println!("{:?}\t{:?}", s, quote);
    }
}
RS
  (cd "$tmp" && cargo run --quiet 2>&1 | sed -n '1,80p')
  rm -rf "$tmp"
fi

Repository: pkgforge/soar

Length of output: 5035


Serialize the profile list into TOML instead of using format!("{profile:?}").

{profile:?} emits Rust debug output, not TOML string content. TOML and Rust Debug escape sequences can differ; for example, TOML basic strings use \uXXXX, while Rust Debug uses braced Unicode escapes such as \u{XXXX}. A profile name containing such a character can make the manifest invalid TOML. Use toml::value::Value::Array or TOML escaping before replacing @profiles@.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/soar-cli/src/plugin_manifest.rs` around lines 235 - 246, The manifest
function currently formats profile names with Rust debug syntax, which can
produce invalid TOML; serialize profiles using TOML-compatible values or
escaping before replacing `@profiles`@. Update the profile-list construction in
manifest while preserving the existing empty-list and comma-separated template
substitution behavior.


### ⚙️ Miscellaneous Tasks

- Updated the following local packages: soar-db, soar-events - ([0000000](https://github.com/pkgforge/soar/commit/0000000))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Tracked CHANGELOG files:"
git ls-files | grep -E '(^|/)CHANGELOG\.md$' | sed -n '1,50p'

echo
echo "Crates soar-core CHANGELOG first lines:"
if [ -f crates/soar-core/CHANGELOG.md ]; then
  nl -ba crates/soar-core/CHANGELOG.md | sed -n '1,20p'
else
  echo "crates/soar-core/CHANGELOG.md not found"
fi

echo
echo "Occurrences of 0000000 in tracked files:"
rg -n --hidden --glob '!target/**' '0000000' . || true

echo
echo "SHA validity check for placeholder:"
python3 - <<'PY'
import subprocess
result = subprocess.run(['git', 'cat-file', '-e', '0000000'], capture_output=True, text=True, check=False)
print(f"git cat-file -e 0000000 exit code={result.returncode}")
print(result.stderr)
PY

Repository: pkgforge/soar

Length of output: 555


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Crates soar-core CHANGELOG context:"
if [ -f crates/soar-core/CHANGELOG.md ]; then
  sed -n '1,25p' crates/soar-core/CHANGELOG.md
else
  echo "crates/soar-core/CHANGELOG.md not found"
fi

echo
echo "Occurrences of 0000000 in tracked files:"
if command -v rg >/dev/null 2>&1; then
  rg -n --hidden --glob '!target/**' '0000000' . || true
else
  grep -RIn --exclude-dir=target '0000000' . || true
fi

echo
echo "SHA validity check for placeholder:"
if command -v git >/dev/null 2>&1; then
  git cat-file -e 0000000
  echo exit="$?"
elif command -v gsha1sum >/dev/null 2>&1; then
  printf '0000000' | gsha1sum
else
  echo "no git or gsha1sum available"
fi

Repository: pkgforge/soar

Length of output: 6377


Replace the placeholder commit hash.

0000000 is not a valid commit and makes this changelog link return a 404. Replace it with the actual commit hash or remove the link before publishing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/soar-core/CHANGELOG.md` at line 6, Update the changelog entry for the
local package updates to replace the placeholder 0000000 link with the actual
commit hash, or remove the commit link if no valid hash is available.

Comment on lines +33 to +38
// WAL mode for better concurrent access
sql_query("PRAGMA journal_mode = WAL;")
.execute(conn)
.map_err(|e| ConnectionError::BadConnection(e.to_string()))?;

trace!("busy timeout and WAL journal mode set");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n 'diesel' --glob 'Cargo.toml' --glob 'Cargo.lock' || true
rg -n -C 4 'PRAGMA (busy_timeout|journal_mode)|sql_query|batch_execute' \
  crates/soar-db/src/connection.rs

if command -v sqlite3 >/dev/null 2>&1; then
  mode="$(sqlite3 ':memory:' 'PRAGMA journal_mode = WAL;')"
  printf 'in-memory journal mode: %s\n' "$mode"
  test "$mode" = "memory"
fi

Repository: pkgforge/soar

Length of output: 151


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Repo files of interest:\n'
git ls-files | rg '(^Cargo\.(toml|lock)$|crates/soar-db/src/connection\.rs$|Cargo\.cargo\.toml$|\.cargo/config\.toml$)' || true

printf '\nconnection.rs outline:\n'
ast-grep outline crates/soar-db/src/connection.rs --view expanded || true

printf '\nconnection.rs relevant lines:\n'
cat -n crates/soar-db/src/connection.rs | sed -n '1,180p'

printf '\nDiesel entries:\n'
for f in Cargo.toml Cargo.lock crates/soar-db/Cargo.toml; do
  if [ -f "$f" ]; then
    echo "--- $f"
    rg -n -C 3 'diesel|sqlite|rusqlite' "$f" || true
  fi
done

if command -v sqlite3 >/dev/null 2>&; then
  printf '\nSQLite PRAGMA mode behavior examples:\n'
  for file in ':memory:' '/tmp/test-journalmode.db' '/tmp/test-journalmode.db-wal'; do
    rm -f "/tmp/test-journalmode.db"{,} "-shm" "-wal" 2>/dev/null || true
  done
  for pragma in 'PRAGMA journal_mode = WAL;' 'PRAGMA journal_mode = DELETE;' 'PRAGMA journal_mode'; do
    printf 'PRAGMA: %s => ' "$pragma"
    sqlite3 ':memory:' "$pragma"
  done
  sqlite3 /tmp/test-journalmode.db-wb "PRAGMA journal_mode = WAL; SELECT 'after switch:' || (SELECT page_count FROM pragma_page_count); PRAGMA journal_mode;" rm -f /tmp/test-journalmode.db-wb* 2>/dev/null || true
fi

Repository: pkgforge/soar

Length of output: 12998


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'SQLite PRAGMA mode behavior examples:\n'
for file in '/tmp/test-journalmode.db' '/tmp/test-journalmode.db-wal'; do
  rm -f "$file"{,-shm,-wal} 2>/dev/null || true
done

for mode in delete memory wal; do
  file="/tmp/test-journalmode-$mode.db"
  rm -f "${file}"{,-shm,-wal} 2>/dev/null || true
  current="$(sqlite3 "$file" "PRAGMA journal_mode; PRAGMA journal_mode = WAL; PRAGMA journal_mode = DELETE;")"
  printf 'initial=%s current after set-wal=%s final=%s\n' "$mode" "$current"
  rm -f "${file}"{,-shm,-wal} 2>/dev/null || true
done

# Try to read the returned value as Diesel can via .get_result(), without using repo code or creating files.
python3 - <<'PY'
import sqlite3
conn = sqlite3.connect(":memory:")
row = conn.execute("PRAGMA journal_mode = WAL;").fetchone()
print("PRAGMA row:", row)
print("effective_mode:", row[0] if row else None)
PY

Repository: pkgforge/soar

Length of output: 235


🌐 Web query:

SQLite PRAGMA journal_mode documentation returns journal mode

💡 Result:

The SQLite PRAGMA journal_mode command is used to query or set the journaling mode for the current database connection [1][2][3]. When executed, the pragma returns a string representing the journal mode that is currently in effect [4][5]. When used to query the current mode, the pragma returns the string value of the active journal mode (e.g., "delete", "wal", "truncate", "persist", "memory", or "off") [1][4][3]. When used to set a new journal mode (e.g., PRAGMA journal_mode = WAL;), the pragma also returns a string [4]. On success, this returned string is the new journal mode (e.g., "wal") [4][5]. If the requested conversion cannot be completed—for example, if the VFS lacks necessary support—the journaling mode remains unchanged, and the pragma returns the string of the prior (existing) journaling mode [4][5].

Citations:


Check the returned journal mode before tracing WAL setup.

PRAGMA journal_mode = WAL returns the journal mode in effect. If SQLite cannot switch to WAL, it returns the previous mode and keeps that mode. The current .execute() call discards this value, so the trace can report WAL mode while operations later run under a different journal mode. Use .get_result(...) to inspect the returned string and fail or handle the fallback before migrations.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/soar-db/src/connection.rs` around lines 33 - 38, Update the WAL setup
in the connection initialization flow to use get_result instead of execute,
capture the returned journal-mode string, and verify that it is WAL before
emitting the success trace. If SQLite reports a different mode, handle it as a
connection error before migrations proceed.

Source: MCP tools

Comment on lines +2 to +6
## [0.3.0](https://github.com/pkgforge/soar/compare/soar-events-v0.2.0...soar-events-v0.3.0) - 2026-08-10

### ⛰️ Features

- *(cli)* Expose soar to frontends with JSON output and a plugin manifest ([#192](https://github.com/pkgforge/soar/pull/192)) - ([1ea7f51](https://github.com/pkgforge/soar/commit/1ea7f51c854c007de53b734de5a3892baaba2c2e))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Document the breaking soar-events API changes.

The 0.3.0 entry only lists the frontend feature. Add the SoarEvent::Log discriminant change from 19 to 20 and the new SoarEvent::ApplyComplete variant. State that exhaustive matches and discriminant-based consumers require migration before upgrade.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/soar-events/CHANGELOG.md` around lines 2 - 6, Update the 0.3.0 entry
in CHANGELOG.md to document the breaking SoarEvent API changes: SoarEvent::Log
now uses discriminant 20 instead of 19, and SoarEvent::ApplyComplete is newly
added. Explicitly state that exhaustive matches and discriminant-based consumers
must migrate before upgrading.

Comment on lines +364 to +369
ctx.events().emit(SoarEvent::ApplyComplete {
installed: installed_count,
updated: updated_count,
removed: removed_count,
failed: failed_count,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Count configuration-write failures in ApplyComplete.

failed_count increases only from installation and removal reports. The PackagesConfig::update_package failures at Lines 224-229, 267-273, and 313-319 are logged but do not change failed_count. A failed write can therefore produce failed: 0 while packages.toml remains stale. Increment failed_count for these failures, or add a separate configuration-write failure field before emitting ApplyComplete.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/soar-operations/src/apply.rs` around lines 364 - 369, Update the
package configuration update error paths in the apply flow—each
PackagesConfig::update_package failure around the installation, update, and
removal handling—to increment failed_count before logging/continuing, then emit
the resulting value through ApplyComplete. Preserve existing handling for
successful writes and other operation failures.

Comment on lines +353 to +371
let found = metadata_mgr.query_repo(&package.repo_name, |conn| {
MetadataRepository::get_maintainers(conn, package.id as i32)
});

if let Ok(Some(maintainers)) = found {
let named: Vec<_> = maintainers
.into_iter()
.map(|m| {
soar_core::database::models::Maintainer {
name: m.name,
contact: m.contact,
}
})
.collect();

if !named.is_empty() {
package.maintainers = Some(named);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Do not silently convert maintainer lookup errors into missing data.

The if let Ok(Some(...)) condition drops every Err from metadata_mgr.query_repo. A lock or schema error then returns a package without maintainers, and JSON consumers cannot distinguish that result from a package with no maintainers. If best-effort enrichment is intentional, log the error with package.repo_name and package.id; otherwise propagate it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/soar-operations/src/search.rs` around lines 353 - 371, Handle errors
from the maintainer lookup in the enrichment flow around metadata_mgr.query_repo
instead of discarding them through if let Ok(Some(...)). Either propagate the
query error, or if enrichment remains best-effort, log it with package.repo_name
and package.id while preserving the existing handling for successful Some and
None results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release New Release (Probably Automated)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant