rigortype 0.4.0 → 0.4.1
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/README.md +4 -3
- data/docs/handbook/08-understanding-errors.md +3 -2
- data/docs/install.md +87 -15
- data/docs/manual/02-cli-reference.md +2 -2
- data/docs/manual/03-configuration.md +5 -0
- data/docs/manual/08-skills.md +4 -3
- data/docs/manual/12-caching.md +43 -4
- data/docs/manual/14-rails-quickstart.md +19 -11
- data/lib/rigor/analysis/check_rules/source_arity.rb +163 -59
- data/lib/rigor/analysis/check_rules.rb +118 -87
- data/lib/rigor/analysis/dependency_recorder.rb +200 -18
- data/lib/rigor/analysis/incremental_run_slot/write_guard.rb +266 -0
- data/lib/rigor/analysis/incremental_run_slot.rb +171 -0
- data/lib/rigor/analysis/incremental_session.rb +273 -49
- data/lib/rigor/analysis/plugin_fact_fingerprint.rb +24 -13
- data/lib/rigor/analysis/reachability/scan_cache.rb +2 -1
- data/lib/rigor/analysis/run_cache_key.rb +27 -8
- data/lib/rigor/analysis/run_stats.rb +2 -2
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +1 -1
- data/lib/rigor/analysis/runner/pool_coordinator.rb +2 -2
- data/lib/rigor/analysis/runner/project_pre_passes.rb +21 -13
- data/lib/rigor/analysis/runner.rb +337 -46
- data/lib/rigor/analysis/shadow_harness.rb +27 -0
- data/lib/rigor/analysis/source_rbs_gate.rb +157 -0
- data/lib/rigor/analysis/template_unit_paths.rb +6 -4
- data/lib/rigor/analysis/template_units.rb +15 -5
- data/lib/rigor/analysis/worker_session.rb +4 -3
- data/lib/rigor/cache/descriptor.rb +40 -1
- data/lib/rigor/cache/file_digest.rb +28 -0
- data/lib/rigor/cache/incremental_snapshot.rb +70 -8
- data/lib/rigor/cache/store.rb +63 -3
- data/lib/rigor/cache/value_digest.rb +325 -0
- data/lib/rigor/cli/check_command.rb +83 -13
- data/lib/rigor/cli/doctor_command.rb +1 -1
- data/lib/rigor/cli/effects_report.rb +2 -2
- data/lib/rigor/cli/unused_command.rb +3 -3
- data/lib/rigor/cli.rb +1 -1
- data/lib/rigor/config_audit.rb +3 -2
- data/lib/rigor/config_path.rb +29 -0
- data/lib/rigor/configuration/severity_profile.rb +5 -0
- data/lib/rigor/configuration.rb +6 -5
- data/lib/rigor/effects/plugin_facts.rb +6 -6
- data/lib/rigor/environment/bundle_sig_discovery.rb +5 -3
- data/lib/rigor/environment/lockfile_resolver.rb +10 -1
- data/lib/rigor/environment/rbs_collection_discovery.rb +10 -1
- data/lib/rigor/environment/rbs_loader.rb +1 -1
- data/lib/rigor/environment/source_rbs_synthesis.rb +147 -0
- data/lib/rigor/environment.rb +13 -70
- data/lib/rigor/inference/block_parameter_binder.rb +29 -13
- data/lib/rigor/inference/captured_locals.rb +7 -1
- data/lib/rigor/inference/declaration_walk/context.rb +195 -0
- data/lib/rigor/inference/declaration_walk/errors.rb +18 -0
- data/lib/rigor/inference/declaration_walk/shadow.rb +147 -0
- data/lib/rigor/inference/declaration_walk/traversal.rb +441 -0
- data/lib/rigor/inference/declaration_walk.rb +7 -0
- data/lib/rigor/inference/def_node_resolver.rb +3 -2
- data/lib/rigor/inference/definer_resolution.rb +266 -0
- data/lib/rigor/inference/expression_typer.rb +136 -45
- data/lib/rigor/inference/external_ancestor_resolution.rb +13 -16
- data/lib/rigor/inference/guard_rebinding.rb +53 -12
- data/lib/rigor/inference/macro_block_self_type.rb +14 -2
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +46 -26
- data/lib/rigor/inference/module_function_state.rb +213 -0
- data/lib/rigor/inference/multi_target_binder.rb +21 -16
- data/lib/rigor/inference/narrowing.rb +147 -17
- data/lib/rigor/inference/parameter_inference_collector.rb +10 -9
- data/lib/rigor/inference/scope_indexer/certainty.rb +176 -0
- data/lib/rigor/inference/scope_indexer/class_cvars_collector.rb +35 -0
- data/lib/rigor/inference/scope_indexer/def_nestings_collector.rb +47 -0
- data/lib/rigor/inference/scope_indexer/layered_def_nestings.rb +36 -0
- data/lib/rigor/inference/scope_indexer/member_layouts_collector.rb +61 -0
- data/lib/rigor/inference/scope_indexer/mixin_accumulator.rb +130 -0
- data/lib/rigor/inference/scope_indexer/superclasses_collector.rb +64 -0
- data/lib/rigor/inference/scope_indexer.rb +1443 -295
- data/lib/rigor/inference/singleton_hook_decline.rb +253 -0
- data/lib/rigor/inference/statement_evaluator.rb +80 -14
- data/lib/rigor/plugin/base.rb +28 -8
- data/lib/rigor/plugin/io_boundary.rb +82 -4
- data/lib/rigor/plugin/isolation.rb +1 -1
- data/lib/rigor/plugin/trust_policy.rb +3 -3
- data/lib/rigor/protection/discovery_seed.rb +18 -9
- data/lib/rigor/protection/mutation_cache.rb +3 -3
- data/lib/rigor/reflection/constant_ancestors.rb +96 -47
- data/lib/rigor/reflection/constant_path.rb +22 -7
- data/lib/rigor/reflection.rb +2 -3
- data/lib/rigor/scope/discovery_index.rb +218 -2
- data/lib/rigor/scope/resolution_chain/relevance.rb +165 -0
- data/lib/rigor/scope/resolution_chain.rb +884 -0
- data/lib/rigor/scope.rb +295 -322
- data/lib/rigor/sig_gen/alias_index.rb +1 -1
- data/lib/rigor/sig_gen/effect_annotation.rb +2 -2
- data/lib/rigor/sig_gen/generator.rb +22 -16
- data/lib/rigor/type/combinator.rb +25 -1
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +10 -0
- data/sig/rigor/environment.rbs +2 -0
- data/sig/rigor/plugin/io_boundary.rbs +1 -0
- data/sig/rigor/scope.rbs +43 -1
- data/skills/rigor-project-init/SKILL.md +37 -11
- data/skills/rigor-project-init/references/02-configure.md +7 -2
- metadata +25 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c26e2df607ebe3e1ef3b0c34a329aea4b1b0c80ec311cf6d9a83c4a58a358dfa
|
|
4
|
+
data.tar.gz: 2c4097594c8abe73819197a867cbb9a7b7dc3de86d8a2f22a2a83b1f948fa63a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d790e8fdb333983f82d85fb13036661ef87ca82d273b86955e1c7fa3191a65d027a04ea92fb4877edeb24f3df6bdae4dc03780791a79b15510ea5c7b494f23b6
|
|
7
|
+
data.tar.gz: b1258c842c5e656aea59b32eb91310cdda72a9dade402c87d2523bae3e4fa927f6607b0e2acd4250d24bfcba77e27df778aaf02c50c57300b6c27099c312c098
|
data/README.md
CHANGED
|
@@ -91,8 +91,9 @@ It installs Rigor, then runs the bundled **`rigor-project-init`**
|
|
|
91
91
|
[Agent Skill](https://agentskills.io/): it walks your `Gemfile`,
|
|
92
92
|
proposes plugins matched to your stack (Rails, Sinatra, dry-rb, …),
|
|
93
93
|
lets you pick an adoption mode — **baseline** (acknowledge existing
|
|
94
|
-
diagnostics, work them down incrementally
|
|
95
|
-
(zero-diagnostic gate from day one
|
|
94
|
+
diagnostics, work them down incrementally; the recommended
|
|
95
|
+
default) or **strict** (zero-diagnostic gate from day one, an
|
|
96
|
+
opt-in for users fluent in type theory and RBS) — and commits a ready-to-use
|
|
96
97
|
configuration.
|
|
97
98
|
|
|
98
99
|
**This works in your language.** The prompt is plain natural
|
|
@@ -231,7 +232,7 @@ rigor docs --list # list every bundled page
|
|
|
231
232
|
|
|
232
233
|
## Status
|
|
233
234
|
|
|
234
|
-
Current release: **`v0.4.
|
|
235
|
+
Current release: **`v0.4.1`** (2026-10-08) — on the
|
|
235
236
|
`0.4.x` line, continuing the evaluation era opened by `v0.2.0`, the first
|
|
236
237
|
publicly-announced (general / evaluation) release. The line publishes
|
|
237
238
|
an enumerated [compatibility surface](docs/compatibility.md) as a
|
|
@@ -114,8 +114,9 @@ mostly a question of *how much* you want to say:
|
|
|
114
114
|
|
|
115
115
|
1. **`severity_profile:`** — the project's overall stance.
|
|
116
116
|
`lenient` for a legacy codebase you are easing Rigor into,
|
|
117
|
-
`balanced` for everyday work,
|
|
118
|
-
|
|
117
|
+
`balanced` for everyday work, new projects included, and
|
|
118
|
+
`strict` only if you are ready to resolve inference gaps
|
|
119
|
+
through signatures and RBS yourself.
|
|
119
120
|
2. **`severity_overrides:`** — one rule (or one family) at a
|
|
120
121
|
different severity from the rest of the profile. The right
|
|
121
122
|
layer when a rule is *useful but not blocking* for you.
|
data/docs/install.md
CHANGED
|
@@ -10,19 +10,42 @@ skill (`rigor-project-init` for a project that has never run Rigor).
|
|
|
10
10
|
**Do not add Rigor to the project's `Gemfile`** — Rigor is a
|
|
11
11
|
standalone tool, not a library.
|
|
12
12
|
|
|
13
|
+
**Install the latest release, not whatever is already on the
|
|
14
|
+
machine.** A `rigor` already on PATH, or a version manager that
|
|
15
|
+
resolves to an older release, is not a reason to stop early: Rigor
|
|
16
|
+
changes quickly, and the skills this guide hands off to are written
|
|
17
|
+
for the current release. Step 1 looks up the latest version; Step 2
|
|
18
|
+
installs it and Step 3 checks it.
|
|
19
|
+
|
|
13
20
|
---
|
|
14
21
|
|
|
15
22
|
## Step 1 — Detect the environment
|
|
16
23
|
|
|
17
|
-
Run these
|
|
24
|
+
Run these checks and note which tools are available:
|
|
18
25
|
|
|
19
26
|
```sh
|
|
20
27
|
which mise # preferred — see Step 2A
|
|
21
28
|
which asdf # fallback — see Step 2B
|
|
22
29
|
ruby --version 2>/dev/null | head -1 # is Ruby 4.0 already on PATH?
|
|
23
|
-
which docker # last resort — see
|
|
30
|
+
which docker # last resort — see "Last resort — Docker"
|
|
31
|
+
rigor --version 2>/dev/null # an existing install, if any
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Then look up the latest Rigor release on RubyGems:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
curl -fsS https://rubygems.org/api/v1/versions/rigortype/latest.json
|
|
24
38
|
```
|
|
25
39
|
|
|
40
|
+
It prints `{"version":"X.Y.Z"}`. Below, `<LATEST>` stands for that
|
|
41
|
+
`X.Y.Z`: replace it with the version you got, never type `<LATEST>`
|
|
42
|
+
literally. Without `curl`, `gem search --remote --exact rigortype`
|
|
43
|
+
gives the same answer once Ruby is available. If neither works, tell
|
|
44
|
+
the user you could not determine the latest version instead of
|
|
45
|
+
guessing one.
|
|
46
|
+
|
|
47
|
+
An existing `rigor` older than `<LATEST>` still goes through Step 2;
|
|
48
|
+
tell the user which version they have and which you are installing.
|
|
26
49
|
Then proceed to the **first** matching case below.
|
|
27
50
|
|
|
28
51
|
---
|
|
@@ -40,23 +63,51 @@ that can be committed alongside the code. Other contributors — and CI
|
|
|
40
63
|
— run `mise install` to restore those versions with no `Gemfile`
|
|
41
64
|
involvement.
|
|
42
65
|
|
|
43
|
-
|
|
66
|
+
First ask mise which Rigor version it would pick:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
mise latest gem:rigortype
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
If that is older than `<LATEST>`, mise is holding the newer release
|
|
73
|
+
back — usually its `minimum_release_age` quarantine, which hides
|
|
74
|
+
releases for a while after they are published (`mise ls-remote
|
|
75
|
+
gem:rigortype` then warns `1 newer gem:rigortype release hidden by
|
|
76
|
+
minimum_release_age` on stderr). A bare `mise use gem:rigortype`
|
|
77
|
+
would install the older version with no error, so this is the step where agents
|
|
78
|
+
silently end up on a stale Rigor. The quarantine is a supply-chain
|
|
79
|
+
safeguard, so do not bypass it on your own: tell the user both
|
|
80
|
+
versions and ask which to install. `mise settings get
|
|
81
|
+
minimum_release_age` tells you whose choice it is: an error ("not
|
|
82
|
+
set") means mise's built-in default is in effect and you can recommend
|
|
83
|
+
`<LATEST>`; a value means the user configured it, so recommend
|
|
84
|
+
respecting it.
|
|
85
|
+
|
|
86
|
+
Then run in the project root, with the version the user agreed to:
|
|
44
87
|
|
|
45
88
|
```sh
|
|
46
89
|
mise use ruby@4.0
|
|
47
|
-
mise use --pin gem:rigortype
|
|
90
|
+
mise use --pin gem:rigortype@<LATEST>
|
|
48
91
|
```
|
|
49
92
|
|
|
50
93
|
`mise use` installs the tools and writes their versions to `mise.toml`
|
|
51
|
-
in one step. Commit `mise.toml` so the version is shared.
|
|
94
|
+
in one step. Commit `mise.toml` so the version is shared. Name the
|
|
95
|
+
version explicitly, as above: an explicit version is installed even
|
|
96
|
+
while the quarantine hides it from `mise latest`.
|
|
52
97
|
|
|
53
|
-
`--pin` records the exact Rigor version (`"gem:rigortype" = "
|
|
98
|
+
`--pin` records the exact Rigor version (`"gem:rigortype" = "X.Y.Z"`).
|
|
54
99
|
Without it mise writes `"gem:rigortype" = "latest"`, which every
|
|
55
100
|
machine re-resolves to whatever is newest when it first installs — so
|
|
56
101
|
a committed `latest` does not give the team one shared version. The
|
|
57
102
|
trade-off: a pin will not move on its own, and `mise outdated` cannot
|
|
58
|
-
report a pinned tool as behind. Upgrade
|
|
59
|
-
gem:rigortype
|
|
103
|
+
report a pinned tool as behind. Upgrade by running `mise use --pin
|
|
104
|
+
gem:rigortype@<version>` again with the newer version; `mise upgrade
|
|
105
|
+
--bump gem:rigortype` goes through the same quarantine as a bare
|
|
106
|
+
`mise use`.
|
|
107
|
+
|
|
108
|
+
A user-wide `~/.config/mise/config.toml` entry for `gem:rigortype`
|
|
109
|
+
keeps applying outside this project. Mention it if it names an older
|
|
110
|
+
version, but do not edit global config without the user's consent.
|
|
60
111
|
|
|
61
112
|
Then verify:
|
|
62
113
|
|
|
@@ -88,7 +139,8 @@ gem is installed with `gem install` after setting the Ruby version.
|
|
|
88
139
|
```sh
|
|
89
140
|
asdf install ruby latest:4.0
|
|
90
141
|
asdf local ruby latest:4.0
|
|
91
|
-
gem install rigortype
|
|
142
|
+
gem install rigortype -v <LATEST>
|
|
143
|
+
asdf reshim ruby
|
|
92
144
|
```
|
|
93
145
|
|
|
94
146
|
Verify:
|
|
@@ -108,7 +160,7 @@ pinning; see <https://mise.jdx.dev/getting-started.html>.
|
|
|
108
160
|
If `ruby --version` reports `ruby 4.0.*`, install the gem directly:
|
|
109
161
|
|
|
110
162
|
```sh
|
|
111
|
-
gem install rigortype
|
|
163
|
+
gem install rigortype -v <LATEST>
|
|
112
164
|
```
|
|
113
165
|
|
|
114
166
|
Verify:
|
|
@@ -152,6 +204,11 @@ and does not integrate well with editor LSP. Use it only when a
|
|
|
152
204
|
host-side Ruby 4.0 is genuinely unavailable (for example, Windows
|
|
153
205
|
without WSL). For all other environments, prefer Case A–D above.
|
|
154
206
|
|
|
207
|
+
With Docker there is no `rigor` on the host PATH, so Step 3 checks the
|
|
208
|
+
image instead: `docker run --rm ghcr.io/rigortype/rigor:latest rigor
|
|
209
|
+
--version`. The image can trail RubyGems by a release; report its
|
|
210
|
+
version to the user rather than treating a mismatch as a failure.
|
|
211
|
+
|
|
155
212
|
---
|
|
156
213
|
|
|
157
214
|
## Step 3 — Verify the installation
|
|
@@ -160,8 +217,23 @@ without WSL). For all other environments, prefer Case A–D above.
|
|
|
160
217
|
rigor --version
|
|
161
218
|
```
|
|
162
219
|
|
|
163
|
-
|
|
164
|
-
If
|
|
220
|
+
The reported version should be the one you installed in Step 2
|
|
221
|
+
(normally `<LATEST>`). If it is older, you are running a different
|
|
222
|
+
`rigor` than the one just installed. With mise, first check what the
|
|
223
|
+
project resolves to:
|
|
224
|
+
|
|
225
|
+
```sh
|
|
226
|
+
mise exec -- rigor --version
|
|
227
|
+
mise which rigor
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
If `mise exec` reports the new version, the shell's PATH is stale (a
|
|
231
|
+
non-interactive shell does not re-run mise's activation after `mise
|
|
232
|
+
use`); run `eval "$(mise hook-env)"`, or use `mise exec -- rigor` for
|
|
233
|
+
the remaining steps. Otherwise run `which -a rigor` to find the older
|
|
234
|
+
install. Do not uninstall anything to fix this without asking, and do
|
|
235
|
+
not continue on the older version without telling the user. If the
|
|
236
|
+
command is not found, revisit Step 2 for your case.
|
|
165
237
|
|
|
166
238
|
---
|
|
167
239
|
|
|
@@ -192,6 +264,6 @@ project is set up, re-run `rigor skill describe` for the step after
|
|
|
192
264
|
that.
|
|
193
265
|
|
|
194
266
|
If `rigor skill describe` is not recognised, your Rigor version predates
|
|
195
|
-
it
|
|
196
|
-
|
|
197
|
-
|
|
267
|
+
it: you are not on the version Step 1 found. Go back to Step 3. If
|
|
268
|
+
you are staying on an older version with the user's agreement, run
|
|
269
|
+
`rigor skill rigor-project-init` directly.
|
|
@@ -34,8 +34,8 @@ the `paths:` list from the configuration file.
|
|
|
34
34
|
| `--format=FORMAT` | Output format. Default `text`. Also `json` (structured stream), plus the CI-native renderings `sarif`, `github`, `gitlab`, `checkstyle`, `junit`, and `teamcity` — see [Running Rigor in CI](11-ci.md). |
|
|
35
35
|
| `--no-ci-detect` | Disable CI auto-detection — by default `text` output also emits the running CI's native annotations / hint (`RIGOR_CI_DETECT=0` does the same). See [Running Rigor in CI § auto-detection](11-ci.md). |
|
|
36
36
|
| `--explain` | Surface fail-soft fallback events as `info` diagnostics. |
|
|
37
|
-
| `--no-cache` | Skip the persistent cache for this run. |
|
|
38
|
-
| `--incremental` | Re-analyse only the files changed since the last run plus the files that depend on them, serving the rest from a cross-process disk snapshot (ADR-46). Diagnostics are identical to a full run; a config / gem / version change (or a file added or removed) transparently forces a full re-analysis. See [Caching](12-caching.md). |
|
|
37
|
+
| `--no-cache` | Skip the persistent cache for this run. With `--incremental` it is a cold full analysis: the incremental snapshot and the run-result cache are neither read nor written, so the next plain `--incremental` run still uses the snapshot it had before. |
|
|
38
|
+
| `--incremental` | Re-analyse only the files changed since the last run plus the files that depend on them, serving the rest from a cross-process disk snapshot (ADR-46). Diagnostics are identical to a full run; a config / gem / version change (or a file added or removed) transparently forces a full re-analysis. A run with nothing changed is answered from the cache without starting the analyzer. See [Caching](12-caching.md). |
|
|
39
39
|
| `--verify-incremental` | Acceptance gate: run the incremental analyzer against a full `--no-cache` run and assert the diagnostics are byte-identical, then exit (0 on match, 1 with the differing diagnostics on mismatch). Used in CI to guarantee `--incremental` never serves a stale result. |
|
|
40
40
|
| `--clear-cache` | Delete the cache directory before running. |
|
|
41
41
|
| `--cache-stats` | Print the on-disk cache inventory when finished — on stdout under `--format text`, on stderr under every other format, so machine-readable output stays a parseable document. `--clear-cache`'s and `--verify-incremental`'s notes follow the same rule. |
|
|
@@ -21,6 +21,11 @@ discovery entirely.
|
|
|
21
21
|
|
|
22
22
|
All relative paths in a config file resolve against that
|
|
23
23
|
file's own directory.
|
|
24
|
+
A leading `~/` (or a bare `~`) in a path setting expands to your home directory; `~name` is an ordinary
|
|
25
|
+
directory called `~name`, not another user's home. This covers `paths:`, `signature_paths:`, `test_paths:`,
|
|
26
|
+
`pre_eval:`, `plugins_io.allowed_paths:`, `includes:`, `bundler.bundle_path:`, `bundler.lockfile:` and
|
|
27
|
+
`rbs_collection.lockfile:`. It does not apply to `cache.path:`, `baseline:` or `effects.snapshot.path:`, which stay
|
|
28
|
+
literal and relative to the working directory.
|
|
24
29
|
|
|
25
30
|
## Editor validation
|
|
26
31
|
|
data/docs/manual/08-skills.md
CHANGED
|
@@ -60,9 +60,10 @@ is not repeated here.)
|
|
|
60
60
|
- **`rigor-project-init`** — onboards a project from a cold start. It
|
|
61
61
|
detects the stack (Rails, RSpec, dry-rb, …), proposes the matching
|
|
62
62
|
[plugins](07-plugins.md), picks an adoption mode — a
|
|
63
|
-
[baseline](06-baseline.md) snapshot
|
|
64
|
-
zero-diagnostic gate for
|
|
65
|
-
|
|
63
|
+
[baseline](06-baseline.md) snapshot by default, new projects
|
|
64
|
+
included, or an opt-in zero-diagnostic gate for users fluent in type
|
|
65
|
+
theory and RBS — writes a `.rigor.dist.yml`, and generates the first
|
|
66
|
+
baseline. Reach for it when setting Rigor up for
|
|
66
67
|
the first time.
|
|
67
68
|
- **`rigor-rbs-setup`** — installs community RBS for your gems
|
|
68
69
|
(`rbs collection install`) so RBS-less dependencies stop typing as
|
data/docs/manual/12-caching.md
CHANGED
|
@@ -135,7 +135,7 @@ CI detection that `auto` relies on.
|
|
|
135
135
|
|
|
136
136
|
| Flag | Effect |
|
|
137
137
|
| --- | --- |
|
|
138
|
-
| `rigor check --no-cache` | Run without reading or writing the persistent cache. |
|
|
138
|
+
| `rigor check --no-cache` | Run without reading or writing the persistent cache. With `--incremental` this includes the snapshot: every file is analysed and the snapshot on disk is left untouched. |
|
|
139
139
|
| `rigor check --clear-cache` | Delete the cache directory, then run. |
|
|
140
140
|
| `rigor check --cache-stats` | Print the on-disk cache inventory when the run finishes (on stderr under every `--format` but `text`, so the document on stdout stays parseable). |
|
|
141
141
|
| `rigor check --incremental` | Re-analyse only what changed; serve the rest from the incremental snapshot (see below). |
|
|
@@ -144,9 +144,12 @@ There is no config key to disable caching permanently — the
|
|
|
144
144
|
flags are per-run toggles. To run without a persistent cache
|
|
145
145
|
habitually, point `cache.path` at a disposable directory.
|
|
146
146
|
|
|
147
|
+
With `--incremental --no-cache` and an editor buffer (`--tmp-file` with `--instead-of`), the buffer is analysed on its own, as it is when no snapshot exists, and the note says that `--no-cache` skipped the snapshot rather than suggesting `rigor check --incremental`.
|
|
148
|
+
|
|
147
149
|
## Size and eviction
|
|
148
150
|
|
|
149
|
-
A project's active cache set is
|
|
151
|
+
A project's active cache set is a few megabytes (about 10 MB
|
|
152
|
+
for a Rails application the size of Mastodon). Entries
|
|
150
153
|
are content-keyed, so events like a gem upgrade or an `.rbs`
|
|
151
154
|
edit write fresh entries and leave the old ones *orphaned* —
|
|
152
155
|
nothing references them, and no run would otherwise delete
|
|
@@ -219,9 +222,45 @@ dependents of removed ones.) As with the rest of the cache, a
|
|
|
219
222
|
missing or corrupt snapshot is simply a full run; it can never
|
|
220
223
|
wedge analysis.
|
|
221
224
|
|
|
225
|
+
When nothing has changed since the last `--incremental` run, the
|
|
226
|
+
answer comes straight from the cache, without starting the
|
|
227
|
+
analyzer at all. Rigor first checks the inputs that answer was
|
|
228
|
+
computed from — your source files and view templates, your RBS,
|
|
229
|
+
your configuration and the files your plugins read — and runs the
|
|
230
|
+
ordinary incremental re-check the moment any of them differs. On
|
|
231
|
+
a Rails application the size of Mastodon, an unchanged
|
|
232
|
+
`--incremental` run takes about a quarter of a second. An
|
|
233
|
+
unchanged plain `rigor check` skips the analyzer the same way,
|
|
234
|
+
except when a plugin compiles your view templates, as
|
|
235
|
+
rigor-actionpack does.
|
|
236
|
+
|
|
237
|
+
The shortcut stands aside under `--workers=N` (or
|
|
238
|
+
`parallel.workers:`), `--explain`, `--cache-stats`, `--coverage`,
|
|
239
|
+
an editor buffer, and an `effects:` block, and when the cache
|
|
240
|
+
directory is on a different filesystem from the project; those
|
|
241
|
+
runs re-check as before. It also switches itself off, silently:
|
|
242
|
+
|
|
243
|
+
- when an input changes that the ordinary re-check does not look
|
|
244
|
+
at itself: an auto-detected `sig/` directory (one you did not
|
|
245
|
+
list under `signature_paths:`), a file a narrower
|
|
246
|
+
`rigor check --incremental DIR` only discovers from the rest of
|
|
247
|
+
your configured `paths:`, or a `pre_eval:` file outside the
|
|
248
|
+
analysed paths. The re-check may keep printing the answer from
|
|
249
|
+
before that change; the shortcut does not repeat it;
|
|
250
|
+
- when an `--incremental` run cannot record its answer safely:
|
|
251
|
+
after a run with `--workers=N` that re-analysed files, when a file or directory changes while a run is reading
|
|
252
|
+
it, after a CI cache is restored onto a fresh checkout, or when
|
|
253
|
+
two runs race.
|
|
254
|
+
|
|
255
|
+
Either way it stays off, and every run is an ordinary re-check,
|
|
256
|
+
until the next full analysis. The ordinary re-check never starts
|
|
257
|
+
one by itself: only a configuration, `Gemfile.lock` or Rigor
|
|
258
|
+
version change does, or `--clear-cache`. So the shortcut can stay
|
|
259
|
+
off indefinitely; run `rigor check --incremental --clear-cache`
|
|
260
|
+
once to turn it back on.
|
|
261
|
+
|
|
222
262
|
`--incremental` is most useful for fast local re-checks and CI
|
|
223
|
-
on a changed branch.
|
|
224
|
-
the ordinary cache already serves the whole result in one step.
|
|
263
|
+
on a changed branch.
|
|
225
264
|
|
|
226
265
|
## Concurrency
|
|
227
266
|
|
|
@@ -90,8 +90,9 @@ It runs eight phases in order:
|
|
|
90
90
|
2. **Choose an adoption mode** — proposes either *acknowledge*
|
|
91
91
|
(snapshot today's diagnostics into a baseline; catch
|
|
92
92
|
regressions going forward) or *strict* (drive the project to
|
|
93
|
-
zero and keep it there). It recommends acknowledge for
|
|
94
|
-
|
|
93
|
+
zero and keep it there). It recommends acknowledge for every
|
|
94
|
+
project, new ones included; strict is an opt-in for users
|
|
95
|
+
fluent in type theory and RBS.
|
|
95
96
|
3. **Select plugins** — proposes the plugin set matching your
|
|
96
97
|
detected stack; you confirm or trim the list.
|
|
97
98
|
4. **Write `.rigor.dist.yml`** — the committed shared config,
|
|
@@ -151,14 +152,19 @@ source-of-truth copy is
|
|
|
151
152
|
|
|
152
153
|
| Mode | When | What happens |
|
|
153
154
|
| --- | --- | --- |
|
|
154
|
-
| **Acknowledge** |
|
|
155
|
-
| **Strict** |
|
|
155
|
+
| **Acknowledge** | Recommended for every project, new ones included | Record today's diagnostics in a baseline; surface only new ones on each PR. |
|
|
156
|
+
| **Strict** | Opt-in, for users fluent in type theory and RBS | Zero outstanding diagnostics; no baseline. |
|
|
156
157
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
Start with acknowledge mode even on a brand-new project. Rigor's
|
|
159
|
+
inference still has gaps, so a zero-diagnostic gate meets
|
|
160
|
+
diagnostics on correct code, and clearing those means fixing
|
|
161
|
+
signatures or RBS rather than your code. Choose strict only if
|
|
162
|
+
you are comfortable doing that yourself. You can tighten later.
|
|
163
|
+
|
|
164
|
+
In `.rigor.dist.yml` (Step 3) the mode maps to a
|
|
165
|
+
`severity_profile:`. Acknowledge mode uses the default `balanced`
|
|
166
|
+
(omit the key), or `lenient` when the first `rigor check` reports
|
|
167
|
+
more than ~100 diagnostics; strict mode uses `strict`.
|
|
162
168
|
|
|
163
169
|
### Step 3 — Write .rigor.dist.yml
|
|
164
170
|
|
|
@@ -198,7 +204,7 @@ plugins:
|
|
|
198
204
|
- rigor-rspec
|
|
199
205
|
- rigor-factorybot
|
|
200
206
|
|
|
201
|
-
severity_profile: lenient # "strict" for strict mode
|
|
207
|
+
# severity_profile: lenient # only for >100 initial diagnostics; "strict" for strict mode
|
|
202
208
|
|
|
203
209
|
# baseline: .rigor-baseline.yml # uncomment after Step 6 (acknowledge mode only)
|
|
204
210
|
```
|
|
@@ -288,7 +294,9 @@ first, then large clusters to record in a baseline.
|
|
|
288
294
|
|
|
289
295
|
### Step 6 — Generate a baseline (acknowledge mode)
|
|
290
296
|
|
|
291
|
-
*Skip this step if you chose strict mode.*
|
|
297
|
+
*Skip this step if you chose strict mode.* Settle `severity_profile:`
|
|
298
|
+
first: changing it afterwards changes which rules fire and leaves the
|
|
299
|
+
baseline out of step.
|
|
292
300
|
|
|
293
301
|
```sh
|
|
294
302
|
rigor baseline generate
|