Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
7a25465
Fix partial coverage background rendering and CSS variables swap in L…
cuzzo Jul 9, 2026
e22389b
Fix partial coverage highlight and swapped coverage/churn mode backgr…
cuzzo Jul 9, 2026
66129d4
Add Go mutation testing script and run mutants for boobytrap Go gem
cuzzo Jul 9, 2026
8b7ffc7
Fix coverage view bugs and add ClearParser to mutation testing
cuzzo Jul 9, 2026
844c677
Update codecov config, generate_generalized_gem_sarif, and fuzz patch…
cuzzo Jul 9, 2026
37c0223
Add Lineage build automation script and style verified hazards green
cuzzo Jul 9, 2026
7708bba
Fix partial/uncovered line styling bug and aggregate directory mutant…
cuzzo Jul 9, 2026
ace750e
Integrate scheduler.zig mutation testing, optimize workspace copying,…
cuzzo Jul 10, 2026
0eb10fc
Exclude dead findings from is_dark_arm classification and expand Ruby…
cuzzo Jul 10, 2026
ea60838
Implement native Cobertura branch partial coverage tracking and optim…
cuzzo Jul 10, 2026
aae7113
Add collapsible sidebar, recycle icon for reentrant functions, functi…
cuzzo Jul 10, 2026
0509cbb
Add ellipse (...) trailing marker on collapsed functions
cuzzo Jul 10, 2026
90908b9
Render closing brace or keyword after ellipse in collapsed functions
cuzzo Jul 10, 2026
9b3e53f
Add Coverage/Hazards toggle in directory view, single hazard quality …
cuzzo Jul 10, 2026
09772ca
Add coverage.txt to COVERAGE_NAMES for Go coverage ingestion support
cuzzo Jul 10, 2026
20b862d
Fix boobytrap and zig-mutants coverage ingestion path matching and he…
cuzzo Jul 10, 2026
d5686f6
Support runtime and space complexity metrics in Espalier and render H…
cuzzo Jul 10, 2026
c41a998
Classify static vs dynamic loops and link trigger source lines to Esp…
cuzzo Jul 11, 2026
0cbae15
Refine loop complexity classification with regex bound variable extra…
cuzzo Jul 11, 2026
48b38a2
Verify dynamic classification and trigger tracing for recursive funct…
cuzzo Jul 11, 2026
3c3e788
Collapse all dashboard sections by default except Active Hazards if h…
cuzzo Jul 11, 2026
9a00eeb
Fix swapped Covered and Killed columns and bar values in hazards table
cuzzo Jul 11, 2026
51b138c
Audit branch reliability and harden analysis tooling
cuzzo Jul 11, 2026
3fd64dc
Fix current SARIF snapshots and fair result capping
cuzzo Jul 11, 2026
fed3049
Add scoped review and test queues to Lineage
cuzzo Jul 11, 2026
2e1ce1c
Keep Lineage dashboard responsive on large databases
cuzzo Jul 11, 2026
35c0405
Replace Lineage dashboard disclosures with section bar
cuzzo Jul 11, 2026
f7f00d2
Shorten Lineage dashboard section labels
cuzzo Jul 11, 2026
13962eb
Add analyzer status indicator and paginated queues
cuzzo Jul 11, 2026
7b566fc
Move analyzer health status onto directory rows
cuzzo Jul 11, 2026
b7ea921
WIP: add focused architecture view
cuzzo Jul 11, 2026
2bd7bad
Add schema-aware SQL coverage and hazards
cuzzo Jul 11, 2026
57aa600
Refine SQL nullability analysis
cuzzo Jul 11, 2026
df392d4
Add multi-dialect SQL coverage and fix dashboard panels
cuzzo Jul 11, 2026
0fdff8b
Keep dashboard tab panels in sync
cuzzo Jul 11, 2026
64fa5eb
Document three-dialect SQL-COV status
cuzzo Jul 11, 2026
63b8012
Render SQL coverage findings in source gutter
cuzzo Jul 11, 2026
d9cc8e4
Preserve SARIF snapshots and extract Lineage SQL
cuzzo Jul 11, 2026
6f6d99f
Implement SQL-cov capability gaps for schema-aware coverage, subquery…
cuzzo Jul 11, 2026
e5878bc
Update gems/sql-cov/README.md to premium quality matching decomplex/e…
cuzzo Jul 11, 2026
936fcc0
Integrate sql-cov and SARIF reporting into GitHub Actions CI
cuzzo Jul 11, 2026
3ceb73f
Add SQLFluff integration and findings tiering to hazards analysis
cuzzo Jul 11, 2026
2849200
Implement sql-cov generate-check subcommand for static hazards
cuzzo Jul 11, 2026
39f9bcf
Optimize path resolution queries in lineage DB import to prevent hangs
cuzzo Jul 11, 2026
d253a93
Add unit and integration tests for sql-cov driver and schema to incre…
cuzzo Jul 12, 2026
cc9e7df
Update sql-cov coverage.lcov report with new test results
cuzzo Jul 12, 2026
0aa884a
Implement LookML JOIN hazard integration in sql-cov and optimize Line…
cuzzo Jul 12, 2026
edaba32
Document LookML JOIN hazards in README and refine hazard detection logic
cuzzo Jul 12, 2026
a97dea9
Implement schema-driven JOIN hazard detection in sql-cov
cuzzo Jul 12, 2026
5077494
Document schema-inferred automatic JOIN hazards in README.md
cuzzo Jul 12, 2026
f75cef0
Implement predicate-based non-nullability propagation in sql-cov
cuzzo Jul 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,9 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install -y z3
- name: Install SQLFluff
run: |
pip install sqlfluff
- uses: dtolnay/rust-toolchain@stable
- uses: actions/setup-go@v5
with:
Expand All @@ -1474,6 +1477,7 @@ jobs:
run: |
cargo build --release --manifest-path gems/fact-mine/Cargo.toml
cargo build --release --manifest-path gems/decomplex/Cargo.toml
cargo build --release --manifest-path gems/sql-cov/Cargo.toml
- name: Download Ruby coverage artifacts
if: ${{ needs['ruby-gems-coverage'].result == 'success' || needs['ruby-unit'].result == 'success' || needs['ruby-integration'].result == 'success' || needs['transpile-tests'].result == 'success' || needs['examples-benchmarks-coverage-shard'].result == 'success' || needs['tools-fuzz-shard'].result == 'success' || needs['bc-lower-coverage-shard'].result == 'success' }}
uses: actions/download-artifact@v4
Expand Down Expand Up @@ -1516,6 +1520,11 @@ jobs:
--top=80 \
--decomplex-binary=./gems/decomplex/target/release/decomplex-rust \
"${coverage_args[@]}"
./tools/generate_sql_cov_sarif.rb \
--repo=. \
--out-dir=tmp/generalized-gems-sarif \
--setup=gems/lineage/sql/storage/init_schema.sql \
--sql-cov-bin=./gems/sql-cov/target/release/sql-cov
- name: Upload Decomplex SARIF
uses: github/codeql-action/upload-sarif@v4
with:
Expand All @@ -1541,6 +1550,11 @@ jobs:
with:
sarif_file: tmp/generalized-gems-sarif/nil-kill.sarif
category: nil-kill
- name: Upload SQL-cov SARIF
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: tmp/generalized-gems-sarif/sql-cov.sarif
category: sql-cov
- uses: actions/upload-artifact@v4
with:
name: generalized-gems-sarif
Expand Down
2 changes: 1 addition & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ comment:
flags:
ruby:
paths:
- src/
- compiler/
carryforward: false
joined: false
zig:
Expand Down
2 changes: 1 addition & 1 deletion compiler/spec/ast_coverage_burndown_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
require_relative "../ruby/ast/type" unless defined?(Type)
require_relative "../ruby/annotator/helpers/function_signature" unless defined?(FunctionSignature::AnalysisFacts)

RSpec.describe "AST coverage burndown" do
RSpec.describe ClearParser do
def token(type = :VAR_ID, value = "x", line: 1, column: 1)
Lexer::Token.new(type, value, line, column)
end
Expand Down
7 changes: 3 additions & 4 deletions gems/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ quality work scalable.
## Projects

- `decomplex`: static complexity and duplicated-decision analysis.
- `boobytrap`: risk ranking from coverage, branch gaps, churn, and
structural evidence.
- `boobytrap`: risk ranking from coverage, branch gaps, churn, and structural evidence.
- `slopcop`: sloppiness and guardrail reporting.
- `nil-kill`: nil/type-pressure evidence.
- `auto-type`: automated type and nilability rewrites driven by analyzer
evidence.
- `auto-type`: automated type and nilability rewrites driven by analyzer evidence.
- `espalier`: architecture and public-surface analysis.
- `lineage`: source/test/quality lineage UI and ingestion tooling.
- `zig-mutants`: mutation testing for Zig runtime/lib code.
- `sql-cov`: dynamic and schema-aware SQL branch coverage and logic hazard analysis.

## Contribution Rules

Expand Down
72 changes: 72 additions & 0 deletions gems/decomplex/docs/agents/iterator-invalidation-reliability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Iterator Invalidation Detector: Product and Architecture Decision

Status: **Do not implement the proposed all-language detector.**

The detailed extraction and feasibility assessment lives in
`gems/fact-mine/docs/agents/iterator-invalidation-reliability.md`. This document
records the Decomplex-side decision and prevents a future agent from building a
plausible-looking detector on insufficient facts.

## Decision

Do not add an `IteratorInvalidationDetector` based on loop spans, textual
collection variables, mutation method names, or `(method, parameter-index)`
reachability. Do not put language mutation registries or language branches in a
Decomplex detector.

Across the 15 supported languages, mutation during traversal can mean undefined
behavior, a fail-fast runtime exception, a compiler error, defined live traversal,
snapshot/copy traversal, a permitted operation, or merely surprising logic.
Calling all of these “iterator invalidation” would be inaccurate. Reliably
distinguishing them requires resolved types and symbols, heap-object aliasing,
call/return/callback flow, and collection/version-specific contracts. Current
FactMine facts provide none of those guarantees.

This is also low-value relative to its cost:

- Rust already rejects the ordinary safe-borrow case.
- Java, C#, C++, Swift, TypeScript, and Zig need compiler semantic services for
useful precision.
- C needs a points-to analysis plus annotated library/allocator contracts.
- Ruby, Python, JavaScript, Lua, and PHP retain unresolved dynamic behavior even
after substantial analysis.
- Go deliberately specifies several mutations during `range`; mutation is not
synonymous with invalidation.
- Existing compilers, runtimes, and focused linters already cover many of the
strongest cases.

## Architectural boundary

If future evidence justifies a narrow implementation, FactMine must emit a
language-neutral, already-adjudicated `IteratorInteraction` fact containing:

- stable iteration and mutation IDs/spans;
- resolved iterable and mutation target value identity;
- resolved iteration and mutation contracts;
- an outcome such as `invalidated`, `runtime_fail_fast`, `traversal_changes`,
`safe`, or `unknown`;
- the contract source and confidence; and
- enough evidence to explain why the mutation targets the traversed object.

Decomplex may consume only those facts. It must not:

- parse source or normalized nodes;
- compare source-text receiver/argument names;
- infer aliases or callees;
- own standard-library mutation lists;
- inspect `Document.language`; or
- reinterpret `unknown` as hazardous.

This follows the existing boundary: FactMine establishes semantic evidence;
Decomplex groups, thresholds, explains, and reports it.

## Reconsideration gate

Reconsider only after a separate, compiler-backed, standard-library-only pilot
for one language achieves at least 95% reviewed precision on real repositories
and finds useful issues not already reported by that ecosystem's compiler or
standard linters. C++/Clang, Java/javac or JDT, and C#/Roslyn are plausible pilot
choices. A Tree-sitter-only or YAML-registry prototype is not evidence that the
design works.

Until that gate is met, the correct implementation is no implementation.
14 changes: 14 additions & 0 deletions gems/espalier/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ bundle exec gems/espalier/exe/espalier \
Espalier can output a compact architecture manifest for tools and LLMs,
or a Markdown report for human architectural review.

### Versioned architecture graph

```bash
bundle exec gems/espalier/exe/espalier \
--format architecture \
--output=tmp/espalier-architecture.json \
src/
```

This output contains stable owner/function/state IDs, first-class call and
state-access edges, confidence, source citations, and explainable function
pressure. It is the structured ingestion contract for Lineage; SARIF, DOT, and
human-readable manifests are not parsed to reconstruct the graph.

### Architecture Report

```bash
Expand Down
19 changes: 17 additions & 2 deletions gems/espalier/exe/espalier
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ end
OptionParser.new do |opts|
opts.banner = "Usage: espalier [options] <files/directories...>"

opts.on("-f", "--format FORMAT", [:markdown, :yaml, :report, :dot, :sarif, :json], "Output format (markdown, yaml, report, dot, sarif, json). Default: markdown") do |f|
opts.on("-f", "--format FORMAT", [:markdown, :yaml, :report, :dot, :sarif, :json, :architecture], "Output format (markdown, yaml, report, dot, sarif, json, architecture). Default: markdown") do |f|
options[:format] = f
end

Expand Down Expand Up @@ -136,7 +136,22 @@ if options[:risk] && File.exist?(options[:risk])
end

# Extract Static Skeletons
evidence = Espalier::StaticEvidence.build(targets, root: Dir.pwd, vcs: options[:vcs])
evidence = Espalier::StaticEvidence.build(
targets,
root: Dir.pwd,
vcs: options[:vcs],
include_annotations: options[:format] != :architecture
)

if options[:format] == :architecture
output_contents = JSON.pretty_generate(Espalier::ArchitectureArtifact.build(evidence, root: Dir.pwd))
if options[:output]
File.write(options[:output], output_contents)
else
puts output_contents
end
exit 0
end

# Group flat evidence into module structures expected by aggregator/analyzers
modules = Espalier::StaticEvidence.project_modules(evidence)
Expand Down
1 change: 1 addition & 0 deletions gems/espalier/lib/espalier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Espalier
require_relative "espalier/architecture_analyzer"
require_relative "espalier/aggregator"
require_relative "espalier/dependency_graph"
require_relative "espalier/architecture_artifact"
require_relative "espalier/graphviz_formatter"
require_relative "espalier/formatter"
require_relative "espalier/reporter"
Expand Down
3 changes: 3 additions & 0 deletions gems/espalier/lib/espalier/aggregator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ def aggregate(modules)

big_o_result = analyzer.analyze_method(key, ast_nodes, local_types: local_types_for_signature(sig))
quality[:big_o] = big_o_result[:lower_bound_complexity]
quality[:big_o_space] = big_o_result[:space_complexity] if big_o_result[:space_complexity]
quality[:big_o_dynamic] = big_o_result[:is_dynamic]
quality[:complexity_trigger] = big_o_result[:trigger] if big_o_result[:trigger]
quality[:big_o_warnings] = big_o_result[:warnings] unless big_o_result[:warnings].empty?
quality[:big_o_unknowns] = big_o_result[:unknown_operations] unless big_o_result[:unknown_operations].empty?

Expand Down
Loading
Loading