Skip to content

feat!: consume the declarative index, drop the pkg_id requirement - #186

Merged
QaidVoid merged 66 commits into
mainfrom
port-format
Aug 1, 2026
Merged

feat!: consume the declarative index, drop the pkg_id requirement#186
QaidVoid merged 66 commits into
mainfrom
port-format

Conversation

@QaidVoid

@QaidVoid QaidVoid commented Jul 29, 2026

Copy link
Copy Markdown
Member

Teaches soar to install from the declarative, hash-pinned index that sbuilder produces, and removes the assumption that every package carries a pkg_id.

Needs pkgforge/sbuilder#16 and pkgforge/soarpkgs#964.

Reading the new index

Published as {format, packages}, so a client can tell an index it cannot read from one that merely lacks a field. Anything without a format is treated as the older format, and existing repositories keep working untouched.

Packages declare their contents rather than having them guessed. files says what comes out of the artifact and where it lands:

"files": [
  {"source": "fd-v10.4.2-x86_64-unknown-linux-musl/fd",   "to": "bin/fd"},
  {"source": "fd-v10.4.2-x86_64-unknown-linux-musl/fd.1", "to": "share/man/man1/fd.1"}
]

to is a path inside the package directory, so where a file lands says what it is. bin/ is a command, share/man/ a manual page, share/*-completion*/ a completion. An empty source means the artifact is itself the file, which is how a bare binary or an AppImage says so, and alias lists other paths resolving to the same file, which is how dunst exposes dunstctl and dunstify.

The layout is built in a staging directory and swapped in at the end, so a source that fails to resolve never leaves a package with its binary deleted. If nothing resolves, the artifact is left as it is rather than installing an empty package. Anything unlisted is pruned, which is how READMEs and changelogs stop being installed.

Linking beyond bin

Manual pages and completions only mean anything where the system looks for them, so they are linked out of the package: man pages beside the bin directory, completions into the per-shell directories, for the shells in completions = [...], defaulting to those whose directory already exists. A destination holding something soar does not own is left alone, and removal takes back only links that resolve into the package being removed.

soar health gains a MANPATH row, shown once a package has installed a manual page. Worth knowing why: man-db discards everything it would derive when MANPATH is set explicitly, which distributions do, so pages can be installed correctly and still be invisible.

pkg_id is optional

A repository whose names are already unique no longer has to invent ids, so pkg_id is nullable throughout and nothing fabricates one. Variants are selected by family instead: the query syntax is family/name, and name#pkg_id still works but warns.

One migration per database. The installed-package table gains pkg_family, the metadata table gains files and drops three columns nothing read, and both relax their pkg_id columns by rebuilding, since SQLite cannot drop NOT NULL in place. The metadata table also gains a COALESCE(pkg_id, '') unique index, because SQLite treats NULLs as distinct and the plain index would have allowed a fresh duplicate row on every sync.

Downgrading refuses rather than deleting installed rows that have no id. The metadata cache, being regenerable, just clears.

Version ordering

Comparison is segment-wise: a version splits into runs of digits and runs of non-digits, and matching runs compare numerically. This fixes 10 sorting below 9 and 1.10 below 1.9.

Semver is deliberately not used. Most published versions carry a rebuild revision as -N, which semver reads as a prerelease and ranks below the plain version, the opposite of what it means here, and plenty of real versions are not valid semver at all. Two commit hashes compare equal, so an arbitrary hash cannot read as an upgrade.

Several versions are not several packages

A repository publishes every version it knows. Installing, running or listing a package by name means the newest, and @version picks another and pins it against update.

Previously any two candidates were treated as ambiguous, the CLI re-resolved the chosen one by name, got the same ambiguity back, and exited silently. That affected install, run, and 8 packages in soarpkgs. The chosen package is now used directly. list and search show one row per package with the other versions named, 18.18.1 (18.17.1), and query orders them newest first.

Identity is repository, family, name and version

Everything that decides "is this the same package" now uses the whole identity. Previously the repository was missing from it, so installing the same name from a second repository did nothing, both variants stayed linked, and two repositories shipping byte-identical builds shared one directory, meaning removal of either destroyed the other's files. Package directories are now named <name>-<version>-<hash>, readable at a glance and unique per install.

run caches per exact package too, and reuses that cache: previously it re-downloaded every time, because it looked for the artifact at a path the layout step had pruned.

Fixes found while testing this

  • Archives are identified by content rather than declared type, so a bare .gz is no longer treated as a tarball
  • Binaries resolve by full path before falling back to the file name, which stops an ARM binary being installed on x86_64
  • Read-only directories from an archive no longer break extraction, layout or removal
  • Removal is ownership-based, so it catches aliases and leaves other people's files alone, and a missing desktop directory no longer abandons it half-done
  • Installed packages are matched by name rather than id, which was breaking upgrades of anything installed earlier

Testing

All 140 non-AppImage packages in soarpkgs install and are verified against what their recipe declares, every path, alias and bin link: 140 passing, 0 failing. Separately sync, list, search, query, install, info, run, download, update, remove, use, json2db and apply are exercised end to end against a local index, including pinning, aliases and multi-version packages.

Summary by CodeRabbit

  • New Features

    • Added support for package families, optional package identifiers, alternate versions, and richer artifact metadata.
    • Packages can define binaries, file layouts, aliases, checksummed extras, man pages, and shell completions.
    • Added version-aware package selection and support for versioned registry metadata.
    • Added manual-page health reporting and improved package caching and execution.
  • Bug Fixes

    • Improved archive extraction, cleanup, package matching, removal, and shared-file handling.
  • Style

    • Simplified CLI output by removing package IDs from progress, status, and error messages.

@QaidVoid QaidVoid changed the title feat: consume the declarative index, drop the pkg_id requirement feat!: consume the declarative index, drop the pkg_id requirement Jul 29, 2026
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR makes package identifiers optional across registry, database, core, operations, and CLI layers. It adds family-aware queries, versioned index parsing, binary and extra-file metadata, custom version comparison, safer extraction and removal handling, and removes package IDs from operation events and most output.

Changes

Declarative package metadata and identity

Layer / File(s) Summary
Package contracts and registry parsing
crates/soar-registry/*, crates/soar-core/src/package/*, crates/soar-utils/src/version.rs
Package IDs become optional. Package families, versioned index parsing, artifact metadata, and custom version comparison are added.
Database schema and nullable repository matching
crates/soar-db/*
Database models and migrations support nullable IDs, package families, binary and extra metadata, family filters, accepted-entry counts, and nullable-aware identity predicates.

Installation and operations

Layer / File(s) Summary
Download and installation flow
crates/soar-dl/src/download.rs, crates/soar-core/src/package/install.rs, crates/soar-operations/src/install.rs
Archive detection, safe extraction promotion, executable-file handling, extra-file installation, and family-aware binary mappings are added.
Operation events and resolution
crates/soar-events/*, crates/soar-operations/*
Operation payloads and result models omit package IDs. Resolution, update, removal, search, health, and progress flows use optional identity fields.

CLI adaptation

Layer / File(s) Summary
CLI queries, imports, and output
crates/soar-cli/src/*, Cargo.toml
CLI queries pass family and optional ID filters. Package displays and logs omit IDs. JSON imports use validated indexes and report accepted and skipped entries.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • pkgforge/soar#119: Extends the registry metadata parsing and package model flow used by this PR.
  • pkgforge/soar#140: Overlaps with package installation, removal, binary linking, and artifact handling.
  • pkgforge/soar#157: Overlaps with the operations workflows and progress bridge updated here.
🚥 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 clearly summarizes the primary changes: declarative index support and removal of the required pkg_id.
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 port-format

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.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 29, 2026

Copy link
Copy Markdown

Deploying soar-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: a1634ce
Status: ✅  Deploy successful!
Preview URL: https://6000691c.soar-docs.pages.dev
Branch Preview URL: https://port-format.soar-docs.pages.dev

View logs

@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: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (13)
crates/soar-core/src/package/local.rs (1)

142-151: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Preserve the local package ID or remove its upstream generation.

from_path still accepts pkg_id_override and constructs self.pkg_id, but to_package no longer copies it. Every local package therefore loses the generated or caller-supplied ID during conversion. Restore the optional pkg_id assignment, or remove the field and override plumbing consistently if this is intentional.

🤖 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/src/package/local.rs` around lines 142 - 151, Update the
to_package conversion to preserve the local package ID by assigning the optional
pkg_id from self.pkg_id, including generated or caller-supplied overrides. Keep
the existing package fields unchanged and ensure the from_path pkg_id_override
plumbing remains consistent.
crates/soar-cli/src/download.rs (1)

153-161: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep the filter arguments aligned in the repository-scoped lookup.

This call passes (name, None, pkg_id, None, ...), while the all-repositories call passes (name, pkg_id, family, None, ...) to the same function. A family/name:repo query therefore drops the family and shifts pkg_id into a different filter slot, which can select the wrong variant or return no match. Pass query.pkg_id.as_deref() and query.family.as_deref() in the same positions as the global lookup.

🤖 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/download.rs` around lines 153 - 161, Update the
repository-scoped MetadataRepository::find_filtered call to match the argument
ordering used by the all-repositories lookup: pass query.pkg_id.as_deref() and
query.family.as_deref() in their corresponding filter positions, preserving the
remaining arguments.
crates/soar-operations/src/update.rs (1)

138-147: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Keep variant identity when finding repository updates.

Line 140 no longer constrains the lookup by identifier or family. If a repository contains multiple family/name variants, this can select the newest version from a different family and install it over the current package. Extend find_newer_version and this call with the installed package’s family and optional identifier identity.

🤖 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/update.rs` around lines 138 - 147, Update
MetadataRepository::find_newer_version and its call in the new_pkg lookup to
accept and apply the installed package’s family and optional identifier,
alongside the package name and version. Ensure repository updates only select
newer versions matching the current package variant identity before converting
and resolving the result.
crates/soar-cli/src/install.rs (1)

244-251: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Honor family/name in --show queries.

Both candidate queries pass None for the family filter, so soar install --show family/name displays candidates from every family instead of the requested one.

  • crates/soar-cli/src/install.rs#L244-L251: pass query.family.as_deref() as the family argument.
  • crates/soar-cli/src/install.rs#L264-L271: pass the same family filter in the all-repositories branch.
🤖 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/install.rs` around lines 244 - 251, The candidate queries
in install --show must honor the requested family filter. In both
MetadataRepository::find_filtered calls in crates/soar-cli/src/install.rs at
lines 244-251 and 264-271, pass query.family.as_deref() as the family argument
instead of None.
crates/soar-db/migrations/metadata/2026-07-29-000000-0000_pkg_id_optional/down.sql (1)

1-3: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Down migration doesn't restore pkg_id NOT NULL.

The paired up.sql rebuilds the table to relax pkg_id to nullable (SQLite can't ALTER COLUMN). This down.sql only drops the index and deletes NULL rows — it never rebuilds the table to restore the NOT NULL constraint, so rolling back leaves the schema in a mixed state that doesn't match the pre-migration schema.

🔧 Suggested mirror-rebuild approach
DROP INDEX IF EXISTS packages_identity;
DELETE FROM packages WHERE pkg_id IS NULL;

CREATE TABLE packages_new (
  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  pkg_id TEXT NOT NULL COLLATE NOCASE,
  pkg_family TEXT COLLATE NOCASE,
  pkg_name TEXT NOT NULL COLLATE NOCASE,
  -- ... remaining columns unchanged from the pre-migration schema
);

INSERT INTO packages_new SELECT
  id, pkg_id, pkg_family, pkg_name, /* ... */
FROM packages;

DROP TABLE packages;
ALTER TABLE packages_new RENAME TO packages;
🤖 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/migrations/metadata/2026-07-29-000000-0000_pkg_id_optional/down.sql`
around lines 1 - 3, Update the down migration to rebuild the packages table
after removing NULL pkg_id rows, restoring the pre-migration schema with pkg_id
defined as NOT NULL. Mirror the up migration’s table-rebuild approach, preserve
all columns, constraints, indexes, and data, then replace the relaxed table with
the rebuilt one.

Source: Linters/SAST tools

crates/soar-core/src/package/install.rs (2)

271-279: 🗄️ Data Integrity & Integration | 🔴 Critical | 🏗️ Heavy lift

package.pkg_family never reaches the disambiguation queries.

has_pending_install/delete_pending_installs (and later unlink_others/find_alternates in record()) are only given pkg_id/pkg_name/repo_name/version. self.package.pkg_family is available but unused here — see the companion comment on crates/soar-db/src/repository/core.rs for the root cause and full impact.

Also applies to: 306-329

🤖 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/src/package/install.rs` around lines 271 - 279, Update the
pending-install checks in the install flow around has_pending_install and the
related delete_pending_installs calls to pass self.package.pkg_family through to
the repository APIs. Ensure the corresponding record() calls to unlink_others
and find_alternates also receive the package family so all disambiguation
queries use it.

808-839: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Missing pre-rename cleanup for existing destination entries.

This rename loop lacks the to.exists() handling used in the extract_root (Lines 909-915) and nested_extract (Lines 976-982) blocks just below. On a resumed/retried install where install_dir already contains a leftover file/directory from a prior attempt, fs::rename(&from, &to) will fail here (non-empty directory or existing file), aborting the install instead of overwriting stale leftovers the way the other two blocks do.

🔧 Proposed fix
                     let from = entry.path();
                     let to = self.install_dir.join(entry.file_name());
+                    if to.exists() {
+                        if to.is_dir() {
+                            fs::remove_dir_all(&to).ok();
+                        } else {
+                            fs::remove_file(&to).ok();
+                        }
+                    }
                     // Renaming a directory rewrites its `..`, so the directory
🤖 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/src/package/install.rs` around lines 808 - 839, Update the
rename loop in the extracted-install block to remove any existing destination
entry at `to` before calling `fs::rename(&from, &to)`, matching the cleanup
behavior in the `extract_root` and `nested_extract` blocks. Preserve the
existing contextual error handling and continue treating stale files or
directories as replaceable leftovers.
crates/soar-db/src/repository/core.rs (2)

327-471: 🗄️ Data Integrity & Integration | 🔴 Critical | 🏗️ Heavy lift

pkg_family isn't threaded through package-disambiguation logic. Both sites stem from the same gap: pkg_family was added to distinguish variants once pkg_id became optional, but it never reaches the queries/calls that decide which installed row is "the same package."

  • crates/soar-db/src/repository/core.rs#L327-L471: add a pkg_family: Option<&str> parameter to find_alternates, unlink_others, unlink_others_by_checksum, get_old_package_paths, delete_old_packages (and ideally the other pkg_id-based lookups) and include it in the match predicate alongside match_pkg_id.
  • crates/soar-core/src/package/install.rs#L271-L329: pass self.package.pkg_family.as_deref() into the has_pending_install, delete_pending_installs, unlink_others, and find_alternates calls once the repository signatures accept 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-db/src/repository/core.rs` around lines 327 - 471, Thread
pkg_family through package disambiguation: in
crates/soar-db/src/repository/core.rs lines 327-471, add Option<&str> parameters
to find_alternates, unlink_others, unlink_others_by_checksum,
get_old_package_paths, delete_old_packages, and other pkg_id-based lookups as
applicable, incorporating it alongside match_pkg_id in predicates. In
crates/soar-core/src/package/install.rs lines 271-329, pass
self.package.pkg_family.as_deref() to has_pending_install,
delete_pending_installs, unlink_others, and find_alternates; update all affected
callers and preserve existing matching behavior.

327-346: 🗄️ Data Integrity & Integration | 🔴 Critical | 🏗️ Heavy lift

Package disambiguation queries don't consider the new pkg_family column.

find_alternates, unlink_others, unlink_others_by_checksum, get_old_package_paths, delete_old_packages, find_exact, find_by_pkg_id_and_repo, find_by_pkg_id_name_and_repo, record_installation, update_pkg_id, has_pending_install, delete_pending_installs, and link_by_checksum match rows using only pkg_name plus optional pkg_id. With nullable pkg_id and the new pkg_family column, unrelated families sharing a pkg_name can be treated as the same package; unlink_others/get_old_package_paths/delete_old_packages can then unlink or delete an unrelated installation.

Add pkg_family: Option<&str> to these repository methods and thread self.package.pkg_family through the call sites in crates/soar-core/src/package/install.rs.

🤖 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/repository/core.rs` around lines 327 - 346, Add a
pkg_family: Option<&str> parameter to find_alternates and the other listed
repository methods, and include pkg_family in their package-matching filters
alongside pkg_name/pkg_id. Update the corresponding calls in the install flow to
pass self.package.pkg_family, preserving existing behavior while preventing
operations from crossing package families.
crates/soar-operations/src/apply.rs (1)

70-78: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Pass pkg_id and pkg_family in their declared positions. find_filtered expects ID before family, but both calls provide None for ID and put the package ID in the family slot.

  • crates/soar-operations/src/apply.rs#L70-L78: pass pkg.pkg_id.as_deref() as the second filter and None as the family filter.
  • crates/soar-operations/src/switch.rs#L118-L126: pass selected_package.pkg_id.as_deref() as the second filter and None as the family filter.
🤖 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 70 - 78, Correct both
MetadataRepository::find_filtered calls in crates/soar-operations/src/apply.rs
lines 70-78 and crates/soar-operations/src/switch.rs lines 118-126: pass
pkg.pkg_id.as_deref() or selected_package.pkg_id.as_deref() as the ID filter,
followed by None for the package-family filter, preserving all other arguments.
crates/soar-operations/src/install.rs (1)

266-293: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not use an absent ID as an unscoped variant filter. None disables the pkg_id predicate, rather than selecting rows with a null ID.

  • crates/soar-operations/src/install.rs#L266-L293: when target_pkg_id is absent, constrain the metadata query by the selected name/family instead of querying every package.
  • crates/soar-operations/src/install.rs#L306-L317: apply the same name/family fallback to installed-package lookup.
  • crates/soar-operations/src/remove.rs#L96-L110: for an ID-less selected package, keep removal scoped to its name rather than resolving all repository packages.
🤖 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/install.rs` around lines 266 - 293, The metadata
queries currently treat an absent target_pkg_id as an unscoped filter; update
the selected-package lookup in install.rs lines 266-293 and installed-package
lookup in install.rs lines 306-317 to use the selected package name/family when
the ID is absent, while retaining ID filtering when present. Apply the same
name-scoped fallback to the removal lookup in remove.rs lines 96-110 so ID-less
packages resolve only within their selected name.
crates/soar-core/src/package/url.rs (1)

250-273: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve the generated package ID for remote installs.

Both branches now default Package::pkg_id to None, although UrlPackage always derives an ID. Later URL status checks filter by that ID, so the existing install is not found and can be reinstalled repeatedly. Set pkg_id: Some(self.pkg_id.clone()) in both literals.

🤖 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/src/package/url.rs` around lines 250 - 273, Preserve the
derived package ID when constructing the installed Package values in both
branches of the UrlPackage conversion. Add pkg_id using
Some(self.pkg_id.clone()) to each Package literal so URL status checks can find
existing remote installations.
crates/soar-db/src/repository/metadata.rs (1)

570-616: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Nullable pkg_id may defeat dedup on re-import via on_conflict_do_nothing().

The insert relies on UNIQUE (pkg_id, pkg_name, version) (per the original packages create-table) to make on_conflict_do_nothing() skip already-imported rows and return Ok(false). Under standard SQL/SQLite semantics, NULL is never equal to NULL for UNIQUE-constraint purposes, so two imports of the same pkg_name+version with pkg_id = None (the common case for the new declarative index format this PR targets) will not conflict — each re-import/refresh will insert a duplicate row instead of being skipped, growing the table and confusing later find_by_name/find_filtered queries.

This may already be handled if crates/soar-db/migrations/metadata/2026-07-29-000000-0000_pkg_id_optional/up.sql redefines the unique index (e.g., unique on (pkg_name, version) alone, or on a coalesced expression), but that file isn't in this review batch.

#!/bin/bash
cat crates/soar-db/migrations/metadata/2026-07-29-000000-0000_pkg_id_optional/up.sql
rg -n "UNIQUE" crates/soar-db/src/schema/metadata.rs crates/soar-db/migrations/metadata -g '*.sql'
🤖 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/repository/metadata.rs` around lines 570 - 616, Ensure
duplicate detection in the package insertion flow remains effective when pkg_id
is None: update the migration/schema constraint or the insert logic around
NewPackage and diesel::insert_into so repeated imports with the same pkg_name
and version conflict and return Ok(false). Verify the existing uniqueness
definition is adjusted without weakening deduplication for populated pkg_id
values.
🤖 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/install.rs`:
- Around line 79-81: The ambiguity re-resolution currently loses the selected
package variant by querying only name:repo and ignoring the resolved result. In
crates/soar-cli/src/install.rs lines 79-81, preserve the selected candidate’s
full family-aware identity or install that candidate directly; apply the same
identity-preserving fix in the --show fallback at lines 202-204.

In `@crates/soar-cli/src/json2db.rs`:
- Around line 55-64: Update the json2db import flow around
MetadataRepository::import_packages so validation and import occur in a
temporary database or transaction rather than the existing output database. Only
atomically replace the output after imported is greater than zero; when all
packages are rejected, preserve the prior database unchanged.

In `@crates/soar-cli/src/update.rs`:
- Around line 29-32: Update the CLI messages using update_info and the
corresponding download and switch confirmation flows to include family and/or
repository context alongside pkg_name, preserving enough identity to distinguish
variants without restoring deprecated pkg_id syntax. Apply this to the update
preview in crates/soar-cli/src/update.rs lines 29-32, the update failure log in
crates/soar-cli/src/update.rs line 52, the download log in
crates/soar-cli/src/download.rs line 215, and the switch confirmation in
crates/soar-cli/src/use.rs line 60.

In `@crates/soar-cli/src/utils.rs`:
- Around line 136-143: Update the installed-package matching logic around
is_installed so it never treats a missing pkg.pkg_id() as an empty identity. Use
package name together with family/repository, or another stable resolved
identity, and revise the producer of the installed tuples to provide the same
identity fields so current and older installs match correctly.

In `@crates/soar-db/src/repository/metadata.rs`:
- Around line 442-473: Update find_newer_version to accept the installed package
family and filter candidates by both pkg_name and pkg_family, matching the
disambiguation behavior in find_filtered. Thread the new family argument through
all callers while preserving the existing version comparison and selection
logic.

In `@crates/soar-dl/src/download.rs`:
- Around line 345-349: Update the extraction flow around compak::extract_archive
so it always extracts into a dedicated temporary child directory rather than the
caller-owned extract_dir. On extraction failure, remove only that temporary
directory; preserve the existing caller-supplied directory and downloaded
archive, while retaining the current warning behavior.

In `@crates/soar-operations/src/install.rs`:
- Around line 834-849: The checksum-less directory suffix currently hashes only
pkg_name and version, causing distinct sources or variants to collide; update
the fallback hash input in the installation path logic to also include a stable
source identity, preferring pkg_id when available and otherwise the package URL
or GHCR reference, while preserving the existing 12-character suffix behavior.

In `@crates/soar-operations/src/list.rs`:
- Around line 60-77: Update the installed_pkgs construction in the list
filtering flow to merge duplicate (repo_name, pkg_name) records with logical OR
semantics, so any record with is_installed=true marks the package installed.
Replace the direct HashMap collect behavior with an aggregation that preserves
the existing key lookup used for entries.

In `@crates/soar-operations/src/search.rs`:
- Around line 58-67: The installed package aggregation in the `installed_pkgs`
construction must combine duplicate `(repo_name, pkg_name)` entries with logical
OR instead of allowing `collect()` to overwrite values arbitrarily. Update the
`into_par_iter` reduction/collection so any matching row with `is_installed ==
true` produces a true aggregate.

In `@crates/soar-operations/src/update.rs`:
- Around line 443-451: Update the install-report success tracking around the
succeeded set and the target cleanup loop to use a stable per-target identity
rather than pkg_name alone. Preserve that identity when recording installed
packages, key succeeded by it, and use the matching target identity for
membership checks so packages from different repositories, families, or variants
cannot share success status.

In `@crates/soar-package/src/formats/common.rs`:
- Around line 294-301: Update the no-pkg_id branch of the portable_dir_base
derivation around package.pkg_id() to include the package family alongside
package.pkg_name(), using the existing family-aware discriminator exposed by
PackageExt. Keep the current package-name-and-id format unchanged for packages
with pkg_id, while ensuring family-a/foo and family-b/foo produce distinct
portable directory bases.

In `@crates/soar-utils/src/version.rs`:
- Around line 30-50: Update compare_versions to detect when both inputs are
hash-only versions and return Ordering::Equal before segment comparison,
preventing distinct commit hashes from determining upgrade or downgrade
decisions. Reuse the existing hash-detection helper or add one near
compare_versions, and preserve normal semantic comparison for non-hash versions.

---

Outside diff comments:
In `@crates/soar-cli/src/download.rs`:
- Around line 153-161: Update the repository-scoped
MetadataRepository::find_filtered call to match the argument ordering used by
the all-repositories lookup: pass query.pkg_id.as_deref() and
query.family.as_deref() in their corresponding filter positions, preserving the
remaining arguments.

In `@crates/soar-cli/src/install.rs`:
- Around line 244-251: The candidate queries in install --show must honor the
requested family filter. In both MetadataRepository::find_filtered calls in
crates/soar-cli/src/install.rs at lines 244-251 and 264-271, pass
query.family.as_deref() as the family argument instead of None.

In `@crates/soar-core/src/package/install.rs`:
- Around line 271-279: Update the pending-install checks in the install flow
around has_pending_install and the related delete_pending_installs calls to pass
self.package.pkg_family through to the repository APIs. Ensure the corresponding
record() calls to unlink_others and find_alternates also receive the package
family so all disambiguation queries use it.
- Around line 808-839: Update the rename loop in the extracted-install block to
remove any existing destination entry at `to` before calling `fs::rename(&from,
&to)`, matching the cleanup behavior in the `extract_root` and `nested_extract`
blocks. Preserve the existing contextual error handling and continue treating
stale files or directories as replaceable leftovers.

In `@crates/soar-core/src/package/local.rs`:
- Around line 142-151: Update the to_package conversion to preserve the local
package ID by assigning the optional pkg_id from self.pkg_id, including
generated or caller-supplied overrides. Keep the existing package fields
unchanged and ensure the from_path pkg_id_override plumbing remains consistent.

In `@crates/soar-core/src/package/url.rs`:
- Around line 250-273: Preserve the derived package ID when constructing the
installed Package values in both branches of the UrlPackage conversion. Add
pkg_id using Some(self.pkg_id.clone()) to each Package literal so URL status
checks can find existing remote installations.

In
`@crates/soar-db/migrations/metadata/2026-07-29-000000-0000_pkg_id_optional/down.sql`:
- Around line 1-3: Update the down migration to rebuild the packages table after
removing NULL pkg_id rows, restoring the pre-migration schema with pkg_id
defined as NOT NULL. Mirror the up migration’s table-rebuild approach, preserve
all columns, constraints, indexes, and data, then replace the relaxed table with
the rebuilt one.

In `@crates/soar-db/src/repository/core.rs`:
- Around line 327-471: Thread pkg_family through package disambiguation: in
crates/soar-db/src/repository/core.rs lines 327-471, add Option<&str> parameters
to find_alternates, unlink_others, unlink_others_by_checksum,
get_old_package_paths, delete_old_packages, and other pkg_id-based lookups as
applicable, incorporating it alongside match_pkg_id in predicates. In
crates/soar-core/src/package/install.rs lines 271-329, pass
self.package.pkg_family.as_deref() to has_pending_install,
delete_pending_installs, unlink_others, and find_alternates; update all affected
callers and preserve existing matching behavior.
- Around line 327-346: Add a pkg_family: Option<&str> parameter to
find_alternates and the other listed repository methods, and include pkg_family
in their package-matching filters alongside pkg_name/pkg_id. Update the
corresponding calls in the install flow to pass self.package.pkg_family,
preserving existing behavior while preventing operations from crossing package
families.

In `@crates/soar-db/src/repository/metadata.rs`:
- Around line 570-616: Ensure duplicate detection in the package insertion flow
remains effective when pkg_id is None: update the migration/schema constraint or
the insert logic around NewPackage and diesel::insert_into so repeated imports
with the same pkg_name and version conflict and return Ok(false). Verify the
existing uniqueness definition is adjusted without weakening deduplication for
populated pkg_id values.

In `@crates/soar-operations/src/apply.rs`:
- Around line 70-78: Correct both MetadataRepository::find_filtered calls in
crates/soar-operations/src/apply.rs lines 70-78 and
crates/soar-operations/src/switch.rs lines 118-126: pass pkg.pkg_id.as_deref()
or selected_package.pkg_id.as_deref() as the ID filter, followed by None for the
package-family filter, preserving all other arguments.

In `@crates/soar-operations/src/install.rs`:
- Around line 266-293: The metadata queries currently treat an absent
target_pkg_id as an unscoped filter; update the selected-package lookup in
install.rs lines 266-293 and installed-package lookup in install.rs lines
306-317 to use the selected package name/family when the ID is absent, while
retaining ID filtering when present. Apply the same name-scoped fallback to the
removal lookup in remove.rs lines 96-110 so ID-less packages resolve only within
their selected name.

In `@crates/soar-operations/src/update.rs`:
- Around line 138-147: Update MetadataRepository::find_newer_version and its
call in the new_pkg lookup to accept and apply the installed package’s family
and optional identifier, alongside the package name and version. Ensure
repository updates only select newer versions matching the current package
variant identity before converting and resolving the result.
🪄 Autofix (Beta)

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: 460f5f0c-292b-42f2-b8ad-be9ccfb6dff8

📥 Commits

Reviewing files that changed from the base of the PR and between 0059732 and 4715fb3.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (64)
  • Cargo.toml
  • crates/soar-cli/src/apply.rs
  • crates/soar-cli/src/download.rs
  • crates/soar-cli/src/health.rs
  • crates/soar-cli/src/inspect.rs
  • crates/soar-cli/src/install.rs
  • crates/soar-cli/src/json2db.rs
  • crates/soar-cli/src/list.rs
  • crates/soar-cli/src/progress.rs
  • crates/soar-cli/src/remove.rs
  • crates/soar-cli/src/run.rs
  • crates/soar-cli/src/update.rs
  • crates/soar-cli/src/use.rs
  • crates/soar-cli/src/utils.rs
  • crates/soar-core/src/database/models.rs
  • crates/soar-core/src/package/install.rs
  • crates/soar-core/src/package/local.rs
  • crates/soar-core/src/package/query.rs
  • crates/soar-core/src/package/remove.rs
  • crates/soar-core/src/package/update.rs
  • crates/soar-core/src/package/url.rs
  • crates/soar-db/migrations/core/2026-07-28-000000-0000_add_pkg_family/down.sql
  • crates/soar-db/migrations/core/2026-07-28-000000-0000_add_pkg_family/up.sql
  • crates/soar-db/migrations/core/2026-07-29-000000-0000_pkg_id_optional/down.sql
  • crates/soar-db/migrations/core/2026-07-29-000000-0000_pkg_id_optional/up.sql
  • crates/soar-db/migrations/metadata/2026-07-28-000000-0000_add_binaries/down.sql
  • crates/soar-db/migrations/metadata/2026-07-28-000000-0000_add_binaries/up.sql
  • crates/soar-db/migrations/metadata/2026-07-28-000001-0000_drop_webpage_tags/down.sql
  • crates/soar-db/migrations/metadata/2026-07-28-000001-0000_drop_webpage_tags/up.sql
  • crates/soar-db/migrations/metadata/2026-07-28-000002-0000_add_extra/down.sql
  • crates/soar-db/migrations/metadata/2026-07-28-000002-0000_add_extra/up.sql
  • crates/soar-db/migrations/metadata/2026-07-29-000000-0000_pkg_id_optional/down.sql
  • crates/soar-db/migrations/metadata/2026-07-29-000000-0000_pkg_id_optional/up.sql
  • crates/soar-db/src/migration.rs
  • crates/soar-db/src/models/core.rs
  • crates/soar-db/src/models/metadata.rs
  • crates/soar-db/src/models/types.rs
  • crates/soar-db/src/repository/core.rs
  • crates/soar-db/src/repository/metadata.rs
  • crates/soar-db/src/schema/core.rs
  • crates/soar-db/src/schema/metadata.rs
  • crates/soar-dl/src/download.rs
  • crates/soar-events/src/event.rs
  • crates/soar-operations/src/apply.rs
  • crates/soar-operations/src/context.rs
  • crates/soar-operations/src/health.rs
  • crates/soar-operations/src/install.rs
  • crates/soar-operations/src/list.rs
  • crates/soar-operations/src/progress.rs
  • crates/soar-operations/src/remove.rs
  • crates/soar-operations/src/run.rs
  • crates/soar-operations/src/search.rs
  • crates/soar-operations/src/switch.rs
  • crates/soar-operations/src/types.rs
  • crates/soar-operations/src/update.rs
  • crates/soar-operations/src/utils.rs
  • crates/soar-package/src/formats/common.rs
  • crates/soar-package/src/traits.rs
  • crates/soar-registry/src/error.rs
  • crates/soar-registry/src/lib.rs
  • crates/soar-registry/src/metadata.rs
  • crates/soar-registry/src/package.rs
  • crates/soar-utils/src/lib.rs
  • crates/soar-utils/src/version.rs
💤 Files with no reviewable changes (5)
  • crates/soar-db/src/migration.rs
  • crates/soar-operations/src/types.rs
  • crates/soar-events/src/event.rs
  • crates/soar-operations/src/health.rs
  • crates/soar-operations/src/progress.rs

Comment thread crates/soar-cli/src/install.rs Outdated
Comment thread crates/soar-cli/src/json2db.rs Outdated
Comment on lines +29 to 32
"{}: {} -> {}",
Colored(Blue, &update_info.pkg_name),
Colored(Cyan, &update_info.pkg_id),
Colored(Red, &update_info.current_version),
Colored(Green, &update_info.new_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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve variant and repository context when removing pkg_id from CLI messages.

pkg_name is not unique once family/name variants exist. These messages should retain family and/or repository context so users can distinguish operations without restoring the deprecated ID syntax.

  • crates/soar-cli/src/update.rs#L29-L32: include family/repository context in update previews.
  • crates/soar-cli/src/update.rs#L52-L52: include the same context in failure logs.
  • crates/soar-cli/src/download.rs#L215-L215: include family/repository context in download logs.
  • crates/soar-cli/src/use.rs#L60-L60: include the selected family/repository in switch confirmations.
📍 Affects 3 files
  • crates/soar-cli/src/update.rs#L29-L32 (this comment)
  • crates/soar-cli/src/update.rs#L52-L52
  • crates/soar-cli/src/download.rs#L215-L215
  • crates/soar-cli/src/use.rs#L60-L60
🤖 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/update.rs` around lines 29 - 32, Update the CLI messages
using update_info and the corresponding download and switch confirmation flows
to include family and/or repository context alongside pkg_name, preserving
enough identity to distinguish variants without restoring deprecated pkg_id
syntax. Apply this to the update preview in crates/soar-cli/src/update.rs lines
29-32, the update failure log in crates/soar-cli/src/update.rs line 52, the
download log in crates/soar-cli/src/download.rs line 215, and the switch
confirmation in crates/soar-cli/src/use.rs line 60.

Comment thread crates/soar-cli/src/utils.rs Outdated
Comment thread crates/soar-db/src/repository/metadata.rs
Comment thread crates/soar-operations/src/list.rs Outdated
Comment thread crates/soar-operations/src/search.rs Outdated
Comment thread crates/soar-operations/src/update.rs Outdated
Comment thread crates/soar-package/src/formats/common.rs Outdated
Comment thread crates/soar-utils/src/version.rs

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/soar-db/migrations/metadata/2026-07-28-000000-0000_declarative_format/up.sql (1)

64-65: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Include pkg_family in the identity index.

Declarative packages use pkg_family as the identity instead of pkg_id, so this index still groups different families with the same pkg_name and version into the same COALESCE(pkg_id, '') bucket and makes those variants unrecoverable inserts that conflict with each other.

🤖 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/migrations/metadata/2026-07-28-000000-0000_declarative_format/up.sql`
around lines 64 - 65, Update the packages_identity unique index to include
pkg_family in the indexed identity columns, preserving the existing pkg_id,
pkg_name, and version components so declarative packages from different families
do not conflict.
🤖 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-db/migrations/core/2026-07-28-000000-0000_declarative_format/down.sql`:
- Line 2: Replace the unconditional NULL-ID deletion in the core downgrade
migration with a guard that aborts clearly when installed package rows have
pkg_id IS NULL, rather than deleting them. Apply the same pre-delete guard to
the metadata downgrade migration for NULL-ID metadata rows; update both
specified migration files accordingly.

---

Outside diff comments:
In
`@crates/soar-db/migrations/metadata/2026-07-28-000000-0000_declarative_format/up.sql`:
- Around line 64-65: Update the packages_identity unique index to include
pkg_family in the indexed identity columns, preserving the existing pkg_id,
pkg_name, and version components so declarative packages from different families
do not conflict.
🪄 Autofix (Beta)

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: 362731b8-f02d-4d4b-887a-046a68286552

📥 Commits

Reviewing files that changed from the base of the PR and between 4715fb3 and a72ee19.

📒 Files selected for processing (4)
  • crates/soar-db/migrations/core/2026-07-28-000000-0000_declarative_format/down.sql
  • crates/soar-db/migrations/core/2026-07-28-000000-0000_declarative_format/up.sql
  • crates/soar-db/migrations/metadata/2026-07-28-000000-0000_declarative_format/down.sql
  • crates/soar-db/migrations/metadata/2026-07-28-000000-0000_declarative_format/up.sql

Comment thread crates/soar-db/migrations/core/2026-07-28-000000-0000_declarative_format/down.sql Outdated

@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: 1

🤖 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-config/src/packages.rs`:
- Around line 337-349: Update PackageSpec::resolve so declarative installs no
longer copy defaults.install_patterns or opts.install_patterns into
ResolvedPackage.globs. Keep legacy install-pattern handling confined to the
OCI-specific path, and ensure declarative installation preserves the complete
package contents without applying these deprecated patterns.
🪄 Autofix (Beta)

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: 7e368202-cd4f-448b-a4cf-5bc4e331be38

📥 Commits

Reviewing files that changed from the base of the PR and between a72ee19 and 203b5c0.

📒 Files selected for processing (9)
  • crates/soar-cli/src/health.rs
  • crates/soar-config/src/config.rs
  • crates/soar-config/src/packages.rs
  • crates/soar-core/src/package/install.rs
  • crates/soar-core/src/package/url.rs
  • crates/soar-events/src/lib.rs
  • crates/soar-operations/src/install.rs
  • crates/soar-operations/src/progress.rs
  • crates/soar-operations/src/utils.rs
💤 Files with no reviewable changes (1)
  • crates/soar-events/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • crates/soar-operations/src/utils.rs
  • crates/soar-cli/src/health.rs
  • crates/soar-operations/src/progress.rs
  • crates/soar-operations/src/install.rs
  • crates/soar-core/src/package/install.rs

Comment thread crates/soar-config/src/packages.rs
QaidVoid added 26 commits August 1, 2026 14:29
The original-repo lookup passed the installed id into the family
parameter, and update matching dropped the id entirely, so either could
resolve to a different package of the same name.
The uniqueness key omitted the family, so two variants publishing no id
collided and the second was dropped on import.
A failed extraction was warned about and the package recorded as
installed with nothing in it. Local files now detect the format first,
so a plain binary is no longer run through the extractor.
An install directory carries its version, so links from the old one read
as foreign and were left dangling. The bin/ fallback also no longer
overrides a package that declares its own binaries.
Hashes compared equal to each other but segment-wise against a tag, so
the ordering was intransitive and could panic sort_by.
An archive shipping read-only directories made the removal of a
superseded version fail, and the failure was discarded, so the tree and
its row stayed behind.
Requiring both to differ, and comparing against a NULL id, meant the
alternate lookup returned the wrong set either way.
Scripted edits left five public items carrying the previous item's
documentation, and one attribute on the wrong function.
A file listed twice is now copied rather than moved a second time, a
failure part-way puts back what it took, an alias outside its target's
directory gets a path that resolves, and the install marker is kept.
Two identity checks in one function disagreed, and the post-lock recheck
could not narrow by family at all.
The cache key left out the repository its comment claimed to cover, and a
laid-out binary that is the artifact itself is now checked against the
published checksum before it is executed.
An untagged enum reports only that no variant matched, so the index
shape is now told apart by its opening character.
The tree was re-walked for every binary mapping, and when several files
answered to one name each overwrote the last silently.
Linking and unlinking each carried their own copy, so a directory added
to one would have been missed by the other.
Both had stopped using the checksum they were named for, and one was
byte-for-byte what unlink_others already did.
list and search carried the same key, index and predicate verbatim.
A NULL id made COUNT(DISTINCT) skip the row entirely, a raw projection
could not load one, and an empty id from an index behaved as a real one.
Unanchored, a/b/c matched from the middle and silently dropped a.
find_exact and find_alternates take the family, and the lookups that
cannot filter on it compare it themselves, preferring the installed row
over whichever came first.
The ambiguity prompt rendered two candidates identically, rerun resolved
by name alone, and the unique count folded them together.
It comes from metadata, so one holding .. would place the portable
directory outside the portable root.
A fixed name let a second import delete the database the first was still
building. Also documents a diagnostic code and corrects a field comment.
packages.toml gains 'family', which is what the declarative format
publishes to tell identically-named projects apart. 'pkg_id' still
parses and is marked deprecated, so every remaining read is flagged.
Dropping the old table cascades portable_package empty and leaves
deferred violations a rename cannot clear, so foreign keys are turned
off, which is only possible outside a transaction. A published metadata
database is migrated on fetch; it was queried with whatever schema built
it.
No repository ever published it and 'files' says more.
Walking one that does not exist failed the whole check.
@QaidVoid
QaidVoid merged commit 3a35ad7 into main Aug 1, 2026
10 checks passed
@QaidVoid QaidVoid mentioned this pull request Aug 1, 2026
github-actions Bot pushed a commit to Azathothas/soar that referenced this pull request Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant