branchproof 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -0
- data/README.md +279 -27
- data/doc/Branchproof/Analyzer.md +2 -2
- data/doc/Branchproof/CLI.md +4 -0
- data/doc/Branchproof/ComparisonReport.md +4 -0
- data/doc/Branchproof/Constraints/Solver.md +21 -0
- data/doc/Branchproof/Constraints.md +98 -0
- data/doc/Branchproof/CoverageIndex.md +6 -0
- data/doc/Branchproof/DecisionSyntax.md +22 -0
- data/doc/Branchproof/DecisionTable.md +153 -0
- data/doc/Branchproof/FlowInstrumentation.md +7 -0
- data/doc/Branchproof/FocusedReport.md +5 -2
- data/doc/Branchproof/Instrumenter.md +1 -0
- data/doc/Branchproof/Loader.md +0 -4
- data/doc/Branchproof/MinitestAdapter.md +0 -3
- data/doc/Branchproof/Report.md +18 -0
- data/doc/Branchproof/Runtime.md +23 -0
- data/doc/Branchproof/RuntimeFlow.md +27 -0
- data/doc/Branchproof/SavedReport.md +21 -0
- data/doc/Branchproof/Source.md +1 -0
- data/doc/Branchproof.md +9 -2
- data/doc/CHANGELOG.md +45 -0
- data/doc/README.md +279 -27
- data/lib/branchproof/analyzer.rb +222 -54
- data/lib/branchproof/cli.rb +28 -19
- data/lib/branchproof/comparison.rb +207 -19
- data/lib/branchproof/comparison_report.rb +49 -1
- data/lib/branchproof/constraints.rb +363 -0
- data/lib/branchproof/coverage_index.rb +120 -3
- data/lib/branchproof/decision_syntax.rb +310 -0
- data/lib/branchproof/decision_table.rb +377 -0
- data/lib/branchproof/evidence.rb +101 -36
- data/lib/branchproof/flow_instrumentation.rb +107 -0
- data/lib/branchproof/focused_report.rb +161 -26
- data/lib/branchproof/instrumenter.rb +65 -39
- data/lib/branchproof/limits.rb +4 -1
- data/lib/branchproof/loader.rb +18 -6
- data/lib/branchproof/minimizer.rb +18 -13
- data/lib/branchproof/minitest_adapter.rb +11 -16
- data/lib/branchproof/records.rb +2 -0
- data/lib/branchproof/report.rb +470 -66
- data/lib/branchproof/runtime.rb +25 -30
- data/lib/branchproof/runtime_flow.rb +58 -0
- data/lib/branchproof/saved_report.rb +438 -13
- data/lib/branchproof/source.rb +239 -41
- data/lib/branchproof/version.rb +1 -1
- data/lib/branchproof/worker.rb +1 -4
- data/lib/branchproof.rb +2 -0
- data/llms.txt +9 -2
- data/sig/branchproof.rbs +54 -1
- metadata +12 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Module Branchproof::DecisionTable <a id="module-Branchproof-DecisionTable"></a>
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
| --- | --- |
|
|
5
|
+
| **Defined in** | lib/branchproof/decision_table.rb |
|
|
6
|
+
|
|
7
|
+
Derives the executable logical rules of a supported Boolean decision and
|
|
8
|
+
overlays the runtime evidence that the existing Branchproof run captured.
|
|
9
|
+
|
|
10
|
+
Rules come from the Boolean tree itself rather than from an exhaustive
|
|
11
|
+
Cartesian expansion, so Ruby's short-circuit semantics are preserved: a
|
|
12
|
+
condition the interpreter would skip becomes an explicit `dont_care` value
|
|
13
|
+
instead of two separate rules.
|
|
14
|
+
|
|
15
|
+
Nothing here executes application code, and no additional test run is
|
|
16
|
+
required: overlay consumes the vectors already recorded for the decision.
|
|
17
|
+
|
|
18
|
+
## Constants
|
|
19
|
+
### `CONDITION_VALUES` <a id="constant-CONDITION_VALUES"></a> <a id="CONDITION_VALUES-constant"></a>
|
|
20
|
+
Not documented.
|
|
21
|
+
|
|
22
|
+
### `CONSTRAINT_ANALYSIS_VERSION` <a id="constant-CONSTRAINT_ANALYSIS_VERSION"></a> <a id="CONSTRAINT_ANALYSIS_VERSION-constant"></a>
|
|
23
|
+
Not documented.
|
|
24
|
+
|
|
25
|
+
### `COVERAGE_STATUSES` <a id="constant-COVERAGE_STATUSES"></a> <a id="COVERAGE_STATUSES-constant"></a>
|
|
26
|
+
Not documented.
|
|
27
|
+
|
|
28
|
+
### `COVERAGE_SUMMARY_STATUSES` <a id="constant-COVERAGE_SUMMARY_STATUSES"></a> <a id="COVERAGE_SUMMARY_STATUSES-constant"></a>
|
|
29
|
+
Not documented.
|
|
30
|
+
|
|
31
|
+
### `DEFAULT_MAX_CONDITIONS` <a id="constant-DEFAULT_MAX_CONDITIONS"></a> <a id="DEFAULT_MAX_CONDITIONS-constant"></a>
|
|
32
|
+
Not documented.
|
|
33
|
+
|
|
34
|
+
### `DEFAULT_MAX_RULES` <a id="constant-DEFAULT_MAX_RULES"></a> <a id="DEFAULT_MAX_RULES-constant"></a>
|
|
35
|
+
Not documented.
|
|
36
|
+
|
|
37
|
+
### `DONT_CARE` <a id="constant-DONT_CARE"></a> <a id="DONT_CARE-constant"></a>
|
|
38
|
+
Not documented.
|
|
39
|
+
|
|
40
|
+
### `FALSE_VALUE` <a id="constant-FALSE_VALUE"></a> <a id="FALSE_VALUE-constant"></a>
|
|
41
|
+
Not documented.
|
|
42
|
+
|
|
43
|
+
### `NOT_CALCULATED_REASONS` <a id="constant-NOT_CALCULATED_REASONS"></a> <a id="NOT_CALCULATED_REASONS-constant"></a>
|
|
44
|
+
Not documented.
|
|
45
|
+
|
|
46
|
+
### `REACHABILITY_STATUSES` <a id="constant-REACHABILITY_STATUSES"></a> <a id="REACHABILITY_STATUSES-constant"></a>
|
|
47
|
+
Not documented.
|
|
48
|
+
|
|
49
|
+
### `SCHEMA_VERSION` <a id="constant-SCHEMA_VERSION"></a> <a id="SCHEMA_VERSION-constant"></a>
|
|
50
|
+
Not documented.
|
|
51
|
+
|
|
52
|
+
### `TABLE_STATUSES` <a id="constant-TABLE_STATUSES"></a> <a id="TABLE_STATUSES-constant"></a>
|
|
53
|
+
Not documented.
|
|
54
|
+
|
|
55
|
+
### `TRUE_VALUE` <a id="constant-TRUE_VALUE"></a> <a id="TRUE_VALUE-constant"></a>
|
|
56
|
+
Not documented.
|
|
57
|
+
|
|
58
|
+
### `VALUE_LABELS` <a id="constant-VALUE_LABELS"></a> <a id="VALUE_LABELS-constant"></a>
|
|
59
|
+
Not documented.
|
|
60
|
+
|
|
61
|
+
## Public Class Methods
|
|
62
|
+
### `build(decision:, vectors: = [], limits: = {}, reachability: = true)` <a id="method-c-build"></a> <a id="build-class_method"></a>
|
|
63
|
+
Builds the reduced, runtime-overlaid table for one Boolean decision.
|
|
64
|
+
- **@raise** [ArgumentError]
|
|
65
|
+
|
|
66
|
+
### `classify_vectors(rules, vectors)` <a id="method-c-classify_vectors"></a> <a id="classify_vectors-class_method"></a>
|
|
67
|
+
Generated traces have nil in every skipped condition position. Their
|
|
68
|
+
normalized vector is therefore an exact table key and can be classified
|
|
69
|
+
without scanning every rule. Malformed or hand-built observations retain the
|
|
70
|
+
historical matcher as a bounded compatibility fallback.
|
|
71
|
+
|
|
72
|
+
### `combine(node, type, budget)` <a id="method-c-combine"></a> <a id="combine-class_method"></a>
|
|
73
|
+
Not documented.
|
|
74
|
+
|
|
75
|
+
### `coverage_entry(table)` <a id="method-c-coverage_entry"></a> <a id="coverage_entry-class_method"></a>
|
|
76
|
+
The per-decision row the coverage ladder renders.
|
|
77
|
+
|
|
78
|
+
### `coverage_status(covered, required, generated)` <a id="method-c-coverage_status"></a> <a id="coverage_status-class_method"></a>
|
|
79
|
+
Not documented.
|
|
80
|
+
|
|
81
|
+
### `enumerate(node, prefer, budget)` <a id="method-c-enumerate"></a> <a id="enumerate-class_method"></a>
|
|
82
|
+
Enumerates every short-circuit evaluation path of the Boolean tree.
|
|
83
|
+
|
|
84
|
+
`prefer` orders the paths deterministically: a conjunction lists its
|
|
85
|
+
short-circuiting false path first, a disjunction its true path first, and a
|
|
86
|
+
negation inverts the preference it inherits. Returns nil once the path count
|
|
87
|
+
would exceed `budget`.
|
|
88
|
+
|
|
89
|
+
### `fast_match_positions(vector, by_signature, condition_count)` <a id="method-c-fast_match_positions"></a> <a id="fast_match_positions-class_method"></a>
|
|
90
|
+
Not documented.
|
|
91
|
+
|
|
92
|
+
### `fetch(record, key)` <a id="method-c-fetch"></a> <a id="fetch-class_method"></a>
|
|
93
|
+
Not documented.
|
|
94
|
+
|
|
95
|
+
### `generic_matches(rules, vectors)` <a id="method-c-generic_matches"></a> <a id="generic_matches-class_method"></a>
|
|
96
|
+
Not documented.
|
|
97
|
+
|
|
98
|
+
### `limit(limits, key, fallback)` <a id="method-c-limit"></a> <a id="limit-class_method"></a>
|
|
99
|
+
Not documented.
|
|
100
|
+
|
|
101
|
+
### `matches?(rule, vector)` <a id="method-c-matches-3F"></a> <a id="matches?-class_method"></a>
|
|
102
|
+
A runtime observation matches a rule when every required condition value
|
|
103
|
+
matches and the decision outcome matches. Conditions Ruby skipped may only
|
|
104
|
+
line up with don't-care positions.
|
|
105
|
+
- **@return** [Boolean]
|
|
106
|
+
|
|
107
|
+
### `not_calculated(decision_id, reason)` <a id="method-c-not_calculated"></a> <a id="not_calculated-class_method"></a>
|
|
108
|
+
Not documented.
|
|
109
|
+
|
|
110
|
+
### `overlay(decision_id:, rules:, vectors:, reachability: = true, indexed: = false)` <a id="method-c-overlay"></a> <a id="overlay-class_method"></a>
|
|
111
|
+
Not documented.
|
|
112
|
+
|
|
113
|
+
### `overlay_rule(decision_id, rule, vectors, diagnostics)` <a id="method-c-overlay_rule"></a> <a id="overlay_rule-class_method"></a>
|
|
114
|
+
Public compatibility wrapper: callers historically passed all vectors, so
|
|
115
|
+
retain matcher filtering for direct calls.
|
|
116
|
+
|
|
117
|
+
### `overlay_rule_matches(decision_id, rule, matched, diagnostics)` <a id="method-c-overlay_rule_matches"></a> <a id="overlay_rule_matches-class_method"></a>
|
|
118
|
+
Not documented.
|
|
119
|
+
|
|
120
|
+
### `percentage(covered, required)` <a id="method-c-percentage"></a> <a id="percentage-class_method"></a>
|
|
121
|
+
Not documented.
|
|
122
|
+
|
|
123
|
+
### `representable?(node, condition_count)` <a id="method-c-representable-3F"></a> <a id="representable?-class_method"></a>
|
|
124
|
+
Only AND, OR, NOT, and atoms within the decision's own condition range are
|
|
125
|
+
representable; anything else leaves the table uncalculated rather than
|
|
126
|
+
producing a table that does not describe the decision.
|
|
127
|
+
- **@return** [Boolean]
|
|
128
|
+
|
|
129
|
+
### `rule(decision_id, conditions, path, index, reachability: = true, prepared_constraints: = nil)` <a id="method-c-rule"></a> <a id="rule-class_method"></a>
|
|
130
|
+
rubocop:disable-next Metrics/ParameterLists
|
|
131
|
+
|
|
132
|
+
### `rule_id(decision_id, values, outcome)` <a id="method-c-rule_id"></a> <a id="rule_id-class_method"></a>
|
|
133
|
+
Rule identity depends only on the decision, the normalized condition vector,
|
|
134
|
+
the expected outcome, and the table schema version. It never depends on a test
|
|
135
|
+
name, a runtime observation, or the Minitest seed.
|
|
136
|
+
|
|
137
|
+
### `signature(values, outcome)` <a id="method-c-signature"></a> <a id="signature-class_method"></a>
|
|
138
|
+
Not documented.
|
|
139
|
+
|
|
140
|
+
### `static_reachability(conditions, values, prepared_constraints: = nil)` <a id="method-c-static_reachability"></a> <a id="static_reachability-class_method"></a>
|
|
141
|
+
Conservative static reachability: prove impossibility, or answer unknown.
|
|
142
|
+
|
|
143
|
+
### `summary(decision_id:, rules:, diagnostics:, reachability_analyzed: = true)` <a id="method-c-summary"></a> <a id="summary-class_method"></a>
|
|
144
|
+
Not documented.
|
|
145
|
+
|
|
146
|
+
### `unavailable_reason(decision, limits)` <a id="method-c-unavailable_reason"></a> <a id="unavailable_reason-class_method"></a>
|
|
147
|
+
Names why a decision carries no Boolean table, or nil when it carries one.
|
|
148
|
+
|
|
149
|
+
### `unique_atom_indices?(node, seen = {})` <a id="method-c-unique_atom_indices-3F"></a> <a id="unique_atom_indices?-class_method"></a>
|
|
150
|
+
- **@return** [Boolean]
|
|
151
|
+
|
|
152
|
+
### `unsupported_coverage_entry()` <a id="method-c-unsupported_coverage_entry"></a> <a id="unsupported_coverage_entry-class_method"></a>
|
|
153
|
+
Not documented.
|
|
@@ -7,9 +7,12 @@
|
|
|
7
7
|
|
|
8
8
|
Terminal renderings grouped around conditions or tests.
|
|
9
9
|
|
|
10
|
+
## Constants
|
|
11
|
+
### `DECISION_TABLE_LABELS` <a id="constant-DECISION_TABLE_LABELS"></a> <a id="DECISION_TABLE_LABELS-constant"></a>
|
|
12
|
+
Not documented.
|
|
13
|
+
|
|
10
14
|
## Public Instance Methods
|
|
11
|
-
### `initialize(document:, view:, level:, missing_only: = false)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
|
|
12
|
-
- **@raise** [ArgumentError]
|
|
15
|
+
### `initialize(document:, view:, level:, missing_only: = false, coordinator: = nil)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
|
|
13
16
|
- **@return** [FocusedReport] a new instance of FocusedReport
|
|
14
17
|
|
|
15
18
|
### `render()` <a id="method-i-render"></a> <a id="render-instance_method"></a>
|
data/doc/Branchproof/Loader.md
CHANGED
|
@@ -7,10 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
Owns the process-local CRuby compilation hook when the VM exposes it.
|
|
9
9
|
|
|
10
|
-
## Constants
|
|
11
|
-
### `STATUS_KEYS` <a id="constant-STATUS_KEYS"></a> <a id="STATUS_KEYS-constant"></a>
|
|
12
|
-
Not documented.
|
|
13
|
-
|
|
14
10
|
## Public Instance Methods
|
|
15
11
|
### `diagnostics()` <a id="method-i-diagnostics"></a> <a id="diagnostics-instance_method"></a>
|
|
16
12
|
Not documented.
|
|
@@ -15,9 +15,6 @@ Returns the value of attribute active_adapter.
|
|
|
15
15
|
Returns the value of attribute tests.
|
|
16
16
|
|
|
17
17
|
## Public Instance Methods
|
|
18
|
-
### `capabilities()` <a id="method-i-capabilities"></a> <a id="capabilities-instance_method"></a>
|
|
19
|
-
Not documented.
|
|
20
|
-
|
|
21
18
|
### `initialize(runtime:)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
|
|
22
19
|
- **@return** [MinitestAdapter] a new instance of MinitestAdapter
|
|
23
20
|
|
data/doc/Branchproof/Report.md
CHANGED
|
@@ -11,9 +11,18 @@ Renders versioned terminal and JSON analysis reports.
|
|
|
11
11
|
### `CRITERION_VERSION` <a id="constant-CRITERION_VERSION"></a> <a id="CRITERION_VERSION-constant"></a>
|
|
12
12
|
Not documented.
|
|
13
13
|
|
|
14
|
+
### `DECISION_TABLE_LABELS` <a id="constant-DECISION_TABLE_LABELS"></a> <a id="DECISION_TABLE_LABELS-constant"></a>
|
|
15
|
+
Not documented.
|
|
16
|
+
|
|
17
|
+
### `DECISION_TABLE_STATUS_LABELS` <a id="constant-DECISION_TABLE_STATUS_LABELS"></a> <a id="DECISION_TABLE_STATUS_LABELS-constant"></a>
|
|
18
|
+
Not documented.
|
|
19
|
+
|
|
14
20
|
### `SCHEMA_VERSION` <a id="constant-SCHEMA_VERSION"></a> <a id="SCHEMA_VERSION-constant"></a>
|
|
15
21
|
Not documented.
|
|
16
22
|
|
|
23
|
+
### `VIEWS` <a id="constant-VIEWS"></a> <a id="VIEWS-constant"></a>
|
|
24
|
+
Not documented.
|
|
25
|
+
|
|
17
26
|
## Public Class Methods
|
|
18
27
|
### `from_document(document:, level: = nil, view: = :decisions, missing_only: = false)` <a id="method-c-from_document"></a> <a id="from_document-class_method"></a>
|
|
19
28
|
Not documented.
|
|
@@ -32,6 +41,15 @@ Render the shared ladder in every terminal view.
|
|
|
32
41
|
### `coverage_status_label(status)` <a id="method-i-coverage_status_label"></a> <a id="coverage_status_label-instance_method"></a>
|
|
33
42
|
Not documented.
|
|
34
43
|
|
|
44
|
+
### `decision_table_expected_heading(decision)` <a id="method-i-decision_table_expected_heading"></a> <a id="decision_table_expected_heading-instance_method"></a>
|
|
45
|
+
Not documented.
|
|
46
|
+
|
|
47
|
+
### `decision_table_reachability(rule)` <a id="method-i-decision_table_reachability"></a> <a id="decision_table_reachability-instance_method"></a>
|
|
48
|
+
Not documented.
|
|
49
|
+
|
|
50
|
+
### `decision_table_requirement(value)` <a id="method-i-decision_table_requirement"></a> <a id="decision_table_requirement-instance_method"></a>
|
|
51
|
+
Not documented.
|
|
52
|
+
|
|
35
53
|
### `diagnostic_message(diagnostic)` <a id="method-i-diagnostic_message"></a> <a id="diagnostic_message-instance_method"></a>
|
|
36
54
|
Formats source context consistently in live and saved terminal views.
|
|
37
55
|
|
data/doc/Branchproof/Runtime.md
CHANGED
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
| | |
|
|
4
4
|
| --- | --- |
|
|
5
|
+
| **Extended by** | [Branchproof::RuntimeFlow](RuntimeFlow.md) |
|
|
5
6
|
| **Defined in** | lib/branchproof/runtime.rb |
|
|
6
7
|
|
|
7
8
|
Process-local execution recorder. It deliberately never coerces or stores
|
|
8
9
|
application values: Ruby's conditional expression is used for truthiness.
|
|
9
10
|
Captures condition evaluations while preserving application values.
|
|
10
11
|
|
|
12
|
+
## Constants
|
|
13
|
+
### `FRAME_STATE_KEY` <a id="constant-FRAME_STATE_KEY"></a> <a id="FRAME_STATE_KEY-constant"></a>
|
|
14
|
+
Not documented.
|
|
15
|
+
|
|
11
16
|
## Public Class Methods
|
|
12
17
|
### `boot(evidence:)` <a id="method-c-boot"></a> <a id="boot-class_method"></a>
|
|
13
18
|
Not documented.
|
|
@@ -27,6 +32,24 @@ Not documented.
|
|
|
27
32
|
### `finish(decision_id, value)` <a id="method-c-finish"></a> <a id="finish-class_method"></a>
|
|
28
33
|
Not documented.
|
|
29
34
|
|
|
35
|
+
### `flow_candidate(decision_id, index)` <a id="method-c-flow_candidate"></a> <a id="flow_candidate-class_method"></a>
|
|
36
|
+
Not documented.
|
|
37
|
+
|
|
38
|
+
### `flow_finish(decision_id, value, default_path = nil)` <a id="method-c-flow_finish"></a> <a id="flow_finish-class_method"></a>
|
|
39
|
+
Not documented.
|
|
40
|
+
|
|
41
|
+
### `flow_path(decision_id, index)` <a id="method-c-flow_path"></a> <a id="flow_path-class_method"></a>
|
|
42
|
+
Not documented.
|
|
43
|
+
|
|
44
|
+
### `flow_receiver(decision_id, receiver)` <a id="method-c-flow_receiver"></a> <a id="flow_receiver-class_method"></a>
|
|
45
|
+
Not documented.
|
|
46
|
+
|
|
47
|
+
### `flow_select(decision_id, index)` <a id="method-c-flow_select"></a> <a id="flow_select-class_method"></a>
|
|
48
|
+
Not documented.
|
|
49
|
+
|
|
50
|
+
### `flow_selected(decision_id)` <a id="method-c-flow_selected"></a> <a id="flow_selected-class_method"></a>
|
|
51
|
+
Not documented.
|
|
52
|
+
|
|
30
53
|
### `leave(decision_id)` <a id="method-c-leave"></a> <a id="leave-class_method"></a>
|
|
31
54
|
Not documented.
|
|
32
55
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Module Branchproof::RuntimeFlow <a id="module-Branchproof-RuntimeFlow"></a>
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
| --- | --- |
|
|
5
|
+
| **Defined in** | lib/branchproof/runtime_flow.rb |
|
|
6
|
+
|
|
7
|
+
Records native Ruby path selection without evaluating application values
|
|
8
|
+
twice.
|
|
9
|
+
|
|
10
|
+
## Public Instance Methods
|
|
11
|
+
### `flow_candidate(decision_id, index)` <a id="method-i-flow_candidate"></a> <a id="flow_candidate-instance_method"></a>
|
|
12
|
+
Not documented.
|
|
13
|
+
|
|
14
|
+
### `flow_finish(decision_id, value, default_path = nil)` <a id="method-i-flow_finish"></a> <a id="flow_finish-instance_method"></a>
|
|
15
|
+
Not documented.
|
|
16
|
+
|
|
17
|
+
### `flow_path(decision_id, index)` <a id="method-i-flow_path"></a> <a id="flow_path-instance_method"></a>
|
|
18
|
+
Not documented.
|
|
19
|
+
|
|
20
|
+
### `flow_receiver(decision_id, receiver)` <a id="method-i-flow_receiver"></a> <a id="flow_receiver-instance_method"></a>
|
|
21
|
+
Not documented.
|
|
22
|
+
|
|
23
|
+
### `flow_select(decision_id, index)` <a id="method-i-flow_select"></a> <a id="flow_select-instance_method"></a>
|
|
24
|
+
Not documented.
|
|
25
|
+
|
|
26
|
+
### `flow_selected(decision_id)` <a id="method-i-flow_selected"></a> <a id="flow_selected-instance_method"></a>
|
|
27
|
+
Not documented.
|
|
@@ -14,9 +14,30 @@ Not documented.
|
|
|
14
14
|
### `CRITERION_VERSION` <a id="constant-CRITERION_VERSION"></a> <a id="CRITERION_VERSION-constant"></a>
|
|
15
15
|
Not documented.
|
|
16
16
|
|
|
17
|
+
### `DECISION_KINDS` <a id="constant-DECISION_KINDS"></a> <a id="DECISION_KINDS-constant"></a>
|
|
18
|
+
Not documented.
|
|
19
|
+
|
|
20
|
+
### `DECISION_TABLE_STATUSES` <a id="constant-DECISION_TABLE_STATUSES"></a> <a id="DECISION_TABLE_STATUSES-constant"></a>
|
|
21
|
+
Not documented.
|
|
22
|
+
|
|
23
|
+
### `NONBOOLEAN_KINDS` <a id="constant-NONBOOLEAN_KINDS"></a> <a id="NONBOOLEAN_KINDS-constant"></a>
|
|
24
|
+
Not documented.
|
|
25
|
+
|
|
17
26
|
### `REQUIRED_FIELDS` <a id="constant-REQUIRED_FIELDS"></a> <a id="REQUIRED_FIELDS-constant"></a>
|
|
18
27
|
Not documented.
|
|
19
28
|
|
|
29
|
+
### `RULE_CONDITION_VALUES` <a id="constant-RULE_CONDITION_VALUES"></a> <a id="RULE_CONDITION_VALUES-constant"></a>
|
|
30
|
+
Not documented.
|
|
31
|
+
|
|
32
|
+
### `RULE_COVERAGE_STATUSES` <a id="constant-RULE_COVERAGE_STATUSES"></a> <a id="RULE_COVERAGE_STATUSES-constant"></a>
|
|
33
|
+
Not documented.
|
|
34
|
+
|
|
35
|
+
### `RULE_REACHABILITY_STATUSES` <a id="constant-RULE_REACHABILITY_STATUSES"></a> <a id="RULE_REACHABILITY_STATUSES-constant"></a>
|
|
36
|
+
Not documented.
|
|
37
|
+
|
|
38
|
+
### `STRICT_FLOW_SCHEMAS` <a id="constant-STRICT_FLOW_SCHEMAS"></a> <a id="STRICT_FLOW_SCHEMAS-constant"></a>
|
|
39
|
+
Not documented.
|
|
40
|
+
|
|
20
41
|
### `SUPPORTED_SCHEMAS` <a id="constant-SUPPORTED_SCHEMAS"></a> <a id="SUPPORTED_SCHEMAS-constant"></a>
|
|
21
42
|
Not documented.
|
|
22
43
|
|
data/doc/Branchproof/Source.md
CHANGED
data/doc/Branchproof.md
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
| | |
|
|
4
4
|
| --- | --- |
|
|
5
|
-
| **Defined in** | lib/branchproof.rb, lib/branchproof/cli.rb, lib/branchproof/limits.rb, lib/branchproof/loader.rb, lib/branchproof/report.rb, lib/branchproof/source.rb, lib/branchproof/worker.rb, lib/branchproof/project.rb, lib/branchproof/records.rb, lib/branchproof/runtime.rb, lib/branchproof/version.rb, lib/branchproof/analyzer.rb, lib/branchproof/evidence.rb, lib/branchproof/minimizer.rb, lib/branchproof/comparison.rb, lib/branchproof/instrumenter.rb, lib/branchproof/saved_report.rb, lib/branchproof/rails_support.rb, lib/branchproof/coverage_index.rb, lib/branchproof/focused_report.rb, lib/branchproof/minitest_adapter.rb, lib/branchproof/comparison_report.rb |
|
|
5
|
+
| **Defined in** | lib/branchproof.rb, lib/branchproof/cli.rb, lib/branchproof/limits.rb, lib/branchproof/loader.rb, lib/branchproof/report.rb, lib/branchproof/source.rb, lib/branchproof/worker.rb, lib/branchproof/project.rb, lib/branchproof/records.rb, lib/branchproof/runtime.rb, lib/branchproof/version.rb, lib/branchproof/analyzer.rb, lib/branchproof/evidence.rb, lib/branchproof/minimizer.rb, lib/branchproof/comparison.rb, lib/branchproof/constraints.rb, lib/branchproof/instrumenter.rb, lib/branchproof/runtime_flow.rb, lib/branchproof/saved_report.rb, lib/branchproof/rails_support.rb, lib/branchproof/coverage_index.rb, lib/branchproof/decision_table.rb, lib/branchproof/focused_report.rb, lib/branchproof/decision_syntax.rb, lib/branchproof/minitest_adapter.rb, lib/branchproof/comparison_report.rb, lib/branchproof/flow_instrumentation.rb |
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Keep each bounded source rewrite together so its evaluation order can be
|
|
8
|
+
audited. rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
8
9
|
|
|
9
10
|
## Constants
|
|
10
11
|
### `VERSION` <a id="constant-VERSION"></a> <a id="VERSION-constant"></a>
|
|
@@ -16,9 +17,14 @@ Not documented.
|
|
|
16
17
|
- [Branchproof/CLI.md](Branchproof/CLI.md)
|
|
17
18
|
- [Branchproof/Comparison.md](Branchproof/Comparison.md)
|
|
18
19
|
- [Branchproof/ComparisonReport.md](Branchproof/ComparisonReport.md)
|
|
20
|
+
- [Branchproof/Constraints/Solver.md](Branchproof/Constraints/Solver.md)
|
|
21
|
+
- [Branchproof/Constraints.md](Branchproof/Constraints.md)
|
|
19
22
|
- [Branchproof/CoverageIndex.md](Branchproof/CoverageIndex.md)
|
|
23
|
+
- [Branchproof/DecisionSyntax.md](Branchproof/DecisionSyntax.md)
|
|
24
|
+
- [Branchproof/DecisionTable.md](Branchproof/DecisionTable.md)
|
|
20
25
|
- [Branchproof/Error.md](Branchproof/Error.md)
|
|
21
26
|
- [Branchproof/Evidence.md](Branchproof/Evidence.md)
|
|
27
|
+
- [Branchproof/FlowInstrumentation.md](Branchproof/FlowInstrumentation.md)
|
|
22
28
|
- [Branchproof/FocusedReport.md](Branchproof/FocusedReport.md)
|
|
23
29
|
- [Branchproof/Instrumenter.md](Branchproof/Instrumenter.md)
|
|
24
30
|
- [Branchproof/Limits.md](Branchproof/Limits.md)
|
|
@@ -31,6 +37,7 @@ Not documented.
|
|
|
31
37
|
- [Branchproof/Records.md](Branchproof/Records.md)
|
|
32
38
|
- [Branchproof/Report.md](Branchproof/Report.md)
|
|
33
39
|
- [Branchproof/Runtime.md](Branchproof/Runtime.md)
|
|
40
|
+
- [Branchproof/RuntimeFlow.md](Branchproof/RuntimeFlow.md)
|
|
34
41
|
- [Branchproof/SavedReport.md](Branchproof/SavedReport.md)
|
|
35
42
|
- [Branchproof/Source.md](Branchproof/Source.md)
|
|
36
43
|
- [Branchproof/Worker.md](Branchproof/Worker.md)
|
data/doc/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.8.0] - 2026-09-17
|
|
4
|
+
|
|
5
|
+
- Derive a reduced decision table for every supported Boolean decision from its
|
|
6
|
+
`AND`/`OR`/`NOT`/atom structure, preserving Ruby short-circuit semantics with
|
|
7
|
+
an explicit `dont_care` value instead of exhaustive Cartesian expansion.
|
|
8
|
+
- Give every rule a stable identity derived from the decision, its normalized
|
|
9
|
+
condition vector, the expected outcome, and the table schema version, so
|
|
10
|
+
saved reports compare across runs, test order, and Minitest seeds.
|
|
11
|
+
- Overlay the existing run's observations onto the rules, attribute covered
|
|
12
|
+
rules to their Minitest tests, and describe uncovered rules as condition-value
|
|
13
|
+
requirements. No additional test execution is performed.
|
|
14
|
+
- Report Decision Table Coverage as its own criterion in the coverage ladder,
|
|
15
|
+
per decision and in aggregate, independently from MC/DC in both directions.
|
|
16
|
+
- Add conservative reachability: `observed`, `unknown`, and
|
|
17
|
+
`statically_impossible` with stable reason codes. Constraint analysis version 2
|
|
18
|
+
requires safe source constraints before excluding rules, keeping arbitrary
|
|
19
|
+
comparison receivers, mutation, and unordered numeric cases unknown.
|
|
20
|
+
- Exclude statically impossible rules from coverage denominators while keeping
|
|
21
|
+
them visible, and let runtime evidence withdraw an impossibility claim with a
|
|
22
|
+
`constraint_model_conflict` diagnostic.
|
|
23
|
+
- Add `--view decision-tables`, which honours `--missing-only` and never lists
|
|
24
|
+
an impossible rule as a missing obligation.
|
|
25
|
+
- Bound table derivation with the new `max_conditions_for_decision_table` and
|
|
26
|
+
`decision_table_rules_per_decision` limits.
|
|
27
|
+
- Persist the table, rule identities, coverage, attribution, and reachability in
|
|
28
|
+
schema `1.3` reports, and distinguish rule-coverage changes from reachability
|
|
29
|
+
changes in offline comparison.
|
|
30
|
+
- Enforce exact rule-limit boundaries and index runtime rule matching rather
|
|
31
|
+
than scanning all observations per rule.
|
|
32
|
+
- Add `--no-reachability` to keep all generated rules as coverage obligations.
|
|
33
|
+
- Align the JSON regression flag with decision-table CLI failures, report
|
|
34
|
+
analysis-version changes, and validate saved rule identities and evidence.
|
|
35
|
+
- Keep uncalculated decision locations and reasons in missing-only reports;
|
|
36
|
+
label `unless` and `until` outcomes as predicate values.
|
|
37
|
+
|
|
38
|
+
## [0.7.0] - 2026-09-10
|
|
39
|
+
|
|
40
|
+
- Discover Boolean loop predicates, subjectless case candidates, standalone
|
|
41
|
+
short-circuit expressions, and pattern predicates through Prism.
|
|
42
|
+
- Analyze unary NOT and keyword `and`/`or` with Ruby's parsed precedence.
|
|
43
|
+
- Attribute selected paths for ordinary case, unguarded case/in, safe navigation,
|
|
44
|
+
and conditional assignments without adding them to MC/DC denominators.
|
|
45
|
+
- Expose decision kinds, contexts, alternative evidence, and explicit unsupported
|
|
46
|
+
constructs in schema 1.2 reports while retaining older saved-report support.
|
|
47
|
+
|
|
3
48
|
## [0.6.0] - 2026-09-10
|
|
4
49
|
|
|
5
50
|
- Report Decision, Condition, and Condition/Decision Coverage alongside
|