main gained six PRs (#1-#6) while the audit fixes and the state-map seam were in progress. Four of main's commits fixed the same bugs this branch did, independently; where they overlap, the more complete version wins: - Fingerprints: main's (a0844bb) - catchSite (`member#index` among all catches), union/owner as identity, a legacy fingerprint so version-1 baselines still match, baseline "version": 2. This branch's `catch` ordinal is dropped; its fingerprint_test still guards the result. - verify --rule: main's verifyAnalysis (cf9e0b7), which also reports findings in skipped files as NOT SCANNED. - Unreadable SDK: both kept - this branch's up-front probe gives the early, specific error; main's catch around the analyzer (d6b6bcb) is the backstop. - Riverpod: main's "a ref.listen is not a render" (f6411dc) and this branch's AsyncError patterns / stored-value tracking compose; the fixture keeps both sets of cases. Ported onto the model-only rules (the seam), since main edited code this branch had moved into front-end facts: - excerpt.dart's literal-free, bounded quoting (a prompt-injection guard) now also covers front-end facts: SwallowedFailure.handler and NonSubscribingRead.excerpt, and the C++ front end elides string literals in handler evidence the same way. - ScanCoverage: runChecks stays source-free; the model carries coverage (`scanCoverage` in the state JSON, written by both front ends), so `check --model` states coverage like a source check. - main's softened wording (rendered-not-emitted "probably unreachable", the remove-policy dead-handler text, notifier-field-unread) and the backticked flag message. Docs: main's README grew the Firestore query inventory and the output contract; the README stays short, the inventory moves to docs/queries.md, and the contract, exit codes, verify and baseline details join docs/usage.md. Checked against origin/main on resolved mirrors of the dogfood apps: nuwayze (102), dex (0) and word_alive (0) identical; tick differs only by the intended riverpod stored-value fix. On the fixture every difference is one of this branch's fixes. 214 tests pass.
56 lines
1.9 KiB
Markdown
56 lines
1.9 KiB
Markdown
# Development
|
|
|
|
## Building
|
|
|
|
```bash
|
|
dart pub get
|
|
tool/build_release.sh # `dart build cli`, falling back to `dart compile exe`
|
|
```
|
|
|
|
Use the native binary rather than `dart run`: JIT startup is paid on every
|
|
invocation. On macOS arm64:
|
|
|
|
| Scenario | `dart run` | AOT binary |
|
|
| --- | --- | --- |
|
|
| 2-file project | 6.4s | 0.2s |
|
|
| 814-file Flutter app, end to end | ~23-29s | 10.4s |
|
|
| per-file p50 on that app | ~50-75ms | 16ms |
|
|
|
|
The binary is about 18MB and self-contained. On a large project the first file
|
|
costs about 3s of analyzer warm-up (SDK and package summaries). Cutting that
|
|
would need a persistent analysis cache.
|
|
|
|
## Tests
|
|
|
|
```bash
|
|
dart test
|
|
```
|
|
|
|
The rule suite runs against `test/fixtures/stuck_loading`, a dependency-free
|
|
project with hand-written stand-ins for BLoC, Riverpod and provider, so it
|
|
resolves with no `pub get` and no network. Do not add a `package:` import to
|
|
it. The query inventory runs against `test/fixtures/firestore_queries`, which
|
|
carries a hand-written `cloud_firestore` skeleton and a gateway adapter.
|
|
|
|
What the suite holds pipe to:
|
|
|
|
- every rule has a positive and a negative control (`rule_contract_test.dart`);
|
|
- no fingerprint depends on position, and none collide (`fingerprint_test.dart`);
|
|
- the state model survives JSON unchanged, with identical findings
|
|
(`state_map_roundtrip_test.dart`);
|
|
- partial, unreadable and unresolved scans are reported, never passed silently.
|
|
|
|
`test/cpp_front_test.dart` runs the C++ front end on `test/fixtures/cpp_state`
|
|
and is skipped without Homebrew LLVM.
|
|
|
|
## Hooks and CI
|
|
|
|
`git config core.hooksPath .githooks` enables the hooks. `pre-commit` runs
|
|
`scripts/lint.sh --hook` (format and analyze); `pre-push` runs
|
|
`scripts/pre-push-ci-gate.sh` (format, analyze and the full test suite).
|
|
Commit messages follow Conventional Commits (`commitlint.config.js`).
|
|
|
|
## Measuring precision and recall
|
|
|
|
See [rules.md](rules.md#how-precision-is-measured) for `tool/adjudicate.py` and
|
|
`pipe recall`.
|