Static analysis and dependency tracing for Excel models, written in MoonBit.
moon update
moon check --target native
moon test --target native
moon run --target native cmd/main -- audit fixtures/bad_model.xlsxSheetSentry: fixtures/bad_model.xlsx
sheets: 5 formula cells: 14 findings: 11
high: 4 medium: 6 low: 1
[medium] SS005 Opex!C6 Formula lives on a hidden row.
[medium] SS003 Summary!B2 Formula embeds numeric constant 1.05; prefer a named input cell.
[high] SS001 Summary!B4 Cell contains error value #REF!.
...# Terminal report
moon run --target native cmd/main -- audit model.xlsx
# JSON
moon run --target native cmd/main -- audit model.xlsx --format json --out findings.json
# SARIF for code scanning
moon run --target native cmd/main -- audit model.xlsx --format sarif --out results.sarif
# Self-contained HTML report
moon run --target native cmd/main -- audit model.xlsx --format html --out report.html
# Trace precedents (what this cell depends on)
moon run --target native cmd/main -- trace model.xlsx --cell "Summary!B7" --direction precedents --depth 4
# Trace dependents (what breaks if this cell changes)
moon run --target native cmd/main -- trace model.xlsx --cell "Inputs!B2" --direction dependents --depth 4
# Fail CI if any high-severity finding exists
moon run --target native cmd/main -- audit model.xlsx --fail-on high| ID | Severity | Rule | Why it matters |
|---|---|---|---|
| SS001 | High | Error value | #REF!, #DIV/0!, #VALUE!, #N/A, #NAME?, #NUM! silently poison downstream results. |
| SS002 | Medium | Formula inconsistency | One cell in a copied row/column uses a different formula pattern. |
| SS003 | Medium | Hardcoded constant | A numeric constant is embedded in a formula instead of living in an input cell. |
| SS004 | Low | Volatile function | TODAY, NOW, RAND, RANDBETWEEN, OFFSET, INDIRECT, INFO, CELL make results time- or environment-dependent. |
| SS005 | Medium | Hidden formula | Formulas on hidden sheets or hidden rows are easy to miss during review. |
| SS006 | High | Circular reference | A dependency cycle makes calculation order undefined or unstable. |
| SS007 | Low | Dynamic reference | INDIRECT / OFFSET prevent complete static dependency tracing. |
- name: Audit Excel model
run: |
moon run --target native cmd/main -- \
audit model.xlsx --format sarif --out results.sarif --fail-on high
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarifflowchart LR
XLSX[XLSX bytes] --> Reader[mbtexcel reader]
Reader --> Cells[Formula cells + cached values + visibility]
Cells --> Refs[Formula reference parser]
Refs --> Graph[Cross-sheet dependency graph]
Graph --> Rules[Rule engine]
Cells --> Rules
Rules --> Report[Terminal / JSON / SARIF / HTML]
Graph --> Trace[Precedents / dependents]moon test --target nativePYTHONPATH=../tools/pylib python3 scripts/make_fixtures.pypub(all) struct CellRef {
start : Int
end : Int
sheet : String?
row : Int
col : Int
end_row : Int
end_col : Int
abs_row : Bool
abs_col : Bool
}pub(all) enum Severity {
High
Medium
Low
}fn normalize_formula(formula : StringView, current_sheet : StringView, row : Int, col : Int) -> StringInstall
Download zipStatic analysis and dependency tracing for Excel models, written in MoonBit.