Skip to content

Kp/refactor url#139

Closed
kitplummer wants to merge 53 commits intogtri:developfrom
kitplummer:kp/refactor_url
Closed

Kp/refactor url#139
kitplummer wants to merge 53 commits intogtri:developfrom
kitplummer:kp/refactor_url

Conversation

@kitplummer
Copy link
Collaborator

No description provided.

kitplummer and others added 30 commits February 5, 2026 10:26
Add .runtime/, .claude/, .beads/, and .logs/ directories to gitignore
for Gas Town multi-agent tooling support.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- mix.exs: Update elixir constraint to ~> 1.14
- hex_publish.yml: Update container image to elixir:1.14-alpine

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add production Dockerfile (Dockerfile.prod) with multi-stage build:
  - Builder stage for compiling Elixir app
  - SBOM generator stage using syft for CycloneDX and SPDX formats
  - Runtime stage with minimal Alpine image, non-root user, tini init
- Add config/prod.exs with air-gapped mode support
- Add zarf.yaml package definition with components:
  - lei-image: Container image build
  - lei-cli: Entrypoint scripts
  - lei-config: Configuration files
  - lei-sbom: SBOM extraction
  - lei-k8s: Kubernetes manifests
- Add Kubernetes manifests (namespace, deployment, service, configmap)
- Add scripts/docker-entrypoint.sh for CLI commands
- Add scripts/build-zarf.sh for building the package
- Update .gitignore for Zarf artifacts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Research document analyzing integration opportunities between
LowEndInsight and Defense Unicorns UDS product portfolio.
Includes concrete recommendations for:
- Pre-package gate integration with Zarf
- UDS Registry metadata enrichment
- Pepr policy integration
- Lula compliance control mapping (NIST SP 800-53)
- CI/CD pipeline integration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The hex and rebar tools were only being installed for root user, but
the container runs as non-root user 'lei'. This caused mix commands
to fail with "Could not find Hex" errors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- poison: ~> 4.0 → ~> 6.0
- ex_doc: ~> 0.24 → ~> 0.34
- credo: ~> 1.5 → ~> 1.7 (also fixed deprecated except: option)
- excoveralls: ~> 0.14 → ~> 0.18
- .tool-versions: erlang 26.2.5.16, elixir 1.16.3-otp-26

httpoison remains at ~> 1.8 due to httpoison_retry compatibility constraint.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…lity

- Remove libtinfo5 (not available on Ubuntu 22.04+)
- Remove libssl1.1 (replaced by libssl3 on Ubuntu 22.04+)
- Use apt-get with update and -y flag for CI best practices

GitHub Actions ubuntu-latest now uses Ubuntu 22.04, which no longer
provides these legacy packages. Only git and libssl-dev are needed
for the Elixir build environment.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Audit all 20 test files (85+ tests) documenting:
- Test categorization (unit/integration/e2e)
- External dependencies (network, git clone, APIs)
- Flakiness sources and risk levels
- Recommendations for improving determinism

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Mox library (~> 1.1) to enable behaviour-based mocking in tests.
This will allow creating mocks for modules like GitModule to enable
deterministic unit tests that don't depend on network access.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create a behaviour definition for GitModule that defines callbacks
for all public functions. This enables Mox-based mocking in tests
to eliminate network dependencies for unit tests.

The behaviour includes callbacks for:
- Repository operations (clone, get, delete)
- Commit analysis (hash, dates, counts)
- Contributor analysis (lists, distributions, mappings)
- Diff and change analysis

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add infrastructure for deterministic test fixtures:

- setup_fixtures.sh: Creates git repos with known commit history,
  contributors, and dates for testing without network access
- FixtureHelper: Elixir module providing paths and expected metadata
  for fixture repositories

Fixtures include:
- simple_repo: 3 commits, 1 contributor
- multi_contributor_repo: 6 commits, 3 contributors
- single_commit_repo: 1 commit
- elixir_project_repo: Elixir project with mix.exs/mix.lock
- node_project_repo: Node.js with package.json
- python_project_repo: Python with requirements.txt

Run `bash test/fixtures/repos/setup_fixtures.sh` to create fixtures.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add @tag :network to all tests that require network access (cloning
from GitHub, GitLab, Bitbucket). Add @tag :long to all slow tests.

Tests marked with network: false and long: false are unit tests that
can run without network access for fast CI feedback.

Tagged files:
- analyzer_test.exs: @moduletag :network/:long, local tests excluded
- files_test.exs: @moduletag :network/:long
- git_module_test.exs: @moduletag :network/:long, local tests excluded
- mix_analyze_test.exs: added :network tag
- mix_bulk_analyze_test.exs: added :network to clone tests
- mix_scan_test.exs: added :network to clone tests
- project_ident_test.exs: @moduletag :network/:long, find_files excluded

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update test_helper.exs to:
- Configure ExUnit to exclude :network and :long tags in CI
- Exclude only :long tags locally by default
- Load the FixtureHelper support module
- Define GitModule.Mock using Mox for behaviour-based mocking

Tests can now be run in different modes:
- CI: mix test (excludes network and long tests automatically)
- Local fast: mix test (excludes only long tests)
- Local full: mix test --include long --include network
- Network only: mix test --only network
- Long only: mix test --only long

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update GitHub Actions workflow to:
- Add CI=true environment variable (triggers test_helper exclusions)
- Exclude both :network and :long tagged tests explicitly

This ensures CI runs only deterministic unit tests that don't depend
on external network access to GitHub, GitLab, or Bitbucket.

For full integration testing, run locally:
  mix test --include network --include long

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move @describetag declarations inside describe blocks as required
by ExUnit. Tags before describe blocks are ignored.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add clearer documentation for running tests in different modes:
- CI: auto-excludes network and long
- Local: auto-excludes long only
- Full suite: --include long --include network
- Network only: --only network --include long
- Long only: --only long

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes since 0.8.1:
- deps: update to latest compatible versions (Poison 6.0, excoveralls 0.18, etc.)
- feat: add GitModule.Behaviour for test mocking
- deps: add Mox for test mocking
- ci: replace deprecated actions/setup-elixir with erlef/setup-beam
- ci: fix Ubuntu 22.04+ compatibility
- test: comprehensive test infrastructure improvements
- require: Elixir ~> 1.14

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ases

- Trigger on v* tags instead of release branch
- Update actions to latest versions (v4/v5)
- Add GitHub release creation with auto-generated notes
- Use Docker Buildx with GHA cache

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
String.slice/2 with negative steps (1..-1) is deprecated in Elixir
1.19+. Use 1..-1//1 to specify the step explicitly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sor, and Copilot

Analyzes extension APIs, MCP server architecture, and competitive landscape
for surfacing LEI bus-factor risk data in AI-assisted development workflows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generates static rule files that inject LowEndInsight dependency risk
awareness into AI coding assistants (Cursor IDE and GitHub Copilot).
Supports configurable thresholds via CLI options or application config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…isk scores

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds lib/cargo/cargolock.ex with:
- Parsing of [[package]] sections from Cargo.lock files
- Extraction of name, version, and source for each package
- Resolution of git sources to repository URLs with commit hashes
- Detection of crates.io registry packages
- Support for local path dependencies (no source)

Includes 7 tests covering all major scenarios.

Part of: lei-9ex (Rust/Cargo Support convoy)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds lib/cargo/cargo_scanner.ex with:
- scan(cargo?, project_types) - Find Cargo.toml/Cargo.lock, parse deps, run analysis
- get_repo_url(name, source) - Lookup crates.io API or use git URL directly
- analyze_dependencies(deps) - Run LEI analysis on each dependency
- Integration with crates.io API for repository URL lookup

Updates scanner_module.ex to:
- Detect cargo projects and run Cargo.Scanner.scan()
- Include cargo reports in combined analysis output

Includes 4 unit tests for basic functionality.

Part of: lei-nys (Rust/Cargo Support convoy - final task)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…res (lei-1v5)

Define dev.lowendinsight.* OCI annotation namespace for publishing bus-factor
risk scores as container image metadata. Includes schema documentation,
annotation generation from LEI reports, JSON/CLI output helpers, and tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-xgj)

Add Lei.Sarif module that converts LowEndInsight analysis reports to
SARIF format, mix lei.sarif task for CLI usage, dedicated GitHub Actions
workflow for upload-sarif, and comprehensive test suite.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
kitplummer and others added 23 commits February 7, 2026 16:40
Implement cache export as OCI-compatible artifacts for Zarf air-gap deployment:
- Lei.Cache.OCI: OCI manifest generation with custom media types
- Lei.Cache.OCIClient: OCI Distribution API client (push/pull)
- Lei.Cache.Exporter: JSONL.gz cache snapshot export
- Lei.Cache.Importer: Local directory and OCI pull import
- Mix tasks: lei.cache.export, lei.cache.pull, lei.cache.import
- Updated zarf.yaml with lei-cache component
- 29 tests covering OCI packaging, export, import, and round-trip

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement standalone CLI tool that runs LEI analysis before Zarf package
creation, failing on high-risk dependencies. Includes:

- Lei.ZarfGate module with configurable risk threshold evaluation
- Lei.ZarfGate.Sarif module for SARIF v2.1.0 output format
- Mix.Tasks.Lei.ZarfGate mix task with --path, --repo, --threshold,
  --format (json/sarif), --output, and --quiet options
- 20 tests covering threshold evaluation, JSON output, and SARIF generation
- Zarf action hook example in zarf.yaml

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create mix task that exports cached analysis results to a portable bundle
for airgap deployment. Includes ETS/DETS-backed cache store, SQLite and
gzipped JSONL export formats, manifest generation, and SHA-256 checksums.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add sarif/sarif_file inputs to action.yml enabling SARIF 2.1.0 output
mode for GitHub Security tab integration. Update entrypoint.sh to
branch between legacy JSON report mode and SARIF generation mode.
Update gha.md with SARIF workflow documentation and rule mapping tables.

Remove duplicate Lei.Cache.Exporter module (lib/lei/cache/exporter.ex)
that conflicted with lib/cache/exporter.ex from a prior merge.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add POST /v1/analyze/batch endpoint for analyzing entire SBOMs in a
single request with parallel cache lookups. Includes Lei.BatchAnalyzer,
Lei.BatchCache (ETS-backed), Lei.Web.Router (Plug/Cowboy), and
Lei.Application supervision tree. 16 new tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous wildcard pattern "/**/*spdx*" matched source code files
like lib/sbom/spdx.ex, causing false positives. Now uses specific
SPDX document extensions (.spdx.json, .spdx.xml, etc).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update actions/checkout from v1 to v4
- Update Elixir from 1.14.1 to 1.15.7
- Update OTP from 25.2 to 26.2
- Update audit container to elixir:1.15.7-alpine
- Remove --trace flag that may cause parallel compilation issues

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…sues)

Keep other CI improvements:
- actions/checkout@v4
- Removed apt-get step (not needed)
- Removed --trace flag

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update badges to point to kitplummer/lowendinsight
- Add What's New section with v0.9.0 features:
  - SARIF output for GitHub Security tab
  - ZarfGate quality gate for CI/CD
  - AI rules generation for Cursor/Copilot
  - Files analysis
  - SPDX parser
- Update installation instructions to ~> 0.9
- Add documentation for new mix tasks:
  - mix lei.sarif
  - mix lei.gate
  - mix lei.generate_rules
- Update all gtri references to kitplummer

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…lity

- Downgrade ex_doc to ~> 0.32.0 for Elixir 1.14 compatibility
- Add separate Compile step before tests
- Limit scheduler parallelism with ELIXIR_ERL_OPTIONS="+S 1:1"
- Use --max-cases 4 to reduce test parallelism
- Split docs generation into separate step with MIX_ENV=dev

The parallel compilation race condition manifests as intermittent
MatchError with {:error, :enoent} during test file loading.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The parallel test file loading race condition in Elixir 1.14.5 causes
intermittent MatchError with {:error, :enoent}. This commit:

- Sets max_cases: 1 in CI to reduce parallel test execution
- Adds retry logic (up to 3 attempts) for the coveralls command
- Sets ELIXIR_COMPILER_PROCESSES=1 to limit compiler parallelism

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ace condition

Elixir 1.14.5 has a known bug in the parallel compiler that causes
intermittent MatchError with {:error, :enoent} during test file loading.
This is fixed in Elixir 1.16.x.

Changes:
- Upgrade CI to Elixir 1.16.3 / OTP 26.2
- Upgrade ex_doc to ~> 0.34 (requires Elixir 1.15+)
- Update Alpine container to elixir:1.16.3-alpine
- Simplify workflow by removing workarounds

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The parallel test file loading race condition occurs in both Elixir
1.14.x and 1.16.x. This adds robust retry logic (up to 5 attempts)
with a 2-second delay between attempts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive unit tests that don't require network access:

- npm_scanner_test.exs: tests for Npm.Scanner.scan/2,3
- pypi_scanner_test.exs: tests for Pypi.Scanner.scan/2,3
- hex_scanner_test.exs: tests for Hex.Scanner.scan/2
- cargo_scanner_test.exs: expanded tests for Cargo.Scanner
- scanner_module_test.exs: tests for ScannerModule.get_report/4
- project_ident_test.exs: unit tests for project type identification

Coverage improved from 58.9% to 63.6%.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tests for parse_diff, get_contributor_counts, get_filtered_contributor_count
- Add tests for split_commits_by_tag, parse_shortlog functions
- Add tests for different project type manifest detection in sarif
- Add tests for risk_to_security_severity and message functions
- Coverage improved: sarif 71.6% -> 92.5%, overall 63.65% -> 65.5%

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tests for get_slug, split_slug, count_forward_slashes
- Add tests for risk thresholds at boundary values
- Add tests for packagefile with devDependencies
- Add tests for requirements.txt edge cases
- Coverage improved to 66.2%

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add test for metadata without timestamp
- Add test for all risk properties in component
- Add test for missing git hash handling
- Coverage improved: cyclonedx 89.4% -> 94.7%, overall 66.2% -> 66.6%

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… git/path parsing (lei-okv9)

- Add [build-dependencies] and [workspace.dependencies] section parsing to Cargofile
- Parse git and path dependency sources in inline table format
- Fix query_crates_io to use HTTPoison.get instead of get! for robustness
- Fix Cargolock regex to be case-sensitive (TOML spec compliance)
- Add comprehensive Cargofile tests for new dependency sections
- Add crates ecosystem tests for batch analyzer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add comprehensive test suite covering mix tasks, cache modules, SBOM
generators, SARIF output, OCI packaging, cargo/npm/hex parsers, and
analyzer edge cases. Introduces 18 new test files and expands 26
existing ones, bringing the project from 67% to 90% code coverage
(505 tests, 0 failures).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kitplummer kitplummer closed this Feb 21, 2026
@kitplummer kitplummer deleted the kp/refactor_url branch February 21, 2026 23:44
@github-advanced-security
Copy link

This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation.

@kitplummer kitplummer restored the kp/refactor_url branch February 21, 2026 23:53
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