NEXY internals
This note is for STIG developers. The user guide explains the metric meaning, percentile policy, and report interpretation. This page only records the implementation boundaries that must stay stable.
Source Of Truth
NEXY policy lives in Kotlin:
Concern | Source |
|---|---|
Percentile markers, zones, equal-zone axis |
|
Metric descriptors and analyzer availability gates |
|
Default metric anchors and scope scales |
|
Runtime default metric models |
|
Gauge/ruler render plans |
|
Report payload maps |
|
JavaScript must not carry independent metric policy. It renders the Kotlin-produced payloads only.
Transformation Chain
The engine transforms metrics in this order:
NexyMetricModel.metricToPercentile applies metric direction. Current shipped complexity metrics use HIGHER_IS_MORE_COMPLEX; lower-tail or two-sided risk scores must be modeled explicitly rather than hidden inside zone rendering.
The browser receives schemaVersion = 2 render plans with already-computed axis positions, labels, bands, and tick values. It must not run CDF or inverse-CDF logic.
Model Types
Report-time metric models are intentionally small:
Supported distribution DTOs:
Supported raw-value metadata DTOs:
The raw-axis DTOs carry unit, rounding, and reference-range metadata. They do not define the gauge angular coordinate; NexyEqualZoneAxis does.
Default Model Runtime Path
Default NEXY metric models are not generated Kotlin source. Runtime scoring uses NexyMetricModels.defaultMetricModelSet(), which lazily calls NexyDefaultMetricModelFactory.defaultMetricModelSet() in the compiled engine. This keeps the report pipeline tied to the current Kotlin source when a local sibling checkout is rebuilt.
Current default policy:
all shipped default models are lognormal;
P75is the function-scope medium-to-high raw anchor;P50 = P75 / DEFAULT_MEDIUM_TO_HIGH_TO_MEDIAN_RATIO;default ratio is
2.0;sink raw boundaries are
20xfunction boundaries;component raw boundaries are
50xfunction boundaries.
NexyDefaultMetricModelFactory.writeDefaultMetricModelsJson() remains an explicit interchange helper. JSON is not the runtime default constant store.
Generated Metric Test Artifacts
The checked-in NEXY test fixture artifact is generated explicitly:
Generated output:
After changing anchors, scales, percentile markers, descriptors, or render-plan shape, run ./gradlew stigGenerateMetrics and review the generated fixture diff. NexyModelTest compares the checked-in fixture with the Kotlin generator output, so stale fixture content fails tests. Normal report and viewer tasks do not implicitly regenerate tracked files.
Generated JavaScript Artifacts
Two JavaScript files are generated from Kotlin source-of-truth code and are intentionally tracked so regeneration produces visible git diffs:
File | Generator | Source of truth |
|---|---|---|
|
|
|
|
| NEXY render plans |
The ASIL file is part of the esbuild import graph. The NEXY fixture file is only for Playwright HTML fixtures; it prevents test HTML from duplicating percentile cuts or equal-zone axis math.
The ASIL palette is not a metric artifact. Regenerate it explicitly with:
Browser Boundary
stig-gauge.js may:
parse
data-stig-gauge;validate schema/kind and required numeric fields;
render ECharts gauges from precomputed bands, ticks, labels, and axis positions;
react to theme and resize changes.
stig-gauge.js must not:
select metric models;
evaluate distribution CDFs or inverse CDFs;
choose percentile thresholds;
classify NEXY zones;
invent fallback thresholds.
If a payload is malformed, the renderer should fail visibly instead of guessing.
Analyzer-Derived Metrics
Analyzer-derived IR metrics are optional. Current shipped descriptors require analyzer graph evidence but do not require Z3 evidence:
Unavailable analyzer-gated metrics are omitted from composite scoring. They are not substituted with zero and are not kept in the denominator.
Validation Expectations
Engine tests must cover:
distribution forward/inverse transformations;
percentile markers and zone classification;
equal-zone gauge positioning;
default model generation policy and scope ratios;
composite weighted-average scoring with unavailable metrics;
JSON/render-plan payload shape.
Viewer tests must cover:
schema-v2 gauge rendering;
generated fixture consumption;
absence of duplicated percentile policy in fixture HTML.
Report-generation postconditions should fail on missing metric models, duplicate model keys, and inconsistent availability coverage before rendering misleading output.