diff --git a/audit/static/run_static.py b/audit/static/run_static.py index b884675c..9e0d5295 100755 --- a/audit/static/run_static.py +++ b/audit/static/run_static.py @@ -363,7 +363,7 @@ def check(ok: bool, msg: str) -> None: # total derives from the call count def _fake_own_check(target_, out_dir_, severity_, root=None): facts = Path(out_dir_) / "own-check.facts.json" - facts.write_text(json.dumps({"ownir_version": 1, "module": "App", "components": [ + facts.write_text(json.dumps({"ownir_version": 2, "module": "App", "components": [ {"name": "CustomerView", "file": "Views/CustomerView.xaml.cs", "subscriptions": [ {"event": "_bus.Changed", "handler": "OnChanged", "line": 21, "released": False}]}]}), encoding="utf-8") @@ -419,7 +419,7 @@ def _fake_own_check(target_, out_dir_, severity_, root=None): ' x:Class="App.Views.CustomerView" Loaded="OnLoaded" />\n', encoding="utf-8") (out5 / "own-check.facts.json").write_text(json.dumps({ - "ownir_version": 1, "module": "Stale", "components": [ + "ownir_version": 2, "module": "Stale", "components": [ {"name": "CustomerView", "file": "Views/CustomerView.xaml.cs", "subscriptions": [{"event": "_bus.Changed", "handler": "OnChanged", "line": 21, "released": False}]}]}), encoding="utf-8") diff --git a/audit/static/tools/xaml_join.py b/audit/static/tools/xaml_join.py index 82e91691..f0140314 100644 --- a/audit/static/tools/xaml_join.py +++ b/audit/static/tools/xaml_join.py @@ -303,7 +303,7 @@ def check(ok: bool, msg: str) -> None: "event_handlers": [{"event": "Loaded", "handler": "OnLoaded", "line": 4}], "bindings": [], "named_elements": []}, ]} - ownir = {"ownir_version": 1, "module": "App", "components": [ + ownir = {"ownir_version": 2, "module": "App", "components": [ {"name": "CustomerView", "file": "Views/CustomerView.xaml.cs", "subscriptions": [ {"event": "_bus.Changed", "handler": "OnChanged", "line": 21, "released": False}]}, {"name": "CleanView", "file": "Views/CleanView.xaml.cs", "subscriptions": [ @@ -363,7 +363,7 @@ def check(ok: bool, msg: str) -> None: wrong_ns = {"documents": [{"file": "Features/Billing/CustomerView.xaml", "x_class": "Billing.CustomerView", "event_handlers": [{"event": "Loaded", "handler": "OnLoaded", "line": 4}]}]} - other = {"ownir_version": 1, "components": [ + other = {"ownir_version": 2, "components": [ {"name": "CustomerView", "file": "Legacy/CustomerView.cs", "subscriptions": [ {"event": "_bus.Changed", "handler": "OnChanged", "line": 9, "released": False}]}]} check(join(wrong_ns, other) == [], diff --git a/docs/evidence/calibration/p022-263a-design-constants.json b/docs/evidence/calibration/p022-263a-design-constants.json index 0ff316d5..1059a69f 100644 --- a/docs/evidence/calibration/p022-263a-design-constants.json +++ b/docs/evidence/calibration/p022-263a-design-constants.json @@ -1,6 +1,6 @@ { "artifact": "p022-263a-calibration-design-constants", - "bound_measurement_harness_digest": "1a26aa63fd5fbbe06e7ae72dd5e1c8f2d611bff8856af4a5b93ae36d2d23a9b1", + "bound_measurement_harness_digest": "b92f08c990fcf6d74df29aad333b330b6c3c4f9e1c1bad55efe8164c39dea57c", "bound_policy_implementation_digest": "c3068ed7fa880a7083866ead25fe8bf65c87889d242d8af1f7eee01582cd5cbf", "constants": { "G": [ diff --git a/docs/evidence/calibration/p022-263a-policy-freeze.json b/docs/evidence/calibration/p022-263a-policy-freeze.json index f3445962..f43eb6e2 100644 --- a/docs/evidence/calibration/p022-263a-policy-freeze.json +++ b/docs/evidence/calibration/p022-263a-policy-freeze.json @@ -1,6 +1,6 @@ { "artifact": "p022-263a-calibration-policy-freeze", - "measurement_harness_digest": "1a26aa63fd5fbbe06e7ae72dd5e1c8f2d611bff8856af4a5b93ae36d2d23a9b1", + "measurement_harness_digest": "b92f08c990fcf6d74df29aad333b330b6c3c4f9e1c1bad55efe8164c39dea57c", "policy_implementation_digest": "c3068ed7fa880a7083866ead25fe8bf65c87889d242d8af1f7eee01582cd5cbf", "policy_implementation_digest_framing": "sha256 over the source set ordered by the UTF-8 bytes of each repo-relative POSIX path. Each file contributes, with no header and no separator: its path byte length as an 8-byte big-endian unsigned integer, its path's exact UTF-8 bytes, its blob byte length as an 8-byte big-endian unsigned integer, and its exact git blob bytes.", "policy_source_commit": "b4f657a0abdfdfaae199cbc7eee0c47acd8b0057", diff --git a/docs/evidence/calibration/p022-263a-training-preregistration.json b/docs/evidence/calibration/p022-263a-training-preregistration.json index c2b23f61..1135a0a3 100644 --- a/docs/evidence/calibration/p022-263a-training-preregistration.json +++ b/docs/evidence/calibration/p022-263a-training-preregistration.json @@ -30,8 +30,8 @@ "anchor_commit": "eedf6d3ed44ecf7bda69fa509dcd23b45960cf76", "artifact": "p022-263a-calibration-training-preregistration", "bindings": { - "design_constants_blob_sha1": "0ff316d5aea6af92c01679babaf0f0251191dcee", - "measurement_harness_digest": "1a26aa63fd5fbbe06e7ae72dd5e1c8f2d611bff8856af4a5b93ae36d2d23a9b1", + "design_constants_blob_sha1": "1059a69fe53ff3c2286414731e6104f848596ca7", + "measurement_harness_digest": "b92f08c990fcf6d74df29aad333b330b6c3c4f9e1c1bad55efe8164c39dea57c", "policy_implementation_digest": "c3068ed7fa880a7083866ead25fe8bf65c87889d242d8af1f7eee01582cd5cbf", "training_scope_implementation_digest": "614bf9efe6ba2bb10e26a251c10d6c4a8fdaa99985d43ea03d76c6774447d25b", "training_scope_root": "scripts/training/" diff --git a/docs/generated/p022-coord-census.md b/docs/generated/p022-coord-census.md index 52110191..bfca331b 100644 --- a/docs/generated/p022-coord-census.md +++ b/docs/generated/p022-coord-census.md @@ -10,8 +10,8 @@ Value classes follow the cp1 taxonomy's axis rather than blurring it: `outside-i | measure | value | |------------------------------------|------:| -| JSON files scanned | 625 | -| coordinate slots found | 4175 | +| JSON files scanned | 709 | +| coordinate slots found | 4535 | ## By value class @@ -21,12 +21,12 @@ Value classes follow the cp1 taxonomy's axis rather than blurring it: `outside-i | `below-1` | 23 | 23 | | `bool` | 18 | 17 | | `float` | 3 | 3 | -| `in-domain` | 3480 | 2193 | +| `in-domain` | 3796 | 2424 | | `negative` | 26 | 26 | -| `null` | 259 | 9 | +| `null` | 261 | 9 | | `outside-int64` | 15 | 15 | | `string` | 19 | 19 | -| `zero` | 308 | 26 | +| `zero` | 350 | 26 | ## By family and slot @@ -162,10 +162,12 @@ Value classes follow the cp1 taxonomy's axis rather than blurring it: `outside-i | `heap_effects` | `summaries[].line` | `in-domain` | — | 56 | 10 | — | | `lowered` | `components[].subscriptions[].line` | `in-domain` | yes | 24 | 10 | — | | `lowered` | `functions[].[].column` | `in-domain` | yes | 2 | 2 | — | -| `lowered` | `functions[].[].line` | `in-domain` | yes | 903 | 112 | — | -| `lowered` | `functions[].params[].line` | `in-domain` | yes | 460 | 79 | — | +| `lowered` | `functions[].[].line` | `in-domain` | yes | 1082 | 138 | — | +| `lowered` | `functions[].params[].line` | `in-domain` | yes | 512 | 105 | — | | `lowered` | `functions[].params[].line` | `zero` | yes | 4 | 3 | — | -| `lowered` | `handles[].line` | `in-domain` | — | 343 | 56 | — | +| `lowered` | `handles[].line` | `in-domain` | — | 363 | 61 | — | +| `lowered` | `heap_effects.methods[].calls[].line` | `in-domain` | — | 25 | 17 | — | +| `lowered` | `heap_effects.methods[].line` | `in-domain` | — | 38 | 18 | — | | `lowered` | `services[].line` | `in-domain` | yes | 2 | 1 | — | | `ownir` | `components[].subscriptions[].column` | `in-domain` | yes | 2 | 1 | — | | `ownir` | `components[].subscriptions[].line` | `in-domain` | yes | 20 | 10 | — | @@ -201,7 +203,7 @@ Value classes follow the cp1 taxonomy's axis rather than blurring it: `outside-i | `repro` | `traces[].layers[].steps[].value.params[].line` | `in-domain` | — | 4 | 1 | — | | `summaries` | `functions[].[].line` | `in-domain` | yes | 37 | 9 | — | | `summaries` | `functions[].params[].line` | `in-domain` | yes | 25 | 8 | — | -| `summaries` | `summaries[].line` | `zero` | — | 252 | 63 | — | +| `summaries` | `summaries[].line` | `zero` | — | 294 | 84 | — | | `verdict_renders` | `components[].subscriptions[].column` | `in-domain` | yes | 1 | 1 | — | | `verdict_renders` | `components[].subscriptions[].line` | `in-domain` | yes | 11 | 5 | — | | `verdict_renders` | `functions[].[].line` | `in-domain` | yes | 3 | 2 | — | @@ -220,8 +222,8 @@ Value classes follow the cp1 taxonomy's axis rather than blurring it: `outside-i | `verdicts` | `effects[].line` | `negative` | yes | 1 | 1 | `-3` | | `verdicts` | `effects[].line` | `zero` | yes | 1 | 1 | — | | `verdicts` | `findings[].column` | `in-domain` | — | 17 | 7 | — | -| `verdicts` | `findings[].column` | `null` | — | 198 | 93 | — | -| `verdicts` | `findings[].line` | `in-domain` | — | 200 | 89 | — | +| `verdicts` | `findings[].column` | `null` | — | 200 | 95 | — | +| `verdicts` | `findings[].line` | `in-domain` | — | 202 | 91 | — | | `verdicts` | `findings[].line` | `zero` | — | 15 | 12 | — | | `verdicts` | `functions[].[].column` | `below-1` | yes | 1 | 1 | `0` | | `verdicts` | `functions[].[].column` | `in-domain` | yes | 7 | 2 | — | diff --git a/docs/generated/p022-cp4-census.md b/docs/generated/p022-cp4-census.md index 84c7650a..2c04e30b 100644 --- a/docs/generated/p022-cp4-census.md +++ b/docs/generated/p022-cp4-census.md @@ -8,18 +8,18 @@ Computed by `tests/verdict_census.py` and `tests/verdict_render_census.py` (the | measure | value | |-------------------------------------------------------------------------|------:| -| goldens — Python's complete truth, one per planned case | 133 | +| goldens — Python's complete truth, one per planned case | 154 | | … swept from `tests/fixtures/ownir` | 22 | -| … swept from `tests/fixtures/lowered` | 64 | +| … swept from `tests/fixtures/lowered` | 85 | | … swept from `tests/fixtures/summaries` | 9 | | … synthetic controls (`manifest.json` cases) | 38 | -| reference refusals over all goldens | 9 | -| reference findings over all goldens | 215 | +| reference refusals over all goldens | 25 | +| reference findings over all goldens | 217 | | declared Rust exclusions — the executable ledger `rust_replay_excluded` | 2 | | … refused at the typed `OwnIr` door (#294 OD-1) | 2 | -| replayed by Rust (goldens minus exclusions) | 131 | -| … reference refusals among them (compared in full) | 9 | -| … findings among them (compared on every `Finding` member) | 213 | +| replayed by Rust (goldens minus exclusions) | 152 | +| … reference refusals among them (compared in full) | 25 | +| … findings among them (compared on every `Finding` member) | 215 | The differential counts over the replayed set — Python-only, Rust-only, changed, ordering-only, unexplained — are asserted, not measured here: the Rust replay compares every replayed case's full ordered verdict list (or its refusal text) against the golden on every member, collects every divergence without fail-fast, and fails if one exists. A green `cargo test -p own-bridge --test verdicts` is 0 / 0 / 0 / 0 / 0 by construction; a non-zero count is a red build. diff --git a/docs/generated/p022-cp5-inventory.md b/docs/generated/p022-cp5-inventory.md index d33b498c..b0684300 100644 --- a/docs/generated/p022-cp5-inventory.md +++ b/docs/generated/p022-cp5-inventory.md @@ -26,7 +26,7 @@ Checkpoint 4 proved identity, anchor, kind and tiering over the replayed set ([c | `flowlocal_own008` | bridge | flow-local release while borrowed | 1 | 1 | | `flowlocal_own011` | bridge | flow-local exclusive re-borrow | 4 | 4 | | `flowlocal_own012` | bridge | flow-local shared borrow under an exclusive one | 2 | 2 | -| `flowlocal_own013` | bridge | flow-local direct use under an exclusive borrow | 5 | 5 | +| `flowlocal_own013` | bridge | flow-local direct use under an exclusive borrow | 7 | 7 | | `flowlocal_own005_pool` | bridge | flow-local use after move on a pooled buffer | 1 | 1 | | `flowlocal_own007_pool` | bridge | flow-local consume/return while borrowed on a pooled buffer | 1 | 1 | | `flowlocal_own008_pool` | bridge | flow-local release while borrowed on a pooled buffer | 1 | 1 | diff --git a/docs/generated/p022-shadow-census.md b/docs/generated/p022-shadow-census.md index a13b64ef..b02d884f 100644 --- a/docs/generated/p022-shadow-census.md +++ b/docs/generated/p022-shadow-census.md @@ -24,12 +24,12 @@ acceptance work. | corpus | documents | |---|---| -| `tests/fixtures/lowered` | 64 | +| `tests/fixtures/lowered` | 85 | | `tests/fixtures/ownir` | 22 | | `tests/fixtures/repro` | 3 | | `tests/fixtures/summaries` | 9 | | `tests/fixtures/verdicts` | 38 | -| **total** | **136** | +| **total** | **157** | Every one of those documents is canonicalized and hashed by the reference (`ownlang/repro.py`) and re-hashed from the same file by the port @@ -43,8 +43,8 @@ refuses to carry a foreign entry that has none rather than filling one in. | surface | count | |---|---| -| documents captured and digest-pinned | 136 | -| tamper controls (one changed character per document, refusal required) | 136 | +| documents captured and digest-pinned | 157 | +| tamper controls (one changed character per document, refusal required) | 157 | | documents both engines must REFUSE to name (`domain_refusals`) | 6 | | reproduction artifacts committed and replayed byte-for-byte | 10 | | structural negative controls on `verify` (each side) | 34 | diff --git a/docs/notes/h1-proven-call.md b/docs/notes/h1-proven-call.md new file mode 100644 index 00000000..d870bdb5 --- /dev/null +++ b/docs/notes/h1-proven-call.md @@ -0,0 +1,112 @@ +# H1 — proven calls in a state-protocol region (OwnIR v2) + +Status: **landed** (owner ruling: OwnIR v2 and T0 Amendment 2 approved for H1). +Base: `main` = `1c70e867eb408d931ae3dfffd8c0b351190f6547`. Follows +[`h1-transport-stop.md`](h1-transport-stop.md), which found that the only +fail-loud transport is a version bump, and [`heap-effect-summaries.md`](heap-effect-summaries.md) +(H0), whose summaries this slice consumes. + +## What changes for a C# user + +```csharp +static int Twice(int x) => x * 2; + +Protocol.WithApproved(order, approved => +{ + var n = Twice(21); // before H1: refused. Now: admitted, clean. + approved.Ship(); +}); +``` + +| Call inside a region | Before H1 | With H1 | +|---|---|---| +| direct call, touches no entity or token, proven harmless | refusal (extractor) | **admitted** | +| same, but not proven harmless (a write, an escape, a global, Unknown anywhere) | refusal (extractor) | refusal (**core**, exit 2), naming the clause | +| a call handed the borrowed entity (`Mutates(order)`) | `use` → verdict | unchanged | +| an external, virtual, delegate or local-function call (`Console.WriteLine`) | refusal (extractor) | unchanged, same text | + +## The transport + +- **`proven_call`** (`site`, `callee`, `line`): a new flow op, so `OWNIR_VERSION` 1 → 2 (spec/OwnIR.md §2, §5.4). +- **`heap_effects`:** a top-level section holding the H0 source facts. It holds one record per call site (the call expression walked like a body, every variable from outside it read as `heap`) and the records of the methods those sites reach through `direct` edges. +- **The frontend decides nothing.** It emits a `proven_call` only for a call the summary layer could prove at all, meaning a call whose H0 dispatch is `direct`. The same shared classifier (`HeapEffectFacts.Dispatch`) produces both that decision and every H0 call fact. +- **Fail-loud.** A v1 core refuses a v2 document on the stamp (IR1). With the stamp stripped it refuses on the unknown op (IR4). C1 below runs the real v1 core to show both. +- **No compatibility shim** in either direction: a v2 core refuses v1 facts. + +## The decision + +The decision is made in the core and only there: `_admit_proven_calls` in `ownlang/ownir.py`, ported in `own-bridge/src/proven.rs`. + +1. **When:** at the head of `to_module` / `lower_full`, before any function is lowered. The pass walks every function body through `then`/`else`/`body`, so no lowering path can carry a `proven_call` past it. +2. **The predicate:** `heap_effects.site_verdict` / `harmless`. It lives in the shared summary layer, not in typestate code. +3. **Strict on purpose:** a reference returned without an alias is still refused (`returns == []`). Unknown fails every clause it reaches. + +Predicate v1. A site is admitted iff all of these hold: + +- the site record exists and calls `callee` directly; +- every call in the site is `direct` to a summarized method, and each such method is harmless; +- the site's own solved summary is harmless. + +A summary is harmless iff: + +- every parameter and the receiver are at most `borrow`; +- `writes.instance`, `writes.static` and `writes.indirect` are all `none`; +- `returns` is `[]`. + +Refusals are `OwnIRError`, with identical text in both engines, in this order (spec/Bridge.md BR-L14): + +1. a malformed `site` or `callee`; +2. a `proven_call` outside a region; +3. no `heap_effects` section; +4. a malformed section; +5. no site record; +6. a site that is not proven harmless. + +## Evidence + +**Kill fixtures.** Real C# files in `frontend/roslyn/protocol-samples/cases/H1*.cs`; the facts are committed as `typestate_cs_h1*`. + +| Case | Result | +|---|---| +| `Twice(21)` | admitted, clean | +| A → B → pure | admitted, clean | +| pure SCC (`Even` ⇄ `Odd`) | admitted, clean | +| `TouchesGlobalState()` | refused: `writes.static is may` | +| A → B → global | refused: `writes.static is may` | +| polluted SCC (`Ping` ⇄ `Pong` writes) | refused: `writes.static is may` | +| A → `Console.WriteLine` | refused: `writes.instance is unknown` | +| `Fill(buffer)`, outer array | refused: `parameter 0 is borrow_mut` | +| `Mutates(order)` / `Escapes(order)` | OWN013, as before H1 | +| R9 backdoor (`Backdoor.AnnotateLast()`) | refused, by the core now: `writes.instance is may` | +| R18 `Console.WriteLine`, R19 interface call | refused by the extractor, unchanged | + +**Compatibility controls** (`tests/test_proven_call.py`): + +- **C1, old core on new facts.** `ownlang/` at `1c70e867` is taken out of git history and run on the extractor's v2 facts. It exits 2 on `schema v2, but this core understands v1`. With the stamp stripped it exits 2 on `unknown OwnIR flow op 'proven_call'`. +- **C2/C3, missing or malformed evidence.** Eleven documents, each derived from the real H1a facts by one corruption, are refused. The Layer 2 goldens pin each text, and Rust replays them byte for byte. The corruptions: + - no section; + - no site record; + - `site` is not a string; + - empty `callee`; + - the op outside the region; + - a malformed section; + - the wrong callee; + - no callee record; + - an Unknown callee; + - an Unknown site; + - a virtual call inside the site. +- **C4, Unknown is poison.** A predicate that reads Unknown as harmless admits the transitive-Unknown fixture and both Unknown-derived documents. The real predicate refuses all three, so the pinned refusals go red under the mutant. The same mutant in the Rust port turns the Layer 2 replay red. +- **C5, the op cannot be dropped.** Dropping the admission pass, or dropping the op from the facts, turns the four refused kill fixtures clean. Both differ from the pinned ledgers. The Rust mutant with no `admit` call is caught by the replay. + +**Parity.** +- The protocol gate's 29 C#-derived documents are byte-identical on both public CLIs. +- The Layer 2, summaries, verdict, CLI, repro and validation ledgers are regenerated at v2 by their own writers and replayed by Rust. +- The H0 sidecar goldens are unchanged. + +## Not in this slice + +- logger, BCL or annotation summaries: `Console.WriteLine` stays refused; +- devirtualization; +- property getters, constructors and operators inside a region: still refused by the extractor; +- typed write targets, which would be needed to admit a write to state that is provably not the entity's type family; +- DB-side mutation gaps. diff --git a/docs/notes/h1-transport-stop.md b/docs/notes/h1-transport-stop.md new file mode 100644 index 00000000..f6686520 --- /dev/null +++ b/docs/notes/h1-transport-stop.md @@ -0,0 +1,107 @@ +# H1 — harmless calls in a protocol region: STOPPED at the transport + +Status: **RESOLVED.** The owner approved OwnIR v2 and T0 Amendment 2 for H1; H1 +landed as [`h1-proven-call.md`](h1-proven-call.md). Kept as the record of why the +version had to move. (Original status: STOP: needs an owner ruling.) +Base: `main` = `1c70e867eb408d931ae3dfffd8c0b351190f6547`, the H0 landing point +([`heap-effect-summaries.md`](heap-effect-summaries.md)). + +H1 would let a provably harmless direct source call stand inside a +`[ProtocolRegion]` instead of being refused. The kill-first question was whether +a fail-loud transport for that decision exists inside the current contracts. +**It does not.** The only compliant transport bumps `OWNIR_VERSION`, and a bump +moves the frozen T0 harness identity, which only an owner amendment may do. + +## 1. Why the decision needs a must-understand transport + +- `ProtocolLowering` refuses in the extractor, before any fact exists. +- The H0 summary is solved in the core. +- The frontend may not solve summaries (IR6, and the rule that frontends emit facts only). + +So the facts must carry an **obligation**: "this call is admitted only if the core proves `Harmless(...)`". A core that does not understand the obligation must not read it as clean. + +## 2. Every fail-loud mechanism in OwnIR v1 is a version bump + +| Candidate transport | Old core (v1) reads it as | Verdict | +|---|---|---| +| Optional field on `call` (`requires: harmless`) | a call to an extern with no tracked argument, i.e. **nothing**, i.e. clean | **fail-open**: rejected | +| Omit the admitted call from facts and put the obligation in a separate file or section | a valid v1 document without the call, i.e. clean | **fail-open**: rejected | +| Extractor calls the core solver before writing facts | n/a | frontend depends on and decides with the core at runtime: an architectural decision no spec makes; **STOP** condition | +| New flow op without a bump | `OwnIRError` (IR4: unknown op) | fail-loud, but violates IR3 ("add a flow op ⇒ bump"); a contract violation is not a transport | +| New resource kind without a bump | `OwnIRError` at load | same: IR3 requires a bump | +| **New flow op + `OWNIR_VERSION` 1 → 2** | `OwnIRError` twice: IR1 (version) and IR4 (op) | **the only compliant fail-loud transport** | + +This is by design, not an accident: in OwnIR, "an old core fails loud" and "the vocabulary changed" are the same event (spec/OwnIR.md §2, IR1–IR4). No mandatory-capability or feature-gating mechanism exists. `fix_candidates_version` and the H0 `heap_effects_version` are additive and are ignored by the core. + +## 3. Why the bump is not this change's to make + +`scripts/perf_baseline.py`'s `facts` calibration generator stamps `"ownir_version": 1`. Under a v2 core: + +1. **The literal must move,** or `perf-calibration-facts-current` goes red: the generator would write facts both engines refuse. This is exactly the defect Amendment 1 found. +2. **Moving it moves the T0 harness identity** (`measurement_harness_digest`, currently `1a26aa63fd5f…`), because `perf_baseline.py` is in the harness source set. +3. **The P-022 merge gate** (`scripts/step7/mergegate.py`, `p022-merge-gate.yml`) recomputes the live digest of the merged commit and requires it to equal the one T0-1 names, so the PR cannot merge green. +4. **T0 rules it out unilaterally.** "the next move is a new amendment or it is a defect" (`p022-263-t0-protocol-freeze.md`, Amendment 1). The owner also "ruled out a compatibility shim on either side", so a v2 core that still accepts v1 is not an option either. + +The P-022 freeze on verdict-changing inference itself is **not** the blocker: it lifted at the Stage 3 cutover (`P-022-rust-core-migration.md`, "With the cutover complete the P-022 feature freeze on verdict-changing inference lifts"). The blocker is the T0 harness binding that a version bump drags along. + +**Precedent:** Amendment 1 is this exact situation (0 → 1 for `borrow_mut`/`move`), and the owner resolved it with one literal plus a re-binding of steps 4, 5 and 6. + +## 4. What the owner is asked to rule + +**Amendment 2: `OWNIR_VERSION` 1 → 2 for the `proven_call` op.** Mirroring Amendment 1: + +| Item | What moves | +|---|---| +| Instrument | one literal in `perf_baseline.py`'s `facts` generator, `1` → `2`; nothing else in the harness source set | +| Re-bound | T0 steps 4, 5, 6 (with `design_constants_blob_sha1`), to the new harness identity | +| Re-run | the instrumentation controls Amendment 1 re-ran | +| Unchanged | rules, budgets, populations, statistic, roll-ups, host predicate, retry budget | +| Not rewritten | committed evidence of past runs | + +**Mechanical churn of the bump itself:** three producer stamps (`ownlang/ownir.py`, `own-ir/src/lib.rs`, `Program.cs`) and 244 committed JSON fixtures carrying `"ownir_version": 1`: + +| Fixture family | Files | +|---|---:| +| summaries | 82 | +| lowered | 64 | +| verdicts | 38 | +| ownir | 22 | +| repro | 19 | +| verdict_renders | 9 | +| cli_ownir | 4 | +| `corpus/ownership-lab/h29` | 4 | +| others | 2 | + +All of them are regenerated by their own `--write` tooling, never by hand. + +## 5. H1 as it would be built once ruled (design, ready) + +- **Extractor (`ProtocolLowering`).** Only one site changes: an invocation inside a region that touches no entity and no token. Today it reaches `OpaqueCode` and is refused. + - If its dispatch is `direct`, decided by the **same classifier H0 uses** (shared, not copied), it lowers to `{"op": "proven_call", "site": , "line": n}`. + - Every other call is refused exactly as today, with the same text: extern, virtual, delegate, local function, constructors, getters, operators. + - An entity-touching call keeps today's `use` + core verdict. +- **Site evidence.** Each site is a synthetic H0 record walked by the H0 producer over the call expression alone. Outer variables (the enclosing method's locals and parameters, the token) read as `heap`, so any mutation through them is a heap write, never silence. +- **Section.** The facts carry a `heap_effects` section (H0 vocabulary v1): the site records plus the records reachable from them by `direct` edges. Selecting the records is closure only, not solving; a missing record solves to Unknown. +- **Core (Python reference + Rust port, byte-parity).** + - The section is required whenever a `proven_call` exists. Its absence, a missing site record, or a malformed section is an `OwnIRError` (refusal, exit 2). + - The H0 solver solves the section. Each site is admitted iff its solved summary satisfies the predicate below; otherwise `OwnIRError` naming the site. + - An admitted `proven_call` lowers to nothing: it touches no tracked resource. +- **Predicate v1 (strict)** on the site summary, and so transitively on the callee: + - no Unknown anywhere; + - every parameter and the receiver at most `borrow`; + - `writes.instance`, `writes.static` and `writes.indirect` all `none`; + - `returns` is `[]` (inert, or no alias to a parameter, the receiver or the heap). +- **Negative controls.** + - A v1 core on v2 facts gives `OwnIRError`, on both engines. + - A v2 core with the section removed gives `OwnIRError`. + - A v2 core with a site record removed gives `OwnIRError`. + - A mutant that reads Unknown as harmless must turn the suite red. + - Python and Rust refusal texts are identical. +- **Kill fixtures.** + - `Twice` is admitted. + - `Mutates(order)` and `Escapes(order)` touch the entity, so they keep `use` + verdict. + - `TouchesGlobalState()`: refusal (static write). + - `Console.WriteLine`: refusal in the extractor, unchanged text. + - A → B pure: admitted. A → B mutating, escaping or global: refusal. + - A pure SCC is admitted; an SCC with mutation, escape or Unknown is refused as a whole. +- **Regression.** Protocol documents without a harmless call change only their version stamp. Their verdicts are unchanged on both CLIs. diff --git a/docs/notes/heap-effect-summaries.md b/docs/notes/heap-effect-summaries.md index 9f3af5a9..5fa6f709 100644 --- a/docs/notes/heap-effect-summaries.md +++ b/docs/notes/heap-effect-summaries.md @@ -98,7 +98,7 @@ Receiver mapping, local aliases, a reassigned parameter, array elements, return **The core:** no verdict-path module changed. The only edit to existing Rust code is the visibility of `dump.rs::emit` (private → `pub(crate)`). The existing suites (`tests/run_tests.py`, `cargo test`) pass unchanged. The coordinate census (`docs/generated/p022-coord-census.md`) is regenerated only because it now also counts the new fixture family's `line` slots. -## 7. What H1 still needs before `ProtocolLowering` can ask `Harmless(callee, region-resource)` +## 7. What H1 still needed (landed: [`h1-proven-call.md`](h1-proven-call.md), OwnIR v2) 1. **The decision point: an owner ruling.** `ProtocolLowering` refuses in the extractor, before any fact exists, while the summary is solved in the core. Moving the decision core-side needs a must-understand construct for "a call inside this region whose effect must be proven", which is an OwnIR v2 op (IR3/IR4), plus the sidecar travelling with the facts it describes. Solving in the extractor is not an option: frontends emit facts only (IR6). 2. **The predicate**, over a solved summary of a `direct` callee: diff --git a/docs/notes/p022-263-t0-protocol-freeze.md b/docs/notes/p022-263-t0-protocol-freeze.md index 9b79fbe8..0f255cb6 100644 --- a/docs/notes/p022-263-t0-protocol-freeze.md +++ b/docs/notes/p022-263-t0-protocol-freeze.md @@ -34,6 +34,13 @@ Status: instrument's generated facts moved to OwnIR v1, and steps 4, 5 and 6 were re-bound to it. The freeze and the authorisation above are unchanged, and so is every rule, budget, population and predicate below. + + AMENDMENT 2 (2026-10-03) is the next such state, on the same principle: + the accepted harness identity moved 1a26aa63fd5f -> b92f08c990fc when the + instrument's generated facts moved to OwnIR v2 (the `proven_call` transport + of H1), and steps 4, 5 and 6 were re-bound to it. The freeze and the + authorisation above are unchanged, and so is every rule, budget, population + and predicate below. ``` **What this is.** The contract that fixes *how numbers will be judged*, before any @@ -170,13 +177,14 @@ Doing so edits `scripts/perf_baseline.py`, which is one of the two files in the harness source set, so it moves the harness identity measurement_harness_digest - 1a26aa63fd5fbbe06e7ae72dd5e1c8f2d611bff8856af4a5b93ae36d2d23a9b1 - -to which steps 4, 5 and 6 are bound. The identity has moved twice, each time by -a recorded act and never as a side effect: steps 4, 5 and 6 were **re-bound** -after the S8 memory-semantics repair (`562a7f7232da` → `104c384d01bf`), and -re-bound again by Amendment 1, when the instrument's generated facts moved to -OwnIR v1 (`104c384d01bf` → `1a26aa63fd5f`). + b92f08c990fcf6d74df29aad333b330b6c3c4f9e1c1bad55efe8164c39dea57c + +to which steps 4, 5 and 6 are bound. The identity has moved three times, each +time by a recorded act and never as a side effect: steps 4, 5 and 6 were +**re-bound** after the S8 memory-semantics repair (`562a7f7232da` → +`104c384d01bf`), re-bound again by Amendment 1, when the instrument's generated +facts moved to OwnIR v1 (`104c384d01bf` → `1a26aa63fd5f`), and re-bound a third +time by Amendment 2, when they moved to OwnIR v2 (`1a26aa63fd5f` → `b92f08c990fc`). Moving it again is a new instrument and a re-evaluation of accepted instrumentation evidence, not a T0 detail. @@ -1326,3 +1334,64 @@ qualification, an exact execution binding, the campaign link and the session preflight are still required, and each may still refuse. It changes no number a verdict is computed from. And it is not a precedent for moving the identity as a side effect: the next move is a new amendment or it is a defect. + +### Amendment 2 — the harness identity follows OwnIR v2 (2026-10-03) + +```text +Status after this amendment: + FROZEN, collection_authorized: true unchanged + accepted harness identity 1a26aa63fd5f -> b92f08c990fc + rules, budgets, populations, statistic, + roll-ups, host predicate, retry budget unchanged, every one of them +``` + +**The owner's ruling.** H1 connects state protocols to the interprocedural +heap-effect summaries through a must-understand flow op, `proven_call`, so that +an older core cannot read an unproven call as clean. A new flow op is a +vocabulary change, so `OWNIR_VERSION` moved 1 → 2 +([OwnIR.md §2, §5.4](../../spec/OwnIR.md), [H1](h1-proven-call.md)). The owner +approved the version move and this amendment for exactly that reason, on the +Amendment 1 principle — a minimal re-binding forced by the version literal — and +for nothing else: no other change to T0, its budgets, populations, predicates or +measurement semantics is authorised by it. As in Amendment 1, a compatibility +shim on either side (a v2 core that also accepts v1) is ruled out. + +**What changed in the instrument.** One literal in the `facts` generator of +`scripts/perf_baseline.py`: `"ownir_version": 1` became `"ownir_version": 2`. +Nothing else in the harness source set moved: the workload manifest, the rung +ladder, the clock, the memory accounting, the identity gate and +`HARNESS_VERSION` are byte-for-byte what they were. This is a schema-transport +change carried by the generated calibration documents, not a change to the +measurement experiment: the generated `facts` workloads have the same shape and +scale and do the same work, and the `refused` workload is refused at the same +door. + + harness identity before 1a26aa63fd5fbbe06e7ae72dd5e1c8f2d611bff8856af4a5b93ae36d2d23a9b1 + harness identity after b92f08c990fcf6d74df29aad333b330b6c3c4f9e1c1bad55efe8164c39dea57c + +**What was re-bound**, in the order the chain runs: the policy freeze (step 4), +the ratified design constants (step 5), and the training preregistration's +bindings (step 6) — and with the last, `design_constants_blob_sha1` +(`0ff316d5aea6` → `1059a69fe53f`), which moved because the design-constants +artifact itself was re-bound. T0-1 above names the new identity; the merge gate +reads it there and recomputes it from the instrument sources of the tree being +merged. With the literal moved and nothing re-bound, the gate refused +(`instrument_matches_t0`: the instrument hashed to `b92f08c990fc`, T0 named +`1a26aa63fd5f`); after the re-binding it allows. + +**What was not touched.** The committed evidence of runs that actually +happened, for the same reason as in Amendment 1. No T0-governed clock has run +under any identity, so there is no training or decisive observation for this +amendment to re-evaluate, keep or discard. + +**The re-evaluation T0-1 says a moved identity owes.** The instrumentation +controls were re-run on the amended tree, all of them as part of +`tests/run_tests.py`, and all hold; `perf-calibration-facts-current` — the +control Amendment 1 added for exactly this defect — was red between the version +move and the instrument literal (the reference refused the generator's v1 +documents at the door) and holds after it. + +**What this amendment does not do.** It authorises nothing new and changes no +number a verdict is computed from. FROZEN and `collection_authorized` stay as +they were. It is not a precedent for moving the identity as a side effect: the +next move is a new amendment or it is a defect. diff --git a/docs/notes/p022-263a-instrument.md b/docs/notes/p022-263a-instrument.md index 627dd2fd..eb76be51 100644 --- a/docs/notes/p022-263a-instrument.md +++ b/docs/notes/p022-263a-instrument.md @@ -276,6 +276,12 @@ caught it is `perf-calibration-facts-current`: it runs the reference on the generator's output and requires the `facts` workloads to be analysed and the `refused` one to be refused. +It moved a third time, from `1a26aa63fd5f` to `b92f08c990fc`, when OwnIR's +vocabulary moved to v2 for H1's must-understand `proven_call`: the same literal, +`1` → `2`, the same re-binding of steps 4, 5 and 6, recorded as the frozen T0's +Amendment 2. `perf-calibration-facts-current` named the defect between the core's +version move and the instrument's, exactly as it was added to. + On POSIX the same `wait4` call also carries the child's CPU split, fault counts and context-switch counts. Those are now kept rather than discarded — see *The interval kept its meaning and gave up its secrets* — under the same rule: off diff --git a/frontend/ownts/ownts.py b/frontend/ownts/ownts.py index 06ee6b70..0a32f841 100644 --- a/frontend/ownts/ownts.py +++ b/frontend/ownts/ownts.py @@ -577,7 +577,7 @@ def extract(path: str) -> list[Component]: def to_ownir(comps: list[Component], module: str, effects: list[dict] | None = None) -> dict: facts = { - "ownir_version": 1, + "ownir_version": 2, "module": module, "components": [ { diff --git a/frontend/roslyn/OwnSharp.Extractor/HeapEffectFacts.cs b/frontend/roslyn/OwnSharp.Extractor/HeapEffectFacts.cs index b7f6beed..7eeb9ff8 100644 --- a/frontend/roslyn/OwnSharp.Extractor/HeapEffectFacts.cs +++ b/frontend/roslyn/OwnSharp.Extractor/HeapEffectFacts.cs @@ -37,7 +37,16 @@ internal static string Key(IMethodSymbol method) => (method.ReducedFrom ?? method).OriginalDefinition.ToDisplayString(KeyFormat); public static Dictionary Extract(Compilation compilation, - IReadOnlyList<(string file, SyntaxTree tree)> parsed) + IReadOnlyList<(string file, SyntaxTree tree)> parsed) => + new() + { + ["heap_effects_version"] = Version, + ["methods"] = Methods(compilation, parsed).Values.ToList(), + }; + + /// Every source method's record, by key. + private static SortedDictionary> Methods( + Compilation compilation, IReadOnlyList<(string file, SyntaxTree tree)> parsed) { var methods = new SortedDictionary>(StringComparer.Ordinal); foreach (var (file, tree) in parsed) @@ -74,13 +83,96 @@ internal static string Key(IMethodSymbol method) => methods[key] = new Walk(compilation, symbol, file, node).Run(body); } } + return methods; + } + + // ---- OwnIR v2 `proven_call` (H1, docs/notes/h1-proven-call.md) ---------------------- + // + // A call inside a protocol region that touches no entity and no token is lowered as a + // `proven_call` instead of being refused, IF it could be proven harmless at all: its + // dispatch is `direct` — the same classification every H0 call fact carries. The proof + // is the core's. What the frontend adds is FACTS: one record for the call site itself + // (the call expression walked like a body, every variable from outside it read as + // `heap`) and the records of the methods it reaches through `direct` edges. + + /// The identity of one call site: unique in a scan, and never a method key. + internal static string SiteKey(string file, SyntaxNode node) + { + var p = node.GetLocation().GetLineSpan().StartLinePosition; + return $"site:{file}:{p.Line + 1}:{p.Character + 1}"; + } + + /// Whether a call could be proven harmless at all: an ordinary method, bound, and + /// dispatched `direct`. Anything else is Unknown to the summary layer by construction. + internal static bool Provable(SemanticModel model, InvocationExpressionSyntax inv) + { + if (model.GetOperation(inv) is not IInvocationOperation op) + return false; + var method = op.TargetMethod; + if (method.MethodKind is not (MethodKind.Ordinary or MethodKind.ReducedExtension)) + return false; + var nonVirtual = !op.IsVirtual || op.Instance?.Syntax is BaseExpressionSyntax; + return Dispatch(method, nonVirtual) == "direct"; + } + + /// The `heap_effects` section of an OwnIR v2 document: the site records, and every + /// method record reachable from them through `direct` call edges. A selection, not a + /// solve: a record left out is a callee with no summary, which the core reads as + /// Unknown. + internal static Dictionary Section( + Compilation compilation, IReadOnlyList<(string file, SyntaxTree tree)> parsed, + IReadOnlyList<(string Key, string File, InvocationExpressionSyntax Call)> sites) + { + var all = Methods(compilation, parsed); + var chosen = new SortedDictionary>(StringComparer.Ordinal); + var work = new Queue>(); + foreach (var (key, file, call) in sites) + { + if (chosen.ContainsKey(key)) + continue; + var model = compilation.GetSemanticModel(call.SyntaxTree); + var op = model.GetOperation(call); + if (op is null) + continue; // no record: the core refuses the site for want of evidence + var record = new Walk(compilation, file, call, op).RunSite(key, op); + chosen[key] = record; + work.Enqueue(record); + } + while (work.Count > 0) + { + var record = work.Dequeue(); + foreach (var call in (List>)record["calls"]!) + { + if ((string?)call["dispatch"] != "direct" || call["callee"] is not string callee + || chosen.ContainsKey(callee) || !all.TryGetValue(callee, out var next)) + continue; + chosen[callee] = next; + work.Enqueue(next); + } + } return new Dictionary { ["heap_effects_version"] = Version, - ["methods"] = methods.Values.ToList(), + ["methods"] = chosen.Values.ToList(), }; } + /// The dispatch of a call: `delegate`, `virtual`, `extern` (no source), or `direct`. + internal static string Dispatch(IMethodSymbol method, bool nonVirtual) + { + if (method.MethodKind == MethodKind.DelegateInvoke) + return "delegate"; + if (!nonVirtual && (method.IsVirtual || method.IsAbstract || method.IsOverride + || method.ContainingType.TypeKind == TypeKind.Interface) + && !(method.IsSealed || method.ContainingType.IsSealed || method.ContainingType.IsValueType)) + return "virtual"; + if (method.ContainingType.TypeKind == TypeKind.Interface) + return "virtual"; // a static abstract member: resolved by a type argument + if (method.OriginalDefinition.DeclaringSyntaxReferences.IsEmpty) + return "extern"; + return "direct"; + } + /// A value of this type carries no reference: copying it shares nothing with the caller. internal static bool Inert(ITypeSymbol? type) => type is not null @@ -101,7 +193,10 @@ or SpecialType.System_Single or SpecialType.System_Double private sealed class Walk { private readonly Compilation _compilation; - private readonly IMethodSymbol _method; + private readonly IMethodSymbol? _method; + // site mode: the one call expression being walked; everything declared outside it is + // somebody else's variable and reads as `heap` + private readonly SyntaxNode? _site; private readonly string _file; private readonly SyntaxNode _decl; private readonly bool _returnInert; @@ -128,6 +223,27 @@ public Walk(Compilation compilation, IMethodSymbol method, string file, SyntaxNo _returnInert = method.ReturnsVoid || Inert(method.ReturnType); } + /// Site mode: one call expression, walked as if it were a body of its own. + public Walk(Compilation compilation, string file, SyntaxNode site, IOperation op) + { + _compilation = compilation; + _method = null; + _site = site; + _file = file; + _decl = site; + _returnInert = op.Type is null || op.Type.SpecialType == SpecialType.System_Void || Inert(op.Type); + } + + /// The record of one call site: no parameters, no receiver; what the call + /// expression returns, if anything, is its `returns`. + public Dictionary RunSite(string key, IOperation op) + { + var value = Eval(op); + if (!_returnInert) + _returns.UnionWith(value); + return Record(key, receiver: false, Array.Empty()); + } + private static SortedSet None() => new(StringComparer.Ordinal); private static SortedSet One(string token) => new(StringComparer.Ordinal) { token }; @@ -136,13 +252,14 @@ public Walk(Compilation compilation, IMethodSymbol method, string file, SyntaxNo public Dictionary Run(IOperation body) { - if (_method.IsAsync) + var method = _method!; + if (method.IsAsync) Unknown("async method"); - if (_method.ReturnsByRef || _method.ReturnsByRefReadonly) + if (method.ReturnsByRef || method.ReturnsByRefReadonly) Unknown("ref return"); - if (_method.MethodKind == MethodKind.Constructor && HasInstanceInitializers(_method.ContainingType)) - Unknown($"instance initializers of {_method.ContainingType.ToDisplayString()}"); - foreach (var p in _method.Parameters) + if (method.MethodKind == MethodKind.Constructor && HasInstanceInitializers(method.ContainingType)) + Unknown($"instance initializers of {method.ContainingType.ToDisplayString()}"); + foreach (var p in method.Parameters) if (!Inert(p.Type) || p.RefKind is RefKind.Ref or RefKind.Out) if (IsReassigned(body, p) && p.RefKind is RefKind.None or RefKind.In) { @@ -151,16 +268,21 @@ public Walk(Compilation compilation, IMethodSymbol method, string file, SyntaxNo _reassigned[p] = slot; } Exec(body); + return Record(Key(method), receiver: !method.IsStatic, method.Parameters); + } + private Dictionary Record(string key, bool receiver, + IEnumerable parameters) + { var line = _decl.GetLocation().GetLineSpan().StartLinePosition.Line + 1; return new Dictionary { - ["key"] = Key(_method), + ["key"] = key, ["file"] = _file, ["line"] = line, - ["receiver"] = !_method.IsStatic, + ["receiver"] = receiver, ["return_inert"] = _returnInert, - ["params"] = _method.Parameters.Select(p => new Dictionary + ["params"] = parameters.Select(p => new Dictionary { ["index"] = p.Ordinal, ["name"] = p.Name, @@ -184,7 +306,13 @@ public Walk(Compilation compilation, IMethodSymbol method, string file, SyntaxNo /// A parameter of the method being read (not one a member captured from elsewhere). private bool Own(IParameterSymbol p) => - SymbolEqualityComparer.Default.Equals(p.ContainingSymbol, _method); + _method is not null && SymbolEqualityComparer.Default.Equals(p.ContainingSymbol, _method); + + /// Site mode: a local declared outside the call expression belongs to the code + /// around it (the region's lambda, the enclosing method). + private bool Outer(ILocalSymbol local) => + _site is not null && !local.DeclaringSyntaxReferences.Any(r => + r.SyntaxTree == _site.SyntaxTree && _site.Span.Contains(r.Span)); private static bool IsReassigned(IOperation body, IParameterSymbol p) => body.Descendants().Any(op => op switch @@ -476,6 +604,8 @@ private SortedSet Value(IOperation op) case ISizeOfOperation: case IDiscardOperation: return None(); + case IParameterReferenceOperation when _site is not null: + return One("heap"); // site mode: a variable of the code around the call case IParameterReferenceOperation p when !Own(p.Parameter): // a primary-constructor parameter captured by a member: hidden state Unknown("captured primary-constructor parameter"); @@ -485,7 +615,7 @@ private SortedSet Value(IOperation op) return One($"local:{slot}"); return One($"param:{p.Parameter.Ordinal}"); case IInstanceReferenceOperation { ReferenceKind: InstanceReferenceKind.ContainingTypeInstance }: - return One("receiver"); + return One(_site is not null ? "heap" : "receiver"); case IInstanceReferenceOperation: Unknown("implicit receiver (an object or collection initializer)"); return None(); @@ -495,6 +625,8 @@ private SortedSet Value(IOperation op) Unknown("ref local"); return None(); } + if (Outer(l.Local)) + return One("heap"); return One($"local:{LocalId(l.Local)}"); case IFieldReferenceOperation f: return Field(f); @@ -740,6 +872,10 @@ private void Assign(IOperation target, SortedSet value) { switch (target) { + case ILocalReferenceOperation l when Outer(l.Local): + case IParameterReferenceOperation when _site is not null: + Unknown("assignment to a variable outside the call"); + return; case ILocalReferenceOperation l when !l.Local.IsRef: _locals[LocalId(l.Local)].Sources.UnionWith(Inert(l.Local.Type) ? None() : value); return; @@ -812,7 +948,7 @@ private void Assign(IOperation target, SortedSet value) /// A get-only auto-property assigned in its own type's constructor writes its backing field. private bool InOwnConstructor(IPropertySymbol property) => - _method.MethodKind is MethodKind.Constructor or MethodKind.StaticConstructor + _method is { MethodKind: MethodKind.Constructor or MethodKind.StaticConstructor } && SymbolEqualityComparer.Default.Equals(property.ContainingType, _method.ContainingType); private static bool IsBaseAccess(IOperation? instance) => @@ -923,19 +1059,7 @@ private SortedSet Call(IMethodSymbol method, IOperation? instance, Sorte StaticAccess(method.ContainingType, "member"); var receiver = instance is null ? null : Eval(instance); - string dispatch; - if (method.MethodKind == MethodKind.DelegateInvoke) - dispatch = "delegate"; - else if (!nonVirtual && (method.IsVirtual || method.IsAbstract || method.IsOverride - || method.ContainingType.TypeKind == TypeKind.Interface) - && !(method.IsSealed || method.ContainingType.IsSealed || method.ContainingType.IsValueType)) - dispatch = "virtual"; - else if (method.ContainingType.TypeKind == TypeKind.Interface) - dispatch = "virtual"; // a static abstract member: resolved by a type argument - else if (method.OriginalDefinition.DeclaringSyntaxReferences.IsEmpty) - dispatch = "extern"; - else - dispatch = "direct"; + var dispatch = Dispatch(method, nonVirtual); var id = _calls.Count; _calls.Add(new Dictionary diff --git a/frontend/roslyn/OwnSharp.Extractor/Program.cs b/frontend/roslyn/OwnSharp.Extractor/Program.cs index c075f86e..621f4bc6 100644 --- a/frontend/roslyn/OwnSharp.Extractor/Program.cs +++ b/frontend/roslyn/OwnSharp.Extractor/Program.cs @@ -7262,10 +7262,13 @@ or ImplicitObjectCreationExpressionSyntax } init // `stats` is additive coverage metadata — the core's load() ignores unknown keys. // P-006: the DI registration + ctor graph (empty when the scan has no // Add{Singleton,Scoped,Transient} calls). ownlang/di.py turns it into DI001. -// P-010 pillar 9: state-protocol regions -> `borrow_mut` / `move` flow records (OwnIR v1). A +// P-010 pillar 9: state-protocol regions -> `borrow_mut` / `move` / `proven_call` flow records (OwnIR v2). A // lowering, not an analysis (see ProtocolLowering.cs). A shape it cannot lower is a // REFUSAL of the whole run (exit 2, the same tier as the guarded-fact self-check below): // the alternative is a region that silently drops out of the facts and reads as clean. +// OwnIR v2 `proven_call` sites (H1): non-empty only when a protocol region holds a call the +// core must prove harmless; they turn into the document's `heap_effects` section below. +List<(string Key, string File, Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax Call)> protocolSites = new(); if (flowLocals) { var protocol = ProtocolLowering.Lower(compilation, parsed, flowRecordNames); @@ -7276,6 +7279,7 @@ or ImplicitObjectCreationExpressionSyntax } init return 2; } flowFunctions.AddRange(protocol.Functions); + protocolSites = protocol.Sites; } var factServices = ExtractServices(parsed); @@ -7298,7 +7302,7 @@ or ImplicitObjectCreationExpressionSyntax } init // // `ownir_version` is the core's current one (ownlang/ownir.py OWNIR_VERSION). It is spelled // as this one literal on purpose: tests/test_ownir.py (IR2) reads every stamp in this file. -const int ownir_version = 1; +const int ownir_version = 2; var facts = new Dictionary(); facts["ownir_version"] = ownir_version; // S0: ADDITIVE metadata, present ONLY under --fix-candidates. It does not move the version @@ -7312,6 +7316,11 @@ or ImplicitObjectCreationExpressionSyntax } init facts["services"] = factServices; facts["functions"] = flowFunctions; facts["stats"] = factStats; +// OwnIR v2 (H1): the heap-effect FACTS a `proven_call` is judged against — the call sites +// and the methods they reach. Present exactly when a `proven_call` is: a document without one +// is the v1 document with a new stamp. The core proves or refuses; nothing here decides. +if (protocolSites.Count > 0) + facts["heap_effects"] = HeapEffectFacts.Section(compilation, parsed, protocolSites); // OWN053 (promoted from ownership-semantics-lab H-29): an ADDITIVE top-level list of orphaned // awaitables from which both engines mint the advisory. Absent when there is no site, so such // a document stays byte-identical to the pre-OWN053 shape. diff --git a/frontend/roslyn/OwnSharp.Extractor/ProtocolLowering.cs b/frontend/roslyn/OwnSharp.Extractor/ProtocolLowering.cs index da818355..64bf6cba 100644 --- a/frontend/roslyn/OwnSharp.Extractor/ProtocolLowering.cs +++ b/frontend/roslyn/OwnSharp.Extractor/ProtocolLowering.cs @@ -1,9 +1,11 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Operations; // State protocols (P-010, pillar 9): lowering a C# state-protocol surface into OwnIR `move` / -// `borrow_mut` (OwnIR v1, spec/OwnIR.md §5.3; the bridge's side is spec/Bridge.md BR-L12/L13). +// `borrow_mut` / `proven_call` (OwnIR v2, spec/OwnIR.md §5.3-5.4; the bridge's side is +// spec/Bridge.md BR-L12/L13/L14). // // The surface is recognised by two attributes, matched by NAME (so an API carries no // dependency on this project): @@ -55,8 +57,10 @@ // no stated contract: a call, a constructor, a property getter or setter, an indexer, a // user-defined operator or conversion. The one exception is a construct that visibly touches // the entity: that is lowered as a use of it, and the core rejects it with a verdict rather -// than a refusal. When effect summaries (P-036/P-037) can prove a call harmless, this rule is -// the one to relax; until then an unprovable call is not analysed as safe. +// than a refusal. The rule is relaxed in exactly one place, and not by this lowering: a call +// that touches nothing and is dispatched `direct` is lowered as an OwnIR v2 `proven_call`, and +// the CORE admits it only when the shared heap-effect summaries prove it harmless +// (docs/notes/h1-proven-call.md). An unprovable call is still not analysed as safe. // // Also refused, anywhere: a token with no lowerable origin (`default`, `new`), a token // parameter or return type, a token type that is not a ref struct, a region whose body is not @@ -76,7 +80,8 @@ // skipped; a project that relies on implicit usings writes them out (or qualifies the API). internal static class ProtocolLowering { - internal sealed record Result(List Functions, List Refusals); + internal sealed record Result(List Functions, List Refusals, + List<(string Key, string File, InvocationExpressionSyntax Call)> Sites); private sealed class Refused(string message) : Exception(message); @@ -95,6 +100,9 @@ private sealed class Ctx public required Dictionary Files { get; init; } public required SortedDictionary Contracts { get; init; } public required ISet LegacyNames { get; init; } + /// OwnIR v2 `proven_call` sites, shared by the whole scan (Program.cs turns them + /// into the document's `heap_effects` section). + public required List<(string Key, string File, InvocationExpressionSyntax Call)> Sites { get; init; } public List Regions { get; } = new(); public Dictionary Tokens { get; } = new(SymbolEqualityComparer.Default); @@ -115,6 +123,7 @@ public static Result Lower(Compilation compilation, { var functions = new List(); var refusals = new List(); + var sites = new List<(string Key, string File, InvocationExpressionSyntax Call)>(); var contracts = new SortedDictionary(StringComparer.Ordinal); var files = new Dictionary(); foreach (var (file, tree) in parsed) @@ -183,7 +192,7 @@ public static Result Lower(Compilation compilation, var ctx = new Ctx { Model = model, File = file, Files = files, Contracts = contracts, - LegacyNames = legacyNames, + LegacyNames = legacyNames, Sites = sites, }; var ops = new List(); foreach (var st in method.Body.Statements) @@ -252,7 +261,7 @@ public static Result Lower(Compilation compilation, } functions.AddRange(contracts.Values); - return new Result(functions, refusals); + return new Result(functions, refusals, sites); } // ---- the protocol boundary ------------------------------------------------------------- @@ -1158,6 +1167,24 @@ private static void Scan(Ctx ctx, SyntaxNode node, List ops) if (inv.Expression is MemberAccessExpressionSyntax target) Scan(ctx, target.Expression, ops); NoteEntityTyped(ctx, inv, ops); + // OwnIR v2 (H1): a call that touched nothing protocol-relevant and that the + // shared summary layer COULD prove harmless (a `direct` call, the H0 + // classification) is handed to the core as a `proven_call`. The core proves + // it or refuses the document; this lowering decides nothing about it. + // Everything else keeps today's answer: a touch is a `use` the core judges, + // and a call no summary can cover is refused here, word for word as before. + if (ctx.EntityTouches == before && HeapEffectFacts.Provable(ctx.Model, inv)) + { + var site = HeapEffectFacts.SiteKey(ctx.File, inv); + ctx.Sites.Add((site, ctx.File, inv)); + ops.Add(new Dictionary + { + ["op"] = "proven_call", ["site"] = site, + ["callee"] = HeapEffectFacts.Key(((IInvocationOperation)ctx.Model.GetOperation(inv)!).TargetMethod), + ["line"] = Line(inv), + }); + return; + } var name = method is null ? inv.Expression.ToString() : $"{method.ContainingType.ToDisplayString()}.{method.Name}"; diff --git a/frontend/roslyn/README.md b/frontend/roslyn/README.md index 9c1bb06b..459511e3 100644 --- a/frontend/roslyn/README.md +++ b/frontend/roslyn/README.md @@ -70,11 +70,15 @@ symbols instead of surfacing as OWN050. `--no-project-refs` opts out; an unbuilt project just contributes nothing. Run `dotnet run --project OwnSharp.Extractor -- --help` for the full option list. -## State protocols (`--flow-locals`, OwnIR v1) +## State protocols (`--flow-locals`, OwnIR v2) With `--flow-locals` the extractor also lowers a **state-protocol surface** — the first slice of [P-010](../../docs/proposals/P-010-type-disciplines.md) pillar 9 — -into the OwnIR v1 ops `move` and `borrow_mut` ([OwnIR.md §5.3](../../spec/OwnIR.md)). +into the OwnIR ops `move` and `borrow_mut` ([OwnIR.md §5.3](../../spec/OwnIR.md)), +and, since OwnIR v2, `proven_call`: a call inside a region that touches neither the +entity nor the token and is dispatched `direct` is handed to the core, which admits it +only when the shared heap-effect summaries prove it harmless ([OwnIR.md §5.4](../../spec/OwnIR.md), +[H1](../../docs/notes/h1-proven-call.md)). (These are *state* protocols — which state an entity is in. The *obligation* protocols of P-025 / OwnIR §8 are a different mechanism with a similar name.) It is recognised by two attributes matched by **name**, so a domain carries no diff --git a/frontend/roslyn/protocol-samples/Api/ProtocolApi.cs b/frontend/roslyn/protocol-samples/Api/ProtocolApi.cs index f4e3b030..c574db6b 100644 --- a/frontend/roslyn/protocol-samples/Api/ProtocolApi.cs +++ b/frontend/roslyn/protocol-samples/Api/ProtocolApi.cs @@ -3,7 +3,7 @@ namespace Own.Protocols.Sample; -// The sample state protocol behind `protocol-samples/cases` (C# -> OwnIR v1 lowering, +// The sample state protocol behind `protocol-samples/cases` (C# -> OwnIR v2 lowering, // see frontend/roslyn/README.md). Deliberately minimal: one entity, three state tokens, // two region entries, no persistence. It is a fixture, not an API proposal — the // realistic shape, on an entity EF Core tracks, is `protocol-samples/efcore`. What it diff --git a/frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs b/frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs new file mode 100644 index 00000000..dec3e0e8 --- /dev/null +++ b/frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1 (OwnIR v2 `proven_call`): a call that touches neither the entity nor the token and that +// the shared heap-effect summaries prove harmless -> ADMITTED, clean. The lowering does not +// decide it: it hands the core a `proven_call` and the facts; the core proves it. +public static class H1aHarmlessCall +{ + static int Twice(int x) => x * 2; + + public static async Task Run(Db db, int id) + { + var order = await db.SingleAsync(id); + Protocol.WithApproved(order, approved => + { + var n = Twice(21); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs b/frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs new file mode 100644 index 00000000..b367d00a --- /dev/null +++ b/frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1: A -> B -> pure work. Only B's summary says what A does, and it says nothing is +// touched -> ADMITTED, clean. +public static class H1bTransitivePure +{ + static int A(int x) => B(x) + 1; + static int B(int x) => x * 3; + + public static async Task Run(Db db, int id, int value) + { + var order = await db.SingleAsync(id); + Protocol.WithApproved(order, approved => + { + var n = A(value); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs b/frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs new file mode 100644 index 00000000..1344fac4 --- /dev/null +++ b/frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1: a strongly connected component that does nothing to memory (Even <-> Odd) solves to +// harmless at its least fixpoint -> ADMITTED, clean. +public static class H1cPureScc +{ + static bool Even(int n) => n == 0 || Odd(n - 1); + static bool Odd(int n) => n != 0 && Even(n - 1); + + public static async Task Run(Db db, int id, int value) + { + var order = await db.SingleAsync(id); + Protocol.WithApproved(order, approved => + { + var even = Even(value); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/cases/H1d_global_state.cs b/frontend/roslyn/protocol-samples/cases/H1d_global_state.cs new file mode 100644 index 00000000..466eea99 --- /dev/null +++ b/frontend/roslyn/protocol-samples/cases/H1d_global_state.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1: the call touches neither entity nor token, but it writes a static -> the core REFUSES +// the document (writes.static is may). Not harmless is not clean. +public static class H1dGlobalState +{ + static int _counter; + static void TouchesGlobalState() => _counter++; + + public static async Task Run(Db db, int id) + { + var order = await db.SingleAsync(id); + Protocol.WithApproved(order, approved => + { + TouchesGlobalState(); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs b/frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs new file mode 100644 index 00000000..3db10110 --- /dev/null +++ b/frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs @@ -0,0 +1,24 @@ +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1: A -> B, and B writes a static. A looks innocent at the call site; its summary carries +// B's write -> the core REFUSES. +public static class H1eTransitiveGlobal +{ + static int _counter; + static int A(int x) { B(); return x; } + static void B() => _counter++; + + public static async Task Run(Db db, int id) + { + var order = await db.SingleAsync(id); + Protocol.WithApproved(order, approved => + { + var n = A(1); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs b/frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs new file mode 100644 index 00000000..8b2e9364 --- /dev/null +++ b/frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs @@ -0,0 +1,24 @@ +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1: Ping <-> Pong, and only Pong writes a static. The write reaches every member of the +// component -> the call to Ping is REFUSED by the core. +public static class H1fPollutedScc +{ + static int _ticks; + static void Ping(int n) { if (n > 0) Pong(n - 1); } + static void Pong(int n) { _ticks++; Ping(n); } + + public static async Task Run(Db db, int id) + { + var order = await db.SingleAsync(id); + Protocol.WithApproved(order, approved => + { + Ping(3); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs b/frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs new file mode 100644 index 00000000..4eb3933e --- /dev/null +++ b/frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs @@ -0,0 +1,23 @@ +using System; +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1: A -> Console.WriteLine. The call site is direct and touches nothing, but A reaches an +// external method no summary describes: Unknown is poison -> the core REFUSES. +public static class H1gTransitiveUnknown +{ + static void A(int x) => Console.WriteLine(x); + + public static async Task Run(Db db, int id) + { + var order = await db.SingleAsync(id); + Protocol.WithApproved(order, approved => + { + A(1); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/cases/H1h_mutates_entity.cs b/frontend/roslyn/protocol-samples/cases/H1h_mutates_entity.cs new file mode 100644 index 00000000..630986d5 --- /dev/null +++ b/frontend/roslyn/protocol-samples/cases/H1h_mutates_entity.cs @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1 leaves the entity rule alone: a call that is handed the borrowed entity is a USE of it, +// and the core rejects it with a verdict, whatever a summary would say. +public static class H1hMutatesEntity +{ + static void Mutates(Order x) => x.Annotate("changed"); + + public static async Task Run(Db db, int id) + { + var order = await db.SingleAsync(id); + Protocol.WithApproved(order, approved => + { + Mutates(order); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/cases/H1i_escapes_entity.cs b/frontend/roslyn/protocol-samples/cases/H1i_escapes_entity.cs new file mode 100644 index 00000000..ca3d89c1 --- /dev/null +++ b/frontend/roslyn/protocol-samples/cases/H1i_escapes_entity.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1 leaves the entity rule alone: handing the borrowed entity to a method that keeps it is a +// USE of it -> a verdict, as before H1. +public static class H1iEscapesEntity +{ + static Order? _saved; + static void Escapes(Order x) => _saved = x; + + public static async Task Run(Db db, int id) + { + var order = await db.SingleAsync(id); + Protocol.WithApproved(order, approved => + { + Escapes(order); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs b/frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs new file mode 100644 index 00000000..24923a58 --- /dev/null +++ b/frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs @@ -0,0 +1,25 @@ +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1: the argument is not the entity, but it is a variable of the code AROUND the call (the +// enclosing method's array). The call-site evidence reads every such variable as heap, so the +// callee's write through it is a heap write -> the core REFUSES. A mutation never vanishes +// because the mutated thing was declared outside the region. +public static class H1jMutatesOuterValue +{ + static void Fill(int[] buffer) => buffer[0] = 1; + + public static async Task Run(Db db, int id) + { + var order = await db.SingleAsync(id); + var buffer = new int[4]; + Protocol.WithApproved(order, approved => + { + Fill(buffer); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/cases/expected.json b/frontend/roslyn/protocol-samples/cases/expected.json index 15a8cb6e..654aa2ca 100644 --- a/frontend/roslyn/protocol-samples/cases/expected.json +++ b/frontend/roslyn/protocol-samples/cases/expected.json @@ -8,6 +8,20 @@ "G6_capability_not_spent": [ "OWN001" ], + "H1a_harmless_call": [], + "H1b_transitive_pure": [], + "H1c_pure_scc": [], + "H1d_global_state": "refused: OwnIR 'proven_call' to 'Own.Protocols.Cases.H1dGlobalState.TouchesGlobalState()' is not proven harmless: 'Own.Protocols.Cases.H1dGlobalState.TouchesGlobalState()': writes.static is may (frontend/roslyn/protocol-samples/cases/H1d_global_state.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless", + "H1e_transitive_global": "refused: OwnIR 'proven_call' to 'Own.Protocols.Cases.H1eTransitiveGlobal.A(int)' is not proven harmless: 'Own.Protocols.Cases.H1eTransitiveGlobal.A(int)': writes.static is may (frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs:19) — refused: an exclusive region admits only calls the effect summaries prove harmless", + "H1f_polluted_scc": "refused: OwnIR 'proven_call' to 'Own.Protocols.Cases.H1fPollutedScc.Ping(int)' is not proven harmless: 'Own.Protocols.Cases.H1fPollutedScc.Ping(int)': writes.static is may (frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs:19) — refused: an exclusive region admits only calls the effect summaries prove harmless", + "H1g_transitive_unknown": "refused: OwnIR 'proven_call' to 'Own.Protocols.Cases.H1gTransitiveUnknown.A(int)' is not proven harmless: 'Own.Protocols.Cases.H1gTransitiveUnknown.A(int)': writes.instance is unknown (frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless", + "H1h_mutates_entity": [ + "OWN013" + ], + "H1i_escapes_entity": [ + "OWN013" + ], + "H1j_mutates_outer_value": "refused: OwnIR 'proven_call' to 'Own.Protocols.Cases.H1jMutatesOuterValue.Fill(int[])' is not proven harmless: 'Own.Protocols.Cases.H1jMutatesOuterValue.Fill(int[])': parameter 0 is borrow_mut (frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs:20) — refused: an exclusive region admits only calls the effect summaries prove harmless", "L10_region_inside_try": [], "L11_region_beside_disposable": [], "L12_region_beside_leaked_disposable": [ diff --git a/frontend/roslyn/protocol-samples/refused/R18_external_call_inside_region.cs.txt b/frontend/roslyn/protocol-samples/refused/R18_external_call_inside_region.cs.txt new file mode 100644 index 00000000..daecc115 --- /dev/null +++ b/frontend/roslyn/protocol-samples/refused/R18_external_call_inside_region.cs.txt @@ -0,0 +1,22 @@ +using System; +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1 does not reach this one: a call to a method with no source (Console.WriteLine) can never +// be proven harmless, so the lowering refuses it exactly as it did before OwnIR v2. No +// allowlist: an external call is code with no stated contract. +public static class R18ExternalCallInsideRegion +{ + public static async Task Run(Db db, int id) + { + var order = await db.SingleAsync(id); + Protocol.WithApproved(order, approved => + { + Console.WriteLine("x"); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/refused/R19_virtual_call_inside_region.cs.txt b/frontend/roslyn/protocol-samples/refused/R19_virtual_call_inside_region.cs.txt new file mode 100644 index 00000000..5c649175 --- /dev/null +++ b/frontend/roslyn/protocol-samples/refused/R19_virtual_call_inside_region.cs.txt @@ -0,0 +1,26 @@ +using System.Threading.Tasks; +using Own.Protocols.Sample; + +namespace Own.Protocols.Cases; + +// H1 does not reach this one: a call through an interface dispatches to an implementation +// nobody can name statically, so no summary describes it -> refused by the lowering, exactly +// as before OwnIR v2. Devirtualization is not attempted. +public interface IClock +{ + int Ticks(); +} + +public static class R19VirtualCallInsideRegion +{ + public static async Task Run(Db db, int id, IClock clock) + { + var order = await db.SingleAsync(id); + Protocol.WithApproved(order, approved => + { + var t = clock.Ticks(); + approved.Ship(); + }); + await db.SaveChangesAsync(); + } +} diff --git a/frontend/roslyn/protocol-samples/refused/R9_opaque_call_inside_region.cs.txt b/frontend/roslyn/protocol-samples/refused/R9_opaque_call_inside_region.cs.txt index ce673b80..89deb7b4 100644 --- a/frontend/roslyn/protocol-samples/refused/R9_opaque_call_inside_region.cs.txt +++ b/frontend/roslyn/protocol-samples/refused/R9_opaque_call_inside_region.cs.txt @@ -6,9 +6,11 @@ using Own.Protocols.Sample; namespace Own.Protocols.Cases; // A call inside the region that never mentions the entity, and mutates it anyway. -// Nothing at the call site can be lowered, so nothing proves the call harmless - and an -// exclusive region does not analyse unprovable code as safe. REFUSED, never clean. -// (When effect summaries can prove a callee harmless, this is the rule they relax.) +// Nothing at the call site touches the entity, so since OwnIR v2 the lowering hands the call +// to the core as a `proven_call` - and the core REFUSES it: the heap-effect summaries see the +// mutation behind it (AnnotateLast writes an object reached through a static, writes.instance +// is may). An exclusive region does not analyse unprovable code as safe. REFUSED, never clean +// - one stage later than before H1, for a reason the summaries can now name. public static class R9OpaqueCallInsideRegion { public static async Task Run(Db db, int id) diff --git a/frontend/roslyn/protocol-samples/refused/expected.json b/frontend/roslyn/protocol-samples/refused/expected.json index 77cdc3a5..ae566288 100644 --- a/frontend/roslyn/protocol-samples/refused/expected.json +++ b/frontend/roslyn/protocol-samples/refused/expected.json @@ -7,6 +7,8 @@ "R15_region_opened_inside_protocol_type": "a protocol region is opened inside 'ParcelHandlers', one of the protocol's own types", "R16_token_handed_out_past_a_region_entry": "a callback that takes protocol token 'OpenLetter' is not the in-place body of a region entry", "R17_token_taken_by_a_local_function": "a callback that takes protocol token 'PackedCrate' is not the in-place body of a region entry", + "R18_external_call_inside_region": "a call to 'System.Console.WriteLine' inside a protocol region runs code with no stated contract", + "R19_virtual_call_inside_region": "a call to 'Own.Protocols.Cases.IClock.Ticks' inside a protocol region runs code with no stated contract", "R1_default_token": "has no lowerable origin", "R2_token_outside_region": "is declared outside a protocol region", "R3_return_inside_region": "`return` inside a protocol region", @@ -15,5 +17,8 @@ "R6_region_body_not_a_lambda": "must be a lambda written in place", "R7_entity_not_a_local": "must be a local or a parameter", "R8_token_not_a_ref_struct": "must be a ref struct", - "R9_opaque_call_inside_region": "a call to 'Own.Protocols.Sample.Backdoor.AnnotateLast' inside a protocol region runs code with no stated contract" + "R9_opaque_call_inside_region": { + "stage": "core", + "text": "OwnIR 'proven_call' to 'Own.Protocols.Sample.Backdoor.AnnotateLast()' is not proven harmless: 'Own.Protocols.Sample.Backdoor.AnnotateLast()': writes.instance is may" + } } diff --git a/ownlang/heap_effects.py b/ownlang/heap_effects.py index ddb05fec..bb24a2e3 100644 --- a/ownlang/heap_effects.py +++ b/ownlang/heap_effects.py @@ -5,8 +5,10 @@ least fixpoint over the call graph's SCC condensation. It is a second summary domain beside the Method Ownership Summary (`ownership.py`), in its own document: nothing here reads OwnIR facts, and nothing in the checker reads this. No verdict, -refusal or diagnostic depends on it (H0 is inert by construction; H1 is the first -consumer, and it is not written). +refusal or diagnostic depends on it, with ONE exception: OwnIR v2's `proven_call` +(H1) admits a call inside an exclusive region only when `site_verdict` below proves +it harmless — the predicate lives here, in the summary layer, not in the typestate +code that asks. THE DOMAIN, per method: @@ -438,6 +440,54 @@ def solve(methods: list[Method]) -> dict[str, Summary]: return solved +# --- H1: the harmless predicate (docs/notes/h1-proven-call.md) ---------------- +# +# The ONE consumer of the solved summaries that decides anything: OwnIR v2's +# `proven_call` (ownir.py `_admit_proven_calls`, own-bridge `proven.rs`) admits a +# call inside an exclusive region only when these two functions say so. Strict on +# purpose — a reference returned without an alias is still refused (`returns` must +# be empty), and Unknown fails every clause it touches. + + +def harmless(s: Summary) -> str | None: + """None when the summary proves the method harmless; otherwise the FIRST failing + clause, in a fixed order (parameters, receiver, writes, returns).""" + for i, effect in enumerate(s.params): + if effect > BORROW: + return f"parameter {i} is {EFFECTS[effect]}" + if s.receiver is not None and s.receiver > BORROW: + return f"receiver is {EFFECTS[s.receiver]}" + for i, kind in enumerate(WRITE_KINDS): + if s.writes[i] != W_NONE: + return f"writes.{kind} is {WRITES[s.writes[i]]}" + if s.returns: + return f"returns alias {', '.join(s.returns)}" + return None + + +def site_verdict(methods: dict[str, Method], solved: dict[str, Summary], + site: str, callee: str) -> str | None: + """None when the call site `site` (a record the frontend wrote for one call + expression) is proven harmless; otherwise why not. Every call in the site must be + a `direct` call to a summarized, harmless method, the site must contain a direct + call to `callee`, and the site's own solved summary must be harmless too.""" + m = methods[site] + if not any(c.callee == callee and c.dispatch == "direct" for c in m.calls): + return f"the site does not call '{callee}' directly" + for c in m.calls: + if c.dispatch != "direct": + return f"'{c.callee}' is {c.dispatch}" + if c.callee not in methods: + return f"'{c.callee}' has no summary" + reason = harmless(solved[c.callee]) + if reason is not None: + return f"'{c.callee}': {reason}" + reason = harmless(solved[site]) + if reason is not None: + return f"the call site: {reason}" + return None + + def _unresolved(m: Method, methods: dict[str, Method]) -> list[str]: reasons = set(m.unknown) for c in m.calls: diff --git a/ownlang/ownir.py b/ownlang/ownir.py index e3ad3789..54e3672d 100644 --- a/ownlang/ownir.py +++ b/ownlang/ownir.py @@ -9,7 +9,7 @@ OwnIR schema (JSON):: { - "ownir_version": 1, + "ownir_version": 2, "module": "WpfApp", "components": [ { @@ -150,6 +150,9 @@ from .effects import Effect as ReactEffect from .effects import find_effect_storms from .evidence import code_flow, di_path_steps +from .heap_effects import HeapEffectsError, site_verdict +from .heap_effects import load as load_heap_effects +from .heap_effects import solve as solve_heap_effects from .obligations import ( COLUMN_MAX, COLUMN_MIN, @@ -181,7 +184,7 @@ # vocabulary changes incompatibly; the extractor stamps the same number so a # mismatched extractor/core pair fails loudly (see load()) instead of silently # mis-reading facts. -OWNIR_VERSION = 1 +OWNIR_VERSION = 2 class OwnIRError(ValueError): @@ -340,7 +343,7 @@ def _route_resource(rkind: str) -> tuple[str, str]: _FLOW_OPS = frozenset({ "acquire", "release", "use", "overspan", "return", "alias_join", "call", "if", "while", - "move", "borrow_mut", + "move", "borrow_mut", "proven_call", }) # The parameter ownership-effect vocabulary (P-006/2b): a method contract's @@ -1232,6 +1235,10 @@ def to_module(facts: dict[str, Any], should surface as advisory findings rather than lose; `advisories` collects ready-made advisory Findings minted during lowering (OWN051 unverified-transfer notes) for the caller to append.""" + # OwnIR v2 (H1): every `proven_call` in the document is admitted or refused + # HERE, before anything is lowered — not where `_lower_flow` happens to meet + # it, so no body the lowering walks differently can carry one past the proof. + _admit_proven_calls(facts) handles: dict[str, dict[str, Any]] = {} functions: list[FnDecl] = [] gid = 0 @@ -1437,8 +1444,8 @@ def to_module(facts: dict[str, Any], # PASS. Refuse instead — on both engines, identically. arg, callee, transfer, cline = unverified[0] raise OwnIRError( - f"OwnIR function {fname!r} opens a borrow_mut region but hands " - f"{arg!r} to {callee!r} at an unverified position (inferred " + f"OwnIR function '{fname}' opens a borrow_mut region but hands " + f"'{arg}' to '{callee}' at an unverified position (inferred " f"contract: {transfer}) ({ffile}:{cline}) — refused: a function " f"with an exclusive region must not rely on the optimistic " f"ownership default") @@ -1501,6 +1508,78 @@ def to_module(facts: dict[str, Any], handles) +# OwnIR v2 (H1, docs/notes/h1-proven-call.md): `proven_call` is a call inside an +# exclusive region that the frontend could not lower (it touches no entity and no +# token, so there is no `use` to reject) and did not refuse, because a summary might +# prove it harmless. MUST-UNDERSTAND: a core that cannot prove it refuses the whole +# document — an unproven call inside a region is never read as clean. The proof is +# the shared heap-effect summary layer (`heap_effects.site_verdict`) over the +# document's `heap_effects` section, which carries the frontend's FACTS only. +_COMPOUND_KEYS = ("then", "else", "body") + + +def _proven_calls(nodes: Any, ffile: str, in_region: bool, + out: list[tuple[dict[str, Any], str, bool]], depth: int = 0) -> None: + """Every `proven_call` under `nodes`, in document order, with whether it sits + inside a `borrow_mut` body.""" + if not isinstance(nodes, list) or depth > 256: + return + for n in nodes: + if not isinstance(n, dict): + continue + if n.get("op") == "proven_call": + out.append((n, ffile, in_region)) + inner = in_region or n.get("op") == "borrow_mut" + for key in _COMPOUND_KEYS: + _proven_calls(n.get(key), ffile, inner, out, depth + 1) + + +def _admit_proven_calls(facts: dict[str, Any]) -> None: + raw_fns = facts.get("functions", []) + sites: list[tuple[dict[str, Any], str, bool]] = [] + if isinstance(raw_fns, list): + for fn in raw_fns: + if isinstance(fn, dict): + _proven_calls(fn.get("body"), str(fn.get("file", "?")), False, sites) + if not sites: + return + for n, ffile, in_region in sites: + line = _as_line(n.get("line", 0)) + site, callee = n.get("site"), n.get("callee") + if not (isinstance(site, str) and site and isinstance(callee, str) and callee): + raise OwnIRError( + f"OwnIR flow op 'proven_call' needs a non-empty string 'site' and a " + f"non-empty string 'callee' ({ffile}:{line})") + if not in_region: + raise OwnIRError( + f"OwnIR 'proven_call' outside a borrow_mut region ({ffile}:{line}) — " + f"refused: the op admits a call only inside an exclusive region") + first_file, first_line = sites[0][1], _as_line(sites[0][0].get("line", 0)) + section = facts.get("heap_effects") + if section is None: + raise OwnIRError( + f"OwnIR 'proven_call' ({first_file}:{first_line}) needs the 'heap_effects' " + f"section — refused: a call with no effect evidence is not harmless") + try: + methods = {m.key: m for m in load_heap_effects(section)} + except HeapEffectsError as e: + raise OwnIRError(f"OwnIR 'heap_effects' section is malformed — {e}") from e + solved = solve_heap_effects(list(methods.values())) + for n, ffile, _ in sites: + line = _as_line(n.get("line", 0)) + site, callee = str(n["site"]), str(n["callee"]) + if site not in methods: + raise OwnIRError( + f"OwnIR 'proven_call' site '{site}' has no record in 'heap_effects' " + f"({ffile}:{line}) — refused: no evidence is not harmless") + reason = site_verdict(methods, solved, site, callee) + if reason is not None: + raise OwnIRError( + f"OwnIR 'proven_call' to '{callee}' is not proven harmless: {reason} " + f"({ffile}:{line}) — refused: an exclusive region admits only calls " + f"the effect summaries prove harmless") + + def _has_region(nodes: Any) -> bool: """Whether a flow body contains a `borrow_mut` region at any depth.""" if not isinstance(nodes, list): @@ -3043,6 +3122,11 @@ def _lower_flow(nodes: list[Any], ffile: str, fname: str, "ever_released": result in released_vars, "pool": False} body.append(Let(handle, Acquire("Disposable", [], line), line)) + elif op == "proven_call": + # Admitted by `_admit_proven_calls` before lowering began (it refuses + # the document otherwise): a call the effect summaries proved + # harmless touches nothing the core tracks, so it lowers to nothing. + continue elif op in _FLOW_OPS: # In `_FLOW_OPS` (the declared vocabulary) but no branch above handled # it — an internal-consistency bug: the op was added to the authority set diff --git a/pyproject.toml b/pyproject.toml index ae06d25c..8fbe4eee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ select = ["E", "W", "F", "I", "B", "UP", "C4", "RUF"] [tool.ruff.lint.per-file-ignores] # scripts/perf_baseline.py is an INSTRUMENT SOURCE: its bytes are hashed into # the measurement harness digest that the frozen #263 preregistration names -# (1a26aa63fd5f), and steps 4, 5 and 6 are bound to that same value. Rewrapping +# (b92f08c990fc), and steps 4, 5 and 6 are bound to that same value. Rewrapping # a line there is not a cosmetic edit — it moves the digest and makes the frozen # contract point at an identity the tree no longer contains, which is exactly # what scripts/step7/mergegate.py exists to refuse. So the one over-long line diff --git a/rust/crates/own-bridge/src/heap_effects.rs b/rust/crates/own-bridge/src/heap_effects.rs index ec8f7c42..13881353 100644 --- a/rust/crates/own-bridge/src/heap_effects.rs +++ b/rust/crates/own-bridge/src/heap_effects.rs @@ -1,6 +1,7 @@ //! Heap-effect summaries — H0, the port of `ownlang/heap_effects.py` -//! (docs/notes/heap-effect-summaries.md). INERT: nothing in the bridge's -//! verdict path reads it. +//! (docs/notes/heap-effect-summaries.md). Inert, with ONE exception: `OwnIR` +//! v2's `proven_call` (H1, `proven.rs`) admits a call inside an exclusive +//! region only when `Proof::site_verdict` below proves it harmless. //! //! The input is the extractor's heap-effect SOURCE FACTS (`ownsharp-extract //! --heap-effects FILE`), not `OwnIR`: a separate document, so this module @@ -767,6 +768,93 @@ fn unresolved(m: &Method, methods: &HashMap<&str, &Method>) -> Vec { reasons.into_iter().collect() } +// --- H1: the harmless predicate (docs/notes/h1-proven-call.md) --------------- +// +// The port of `harmless` / `site_verdict`: the one consumer of the solved +// summaries that decides anything — OwnIR v2's `proven_call` (`proven.rs`). The +// reason texts are part of the refusal parity surface. + +/// The FIRST failing clause, in the reference's fixed order, or `None` when +/// the summary proves the method harmless. +fn harmless(s: &Summary) -> Option { + for (i, effect) in s.params.iter().enumerate() { + if *effect > BORROW { + return Some(format!("parameter {i} is {}", effect_label(*effect))); + } + } + if let Some(r) = s.receiver { + if r > BORROW { + return Some(format!("receiver is {}", effect_label(r))); + } + } + for (i, kind) in WRITE_KINDS.iter().enumerate() { + let level = s.writes.get(i).copied().unwrap_or(W_UNKNOWN); + if level != W_NONE { + return Some(format!("writes.{kind} is {}", write_label(level))); + } + } + if !s.returns.is_empty() { + return Some(format!("returns alias {}", s.returns.join(", "))); + } + None +} + +/// A loaded and solved `heap_effects` section — what `proven_call` is judged +/// against. +pub(crate) struct Proof { + methods: Vec, + solved: HashMap, +} + +/// Load and solve a `heap_effects` section (the H0 vocabulary). +pub(crate) fn prove(section: &Value) -> Result { + let methods = load(section)?; + let solved = solve(&methods); + Ok(Proof { methods, solved }) +} + +impl Proof { + fn method(&self, key: &str) -> Option<&Method> { + self.methods.iter().find(|m| m.key == key) + } + + /// Whether the section holds a record named `key`. + pub(crate) fn has(&self, key: &str) -> bool { + self.method(key).is_some() + } + + /// The reference's `site_verdict`: `None` when the call site is proven + /// harmless, otherwise why not. + pub(crate) fn site_verdict(&self, site: &str, callee: &str) -> Option { + let Some(m) = self.method(site) else { + return Some(format!("'{site}' has no summary")); + }; + if !m + .calls + .iter() + .any(|c| c.callee == callee && c.dispatch == "direct") + { + return Some(format!("the site does not call '{callee}' directly")); + } + for c in &m.calls { + if c.dispatch != "direct" { + return Some(format!("'{}' is {}", c.callee, c.dispatch)); + } + let Some(s) = self.solved.get(&c.callee) else { + return Some(format!("'{}' has no summary", c.callee)); + }; + if let Some(reason) = harmless(s) { + return Some(format!("'{}': {reason}", c.callee)); + } + } + // every loaded record is solved; a missing one is no proof, never a pass + let Some(s) = self.solved.get(site) else { + return Some(format!("'{site}' has no summary")); + }; + harmless(s).map(|reason| format!("the call site: {reason}")) + } +} + fn effect_label(level: u8) -> &'static str { EFFECTS .get(usize::from(level)) diff --git a/rust/crates/own-bridge/src/lib.rs b/rust/crates/own-bridge/src/lib.rs index abc45c46..56cfa5ce 100644 --- a/rust/crates/own-bridge/src/lib.rs +++ b/rust/crates/own-bridge/src/lib.rs @@ -41,6 +41,7 @@ mod dump; mod heap_effects; mod lower; mod mos; +mod proven; mod render; mod verdict; diff --git a/rust/crates/own-bridge/src/lower.rs b/rust/crates/own-bridge/src/lower.rs index b3de0fc6..a4e3671e 100644 --- a/rust/crates/own-bridge/src/lower.rs +++ b/rust/crates/own-bridge/src/lower.rs @@ -1973,6 +1973,10 @@ fn lower_flow<'v>(ctx: &mut FnCtx<'v, '_>, nodes: &'v [Value]) -> Result {} _ => { return Err(BridgeError(format!( "unknown OwnIR flow op {} ({}:{line}) — extractor/core \ @@ -1999,6 +2003,11 @@ pub(crate) fn lower_full(facts: &OwnIr) -> Result { .as_object() .expect("a struct serializes to an object"); + // OwnIR v2 (H1): every `proven_call` is admitted or refused before anything + // is lowered (the reference's `_admit_proven_calls` at the head of + // `to_module`). + crate::proven::admit(root)?; + let mut handles = HandleStore::default(); let mut functions: Vec = Vec::new(); let mut gid: i64 = 0; diff --git a/rust/crates/own-bridge/src/proven.rs b/rust/crates/own-bridge/src/proven.rs new file mode 100644 index 00000000..92033c4d --- /dev/null +++ b/rust/crates/own-bridge/src/proven.rs @@ -0,0 +1,136 @@ +//! `OwnIR` v2's `proven_call` (H1, docs/notes/h1-proven-call.md) — the port of +//! `ownlang/ownir.py::_admit_proven_calls`. +//! +//! A `proven_call` is a call inside an exclusive region that the frontend +//! could not lower (it touches no entity and no token) and did not refuse, +//! because a summary might prove it harmless. MUST-UNDERSTAND: every one in the +//! document is admitted or refused here, before anything is lowered — not where +//! `lower_flow` happens to meet it — and a refusal is the whole document's. The +//! proof belongs to the shared heap-effect summary layer +//! (`heap_effects::Proof`) over the document's `heap_effects` section; the +//! frontend contributes facts only. +//! +//! Every message is the reference's, byte for byte, in the reference's order. + +// `redundant_pub_crate` (nursery) conflicts with the workspace's DENY of +// `unreachable_pub` for items in private modules (same stance as `mos.rs`). +#![allow(clippy::redundant_pub_crate)] + +use crate::heap_effects; +use crate::lower::{as_line, as_list, py_str}; +use crate::BridgeError; +use serde_json::{Map, Value}; + +/// The reference's recursion bound for the walk (`_proven_calls`). +const MAX_DEPTH: usize = 256; + +/// The compound keys a flow node nests bodies under, in the reference's order. +const COMPOUND_KEYS: [&str; 3] = ["then", "else", "body"]; + +struct Site<'v> { + node: &'v Map, + file: String, + in_region: bool, +} + +/// `_proven_calls`: every `proven_call` under `nodes`, in document order, with +/// whether it sits inside a `borrow_mut` body. +fn collect<'v>( + nodes: Option<&'v Value>, + file: &str, + in_region: bool, + out: &mut Vec>, + depth: usize, +) { + let Some(Value::Array(items)) = nodes else { + return; + }; + if depth > MAX_DEPTH { + return; + } + for item in items { + let Some(n) = item.as_object() else { continue }; + let op = n.get("op").and_then(Value::as_str); + if op == Some("proven_call") { + out.push(Site { + node: n, + file: file.to_owned(), + in_region, + }); + } + let inner = in_region || op == Some("borrow_mut"); + for key in COMPOUND_KEYS { + collect(n.get(key), file, inner, out, depth.saturating_add(1)); + } + } +} + +fn non_empty_str<'v>(n: &'v Map, key: &str) -> Option<&'v str> { + n.get(key).and_then(Value::as_str).filter(|s| !s.is_empty()) +} + +/// `_admit_proven_calls`. +pub(crate) fn admit(root: &Map) -> Result<(), BridgeError> { + let mut sites = Vec::new(); + if let Some(Value::Array(_)) = root.get("functions") { + for fn_v in as_list(root.get("functions")) { + let Some(f) = fn_v.as_object() else { continue }; + let file = f.get("file").map_or_else(|| "?".to_owned(), py_str); + collect(f.get("body"), &file, false, &mut sites, 0); + } + } + let Some(first) = sites.first() else { + return Ok(()); + }; + for s in &sites { + let line = as_line(s.node.get("line")); + if non_empty_str(s.node, "site").is_none() || non_empty_str(s.node, "callee").is_none() { + return Err(BridgeError(format!( + "OwnIR flow op 'proven_call' needs a non-empty string 'site' and a \ + non-empty string 'callee' ({}:{line})", + s.file + ))); + } + if !s.in_region { + return Err(BridgeError(format!( + "OwnIR 'proven_call' outside a borrow_mut region ({}:{line}) — \ + refused: the op admits a call only inside an exclusive region", + s.file + ))); + } + } + let section = match root.get("heap_effects") { + None | Some(Value::Null) => { + return Err(BridgeError(format!( + "OwnIR 'proven_call' ({}:{}) needs the 'heap_effects' section — \ + refused: a call with no effect evidence is not harmless", + first.file, + as_line(first.node.get("line")) + ))) + } + Some(v) => v, + }; + let proof = heap_effects::prove(section) + .map_err(|e| BridgeError(format!("OwnIR 'heap_effects' section is malformed — {e}")))?; + for s in &sites { + let line = as_line(s.node.get("line")); + let site = non_empty_str(s.node, "site").unwrap_or_default(); + let callee = non_empty_str(s.node, "callee").unwrap_or_default(); + if !proof.has(site) { + return Err(BridgeError(format!( + "OwnIR 'proven_call' site '{site}' has no record in 'heap_effects' \ + ({}:{line}) — refused: no evidence is not harmless", + s.file + ))); + } + if let Some(reason) = proof.site_verdict(site, callee) { + return Err(BridgeError(format!( + "OwnIR 'proven_call' to '{callee}' is not proven harmless: {reason} \ + ({}:{line}) — refused: an exclusive region admits only calls the \ + effect summaries prove harmless", + s.file + ))); + } + } + Ok(()) +} diff --git a/rust/crates/own-bridge/src/render.rs b/rust/crates/own-bridge/src/render.rs index d91733d1..998d30a4 100644 --- a/rust/crates/own-bridge/src/render.rs +++ b/rust/crates/own-bridge/src/render.rs @@ -38,7 +38,12 @@ const SARIF_VERSION: &str = "2.1.0"; const TOOL_NAME: &str = "Owen"; /// `OWNIR_VERSION` — the schema stamp the driver carries so a consumer can tell /// which fact vocabulary produced the log. -const OWNIR_VERSION: u32 = 1; +const OWNIR_VERSION: u32 = 2; + +// The SARIF stamp is a copy of the door's version and must not drift from it: OwnIR v2 +// moved the door and left this copy at 1, and only the repro parity surface noticed. +#[allow(clippy::cast_lossless)] // `From` is not const; u32 -> i64 is lossless +const _: () = assert!(OWNIR_VERSION as i64 == own_ir::OWNIR_VERSION); /// `_esc_data`: a GitHub workflow-command MESSAGE escapes only `%`, CR and LF. fn esc_data(s: &str) -> String { diff --git a/rust/crates/own-bridge/tests/mechanisms.rs b/rust/crates/own-bridge/tests/mechanisms.rs index 714a23f7..2cf4ac09 100644 --- a/rust/crates/own-bridge/tests/mechanisms.rs +++ b/rust/crates/own-bridge/tests/mechanisms.rs @@ -34,12 +34,12 @@ fn record_order_changes_global_mint_order_predictably() { ) }; let doc_ab = lower(&format!( - r#"{{"ownir_version": 1, "module": "M", "components": [{}, {}]}}"#, + r#"{{"ownir_version": 2, "module": "M", "components": [{}, {}]}}"#, comp("A"), comp("B") )); let doc_ba = lower(&format!( - r#"{{"ownir_version": 1, "module": "M", "components": [{}, {}]}}"#, + r#"{{"ownir_version": 2, "module": "M", "components": [{}, {}]}}"#, comp("B"), comp("A") )); @@ -62,7 +62,7 @@ fn record_order_changes_global_mint_order_predictably() { #[test] fn kill_on_rebind_removes_the_old_mapping() { let doc = lower( - r#"{"ownir_version": 1, "module": "M", "functions": [ + r#"{"ownir_version": 2, "module": "M", "functions": [ {"name": "F", "file": "F.cs", "body": [ {"op": "acquire", "var": "x", "line": 2}, {"op": "call", "callee": "Unknown.Make", "args": [], "result": "x", "line": 3}, @@ -82,7 +82,7 @@ fn kill_on_rebind_removes_the_old_mapping() { #[test] fn precise_overload_channel_does_not_unmap() { let doc = lower( - r#"{"ownir_version": 1, "module": "M", "functions": [ + r#"{"ownir_version": 2, "module": "M", "functions": [ {"name": "Take", "file": "F.cs", "sig": "System.IO.Stream", "params": [{"name": "p", "line": 1, "effect": "consume"}], "body": []}, {"name": "Take", "file": "F.cs", "sig": "System.String", @@ -115,7 +115,7 @@ fn precise_overload_channel_does_not_unmap() { #[test] fn merged_may_consume_applies_the_kill_site_unmap() { let doc = lower( - r#"{"ownir_version": 1, "module": "M", "functions": [ + r#"{"ownir_version": 2, "module": "M", "functions": [ {"name": "Take", "file": "F.cs", "sig": "System.IO.Stream", "params": [{"name": "p", "line": 1, "effect": "consume"}], "body": []}, {"name": "Take", "file": "F.cs", "sig": "System.String", @@ -148,7 +148,7 @@ mod hoist_gates { #[test] fn positive_control_hoists() { let doc = lower( - r#"{"ownir_version": 1, "module": "M", "functions": [ + r#"{"ownir_version": 2, "module": "M", "functions": [ {"name": "F", "file": "F.cs", "body": [ {"op": "if", "line": 2, "then": [{"op": "acquire", "var": "r", "line": 3}], @@ -175,7 +175,7 @@ mod hoist_gates { #[test] fn nested_depth_reference_blocks_the_hoist() { let doc = lower( - r#"{"ownir_version": 1, "module": "M", "functions": [ + r#"{"ownir_version": 2, "module": "M", "functions": [ {"name": "F", "file": "F.cs", "body": [ {"op": "if", "line": 2, "then": [ {"op": "if", "line": 3, @@ -195,7 +195,7 @@ mod hoist_gates { #[test] fn while_body_acquire_blocks_the_hoist() { let doc = lower( - r#"{"ownir_version": 1, "module": "M", "functions": [ + r#"{"ownir_version": 2, "module": "M", "functions": [ {"name": "F", "file": "F.cs", "body": [ {"op": "while", "line": 2, "body": [{"op": "acquire", "var": "r", "line": 3}]}, @@ -214,7 +214,7 @@ mod hoist_gates { #[test] fn early_return_blocks_the_hoist() { let doc = lower( - r#"{"ownir_version": 1, "module": "M", "functions": [ + r#"{"ownir_version": 2, "module": "M", "functions": [ {"name": "F", "file": "F.cs", "body": [ {"op": "if", "line": 2, "then": [{"op": "acquire", "var": "r", "line": 3}], @@ -236,7 +236,7 @@ mod hoist_gates { #[test] fn unknown_flow_op_fails_loud_with_python_text() { let facts = own_ir::OwnIr::from_json( - r#"{"ownir_version": 1, "module": "M", "functions": [ + r#"{"ownir_version": 2, "module": "M", "functions": [ {"name": "F", "file": "X.cs", "body": [{"op": "goto", "line": 7}]}]}"#, ) .expect("facts parse"); diff --git a/rust/crates/own-ir/src/lib.rs b/rust/crates/own-ir/src/lib.rs index b250f647..de875a87 100644 --- a/rust/crates/own-ir/src/lib.rs +++ b/rust/crates/own-ir/src/lib.rs @@ -59,7 +59,7 @@ use serde_json::{Map, Value}; /// The schema version this crate understands. Bump only on an incompatible /// vocabulary change — additive optional fields are NOT a version bump. -pub const OWNIR_VERSION: i64 = 1; +pub const OWNIR_VERSION: i64 = 2; /// Why a document was rejected. /// diff --git a/rust/crates/own-ir/tests/roundtrip.rs b/rust/crates/own-ir/tests/roundtrip.rs index 26281dbc..4435ebb0 100644 --- a/rust/crates/own-ir/tests/roundtrip.rs +++ b/rust/crates/own-ir/tests/roundtrip.rs @@ -45,9 +45,21 @@ fn round_trips_every_python_fixture() { #[test] fn version_gate_rejects_future_schema() { - let err = OwnIr::from_json(r#"{"ownir_version": 2}"#).expect_err("v2 must be rejected"); + let err = OwnIr::from_json(r#"{"ownir_version": 3}"#).expect_err("v3 must be rejected"); assert!( - err.message.contains("schema v2") && err.message.contains(&format!("v{OWNIR_VERSION}")), + err.message.contains("schema v3") && err.message.contains(&format!("v{OWNIR_VERSION}")), + "gate message must name both versions: {err}" + ); +} + +/// `OwnIR` v2 is not a superset that also reads v1: a v1 document is refused at +/// the door, like any other version (no compatibility shim, either direction). +#[test] +fn version_gate_rejects_the_previous_schema() { + assert_eq!(OWNIR_VERSION, 2, "this control is about the v1 -> v2 move"); + let err = OwnIr::from_json(r#"{"ownir_version": 1}"#).expect_err("v1 must be rejected"); + assert!( + err.message.contains("schema v1") && err.message.contains("understands v2"), "gate message must name both versions: {err}" ); } diff --git a/rust/crates/own-ir/tests/validation_replay.rs b/rust/crates/own-ir/tests/validation_replay.rs index 0bfaeb9d..f2787fe5 100644 --- a/rust/crates/own-ir/tests/validation_replay.rs +++ b/rust/crates/own-ir/tests/validation_replay.rs @@ -370,7 +370,7 @@ fn the_depth_guard_never_fires_on_a_document_from_json_accepts() { node = serde_json::json!({"nested": [node]}); } serde_json::to_string(&serde_json::json!({ - "ownir_version": 1, + "ownir_version": 2, "future_section": node })) .expect("serializes") diff --git a/rust/crates/own-ir/tests/version_repr_census.rs b/rust/crates/own-ir/tests/version_repr_census.rs index cbf3a4df..d8d49c5b 100644 --- a/rust/crates/own-ir/tests/version_repr_census.rs +++ b/rust/crates/own-ir/tests/version_repr_census.rs @@ -61,10 +61,10 @@ const CENSUS: &[(&str, &str, &str)] = &[ ("null", "{\"ownir_version\": null}", "OwnIR 'ownir_version' must be an integer, got None"), ("array of one", "{\"ownir_version\": [\"a\"]}", "OwnIR 'ownir_version' must be an integer, got ['a']"), ("array empty", "{\"ownir_version\": []}", "OwnIR 'ownir_version' must be an integer, got []"), - ("int oversized +", "{\"ownir_version\": 10000000000000000000000000000000}", "OwnIR facts are schema v10000000000000000000000000000000, but this core understands v1. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it."), - ("int oversized -", "{\"ownir_version\": -10000000000000000000000000000000}", "OwnIR facts are schema v-10000000000000000000000000000000, but this core understands v1. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it."), - ("int i64 max + 1", "{\"ownir_version\": 9223372036854775808}", "OwnIR facts are schema v9223372036854775808, but this core understands v1. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it."), - ("int mismatch 7", "{\"ownir_version\": 7}", "OwnIR facts are schema v7, but this core understands v1. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it."), + ("int oversized +", "{\"ownir_version\": 10000000000000000000000000000000}", "OwnIR facts are schema v10000000000000000000000000000000, but this core understands v2. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it."), + ("int oversized -", "{\"ownir_version\": -10000000000000000000000000000000}", "OwnIR facts are schema v-10000000000000000000000000000000, but this core understands v2. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it."), + ("int i64 max + 1", "{\"ownir_version\": 9223372036854775808}", "OwnIR facts are schema v9223372036854775808, but this core understands v2. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it."), + ("int mismatch 7", "{\"ownir_version\": 7}", "OwnIR facts are schema v7, but this core understands v2. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it."), ]; /// Every value class the reference rejects, spelled byte for byte as the diff --git a/rust/crates/own-shadow/tests/repro.rs b/rust/crates/own-shadow/tests/repro.rs index f4cb2074..ae706b10 100644 --- a/rust/crates/own-shadow/tests/repro.rs +++ b/rust/crates/own-shadow/tests/repro.rs @@ -832,7 +832,7 @@ fn verify_refuses_each_structural_violation() { "raw bytes that parse to another document", "does not reproduce input.canonical", with_raw(&|_raw| { - let other = br#"{"ownir_version": 1, "module": "SomethingElse"}"#; + let other = br#"{"ownir_version": 2, "module": "SomethingElse"}"#; let identity = own_shadow::hash_bytes(other); Json::Object(vec![ ("algorithm".to_owned(), Json::Str("sha256".to_owned())), diff --git a/scripts/perf_baseline.py b/scripts/perf_baseline.py index 944c6bc1..42161e0a 100644 --- a/scripts/perf_baseline.py +++ b/scripts/perf_baseline.py @@ -1272,7 +1272,7 @@ def materialize_calibration(w: Workload, tmp: Path) -> Path: if gen == "facts": scale = _as_int(w.spec.get("scale", 1), 1) doc = { - "ownir_version": 1, + "ownir_version": 2, "module": w.id, "components": [{"name": f"C{i}", "kind": "class", "file": f"gen/{i}.cs", "line": i + 1} for i in range(scale)], diff --git a/scripts/protocol_gate.py b/scripts/protocol_gate.py index 88681943..f8ded89f 100644 --- a/scripts/protocol_gate.py +++ b/scripts/protocol_gate.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""State protocols (P-010, pillar 9): real C# -> OwnIR v1 -> core, tied back to source. +"""State protocols (P-010, pillar 9): real C# -> OwnIR v2 -> core, tied back to source. The Layer 2/3 ledgers freeze the facts the Roslyn lowering emits for the state-protocol surface, and both engines replay them with zero `dotnet`. This script is the other half: it @@ -15,7 +15,10 @@ 2. **refused** — every `refused/.cs.txt` compiles, and the extractor must REFUSE it (exit 2) with the text in `expected.json`: a shape the core cannot check, code with no - contract inside a region, a protocol that is not admitted. + contract inside a region, a protocol that is not admitted. An entry + `{"stage": "core", "text": ...}` is a call the lowering hands to the core as an OwnIR v2 + `proven_call` (H1): the extractor writes the facts, and the core must refuse them with + that text because the effect summaries cannot prove the call harmless. 3. **does-not-compile** — every `does-not-compile/.cs.txt` must be rejected by the C# compiler itself, built against the API as a SEPARATE assembly (so `internal` means what @@ -159,13 +162,31 @@ def refused(dll: str, fails: list[str]) -> int: src = _staged("refused", case, tmp) out = os.path.join(tmp, f"{case}.json") done = _run(["dotnet", dll, API_REL, src, "--flow-locals", "-o", out]) + want = expected[case] + if isinstance(want, dict): + # OwnIR v2 (H1): a call the lowering hands to the core as a `proven_call` + # is refused by the CORE when the summaries cannot prove it harmless — + # still a refusal of the whole document, one stage later. The facts are + # written, and the reference must refuse them with the pinned text. + if want.get("stage") != "core": + fails.append(f"refused/{case}: unknown expectation {want!r}") + elif done.returncode != 0 or not os.path.exists(out): + fails.append(f"refused/{case}: the extractor exited {done.returncode}; " + f"a core-stage refusal needs its facts written") + else: + with open(out, encoding="utf-8") as f: + got = _verdict(json.load(f)) + if not (isinstance(got, str) and want["text"] in got): + fails.append(f"refused/{case}: the core did not refuse with " + f"{want['text']!r}: {got!r}") + continue if done.returncode != 2: fails.append(f"refused/{case}: the extractor exited {done.returncode}, " f"expected a refusal (2)") elif os.path.exists(out): fails.append(f"refused/{case}: a facts file was written despite the refusal") - elif expected[case] not in done.stderr: - fails.append(f"refused/{case}: refusal text lacks {expected[case]!r}: " + elif want not in done.stderr: + fails.append(f"refused/{case}: refusal text lacks {want!r}: " f"{done.stderr.strip()[-300:]}") return len(on_disk) diff --git a/spec/Bridge.md b/spec/Bridge.md index 5a6c3431..b73f7834 100644 --- a/spec/Bridge.md +++ b/spec/Bridge.md @@ -243,6 +243,25 @@ A frontend must therefore not emit a region it cannot prove closed over contracted calls; what it may put inside one is the frontend's rule, not the bridge's (the Roslyn lowering is default-deny: transitions and what it reads). +**BR-L14 (`proven_call` — admission by proof, OwnIR v2).** A `proven_call` +(`site`, `callee`, `line`) is a call inside a region that touches nothing the +core tracks and that the frontend did not refuse, because a summary might prove +it harmless. It is **must-understand**: before ANY function is lowered, +`to_module` walks every function body (through `then`/`else`/`body`) and +admits or refuses every `proven_call` in the document, so no lowering path can +carry one past the proof. Refused (`OwnIRError`, file:line), in this order: +(a) a `site` or `callee` that is not a non-empty string; (b) a `proven_call` +outside a `borrow_mut` body; (c) a document with a `proven_call` and no +`heap_effects` section; (d) a `heap_effects` section the H0 reader refuses +(its message, prefixed); (e) a `site` with no record in the section; (f) a site +the shared summary layer does not prove harmless (`heap_effects.site_verdict`: +every call in the site `direct` to a summarized method that satisfies the +strict predicate — every parameter and the receiver at most `borrow`, no write +of any kind, nothing returned — and the site's own solved summary the same). +An admitted `proven_call` lowers to **nothing**: it touches no tracked +resource. The inference views and the MOS dump ignore it. The bridge never +reads a summary the frontend solved; the section carries facts only. + ## 3. Interprocedural MOS Normatively specified in [Inference.md](Inference.md) (INF-L/S/R/M/F/A/P + diff --git a/spec/OwnIR.md b/spec/OwnIR.md index 559cae8f..87035546 100644 --- a/spec/OwnIR.md +++ b/spec/OwnIR.md @@ -19,14 +19,15 @@ A facts document is a single JSON object: ```json { - "ownir_version": 1, + "ownir_version": 2, "module": "WpfApp", "components": [ /* §4 owned-resource records, grouped by type */ ], "functions": [ /* §5 flow bodies (intra-procedural CFG facts) */ ], "services": [ /* §6 DI registration graph */ ], "effects": [ /* §7 reactive-effect graph (EFF001) */ ], "protocols": [ /* §8 obligation protocols (OBL001-005): rules */ ], - "protocol_functions": [ /* §8 obligation protocols: per-method events */ ] + "protocol_functions": [ /* §8 obligation protocols: per-method events */ ], + "heap_effects": { /* §5.4 the facts a `proven_call` is judged against (v2) */ } } ``` @@ -47,12 +48,13 @@ OwnTS frontend. A document whose `ownir_version` differs from the core's raises silently mis-reading facts. A document that omits the field is read as the current version (the producers that omit it predate the field). -The version is currently **1**: +The version is currently **2**: | Version | What it added | |---|---| | 0 | the initial vocabulary | | 1 | two flow ops: `move` ([§5](#5-flow-bodies-functions)) and the compound `borrow_mut` ([§5.3](#53-exclusive-regions-borrow_mut)) | +| 2 | the must-understand flow op `proven_call` and the `heap_effects` section it is judged against ([§5.4](#54-proven-calls-proven_call-v2)) | A document stamped with an older version is refused, not migrated: no core reads two versions, and a producer and a core are built from the same commit. @@ -325,6 +327,7 @@ op vocabulary: | `while` | `body` (sub-body) | a `While` — a back-edge the core's worklist fixpoint converges over (A1) | | `move` | `var`, `src` | a `Let`+`Move`: `var` takes ownership of `src`'s obligation and `src` is dead after it (a later use is **OWN005**) | | `borrow_mut` | `owner`, `binding`, `body` (sub-body) | a `BorrowBlock`: an exclusive loan of the local `owner` for the block, visible inside as `binding` (§5.3) | +| `proven_call` | `site`, `callee` | nothing, once ADMITTED: a call inside a region the shared heap-effect summaries prove harmless; refused otherwise (§5.4) | Anything else is a hard error (§2, fail-loud). Overwriting a tracked local (a re-bound `call` result or `alias_join` target) kills its previous ownership @@ -454,6 +457,44 @@ region, two tokens in one region, and a token spent against a different owner are all accepted by the core; a frontend that uses regions for a state protocol must make those shapes unrepresentable in what it emits. +### 5.4 Proven calls (`proven_call`, v2) + +A region is default-deny: a call inside it that touches neither the owner nor a +token, and has no ownership contract, used to be refused by the frontend. OwnIR v2 +lets such a call through **only when it is proven harmless**, and moves that proof +out of the frontend into the core's shared heap-effect summary layer +([`docs/notes/h1-proven-call.md`](../docs/notes/h1-proven-call.md)). + +```json +{"op": "proven_call", "site": "site:Handlers.cs:42:21", + "callee": "Shop.Pricing.Twice(int)", "line": 42} +``` + +The op is **must-understand**, which is why it moved the version (§2): a core that +does not know it refuses the document (IR1 on the stamp, IR4 on the op), so no core +can read an unproven call as nothing. Its judge is the top-level `heap_effects` +section, in the H0 vocabulary ([`heap-effect-summaries.md`](../docs/notes/heap-effect-summaries.md)): +the record of the call `site` (the call expression, walked like a body, every +variable from outside it reading as `heap`) and the records of every method it +reaches through `direct` calls. The section carries **facts only**; the core solves +it. + +Before anything is lowered, every `proven_call` in the document is admitted or the +document is refused (`OwnIRError`, [Bridge.md](Bridge.md) BR-L14): + +- `site` and `callee` must be non-empty strings, and the op must sit inside a + `borrow_mut` body; +- the section must be present and valid, and must hold a record for `site`; +- every call in the site must be `direct`, to a method the section summarizes, and + the site must call `callee` directly; +- every one of those methods, and the site itself, must solve to **harmless**: every + parameter and the receiver at most `borrow`, no instance, static or indirect write, + nothing returned, and so no Unknown anywhere. + +An admitted `proven_call` lowers to nothing; inference and the MOS dump ignore it. +What the frontend still refuses is unchanged: a call it can see is virtual, external, +through a delegate, or a local function, and anything else no summary can describe. + ## 6. DI registration graph (`services[]`) An optional array feeding the **DI001** captive-dependency check (P-006), a diff --git a/spec/ownir.schema.json b/spec/ownir.schema.json index f6d6d3ff..7e428eed 100644 --- a/spec/ownir.schema.json +++ b/spec/ownir.schema.json @@ -8,7 +8,7 @@ "properties": { "ownir_version": { "description": "OwnIR fact-vocabulary version. Every producer stamps the same integer (OWNIR_VERSION in ownlang/ownir.py); a document whose version differs from the core's is rejected at load (spec/OwnIR.md IR1/IR2). An absent field is read as the current version by the core, but this schema requires it.", - "const": 1 + "const": 2 }, "module": { "description": "The extracted module/assembly name.", @@ -44,6 +44,15 @@ "type": "array", "items": { "$ref": "#/$defs/protocolFunction" } }, + "heap_effects": { + "description": "OwnIR v2 (H1): the heap-effect SOURCE FACTS a `proven_call` is judged against, in the H0 vocabulary (docs/notes/heap-effect-summaries.md; validated record by record by ownlang/heap_effects.py `load`): the call-site records and the method records they reach. Required when any `proven_call` is present; a document with one and without this section is refused. Facts only — the core solves them.", + "type": "object", + "required": ["heap_effects_version", "methods"], + "properties": { + "heap_effects_version": { "const": 1 }, + "methods": { "type": "array", "items": { "type": "object" } } + } + }, "orphaned_awaitables": { "description": "Optional, additive: the orphaned-awaitable sites feeding the OWN053 advisory (spec/OwnIR.md §9); absent when the extractor saw no site. Validated LAST by both strict doors (P-OWN053-DOOR); the tolerant coercions remain the contract for check_facts on an un-validated document.", "type": "array", @@ -323,6 +332,18 @@ "body": { "type": "array", "items": { "$ref": "#/$defs/flowOp" } } }, "required": ["op", "owner", "binding", "body"] + }, + { + "title": "proven_call", + "description": "OwnIR v2 (H1). A call inside a `borrow_mut` body that touches nothing the core tracks and that the frontend did not refuse, because the heap-effect summaries might prove it harmless. MUST-UNDERSTAND: the core admits it only when the shared summary layer proves the `site` record (and every method it calls) harmless over the document's `heap_effects` section, and refuses the whole document otherwise. An admitted call lowers to nothing (spec/Bridge.md BR-L14).", + "properties": { + "op": { "const": "proven_call" }, + "line": { "$ref": "#/$defs/sourceLine" }, + "column": { "$ref": "#/$defs/sourceColumn" }, + "site": { "type": "string", "minLength": 1 }, + "callee": { "type": "string", "minLength": 1 } + }, + "required": ["op", "site", "callee"] } ] }, diff --git a/tests/fake_shadow_engine.py b/tests/fake_shadow_engine.py index 0f5184bf..85e5c1a0 100755 --- a/tests/fake_shadow_engine.py +++ b/tests/fake_shadow_engine.py @@ -87,7 +87,7 @@ def main() -> int: target = os.environ.get("OWN_FAKE_ENGINE_REWRITE") if target: with open(target, "wb") as f: - f.write(b'{"ownir_version": 1, "module": "RewrittenUnderneath"}\n') + f.write(b'{"ownir_version": 2, "module": "RewrittenUnderneath"}\n') entry = _recorded_entry() entry["consumed"] = hash_bytes(raw) diff --git a/tests/fixtures/cli_ownir/bands-sarif-error-normal.case.json b/tests/fixtures/cli_ownir/bands-sarif-error-normal.case.json index e464ca44..72d411c8 100644 --- a/tests/fixtures/cli_ownir/bands-sarif-error-normal.case.json +++ b/tests/fixtures/cli_ownir/bands-sarif-error-normal.case.json @@ -14,7 +14,7 @@ "env": {}, "expected": { "exit": 1, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n },\n {\n \"id\": \"OWN050\",\n \"shortDescription\": {\n \"text\": \"declaring type unresolved -- leakage analysis skipped\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN050\",\n \"level\": \"note\",\n \"message\": {\n \"text\": \"cannot verify 'ext.Unknown' \\u2014 its declaring type is an unresolved reference (build the project or pass references); leakage analysis skipped [resource: unresolved reference]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 13\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"unresolved reference\",\n \"component\": \"Vm\",\n \"event\": \"ext.Unknown\",\n \"handler\": \"OnU\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n },\n {\n \"id\": \"OWN050\",\n \"shortDescription\": {\n \"text\": \"declaring type unresolved -- leakage analysis skipped\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN050\",\n \"level\": \"note\",\n \"message\": {\n \"text\": \"cannot verify 'ext.Unknown' \\u2014 its declaring type is an unresolved reference (build the project or pass references); leakage analysis skipped [resource: unresolved reference]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 13\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"unresolved reference\",\n \"component\": \"Vm\",\n \"event\": \"ext.Unknown\",\n \"handler\": \"OnU\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", "stderr": "\n2 findings, 1 advisory (OWN050), 1 suppressed ([OwnIgnore]).\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/bands-sarif-error-quiet.case.json b/tests/fixtures/cli_ownir/bands-sarif-error-quiet.case.json index 60e9278f..b3c64f9e 100644 --- a/tests/fixtures/cli_ownir/bands-sarif-error-quiet.case.json +++ b/tests/fixtures/cli_ownir/bands-sarif-error-quiet.case.json @@ -14,7 +14,7 @@ "env": {}, "expected": { "exit": 1, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", "stderr": "\n2 findings (1 advisory hidden), 1 suppressed ([OwnIgnore]).\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/bands-sarif-error-verbose.case.json b/tests/fixtures/cli_ownir/bands-sarif-error-verbose.case.json index da29f794..1710ac08 100644 --- a/tests/fixtures/cli_ownir/bands-sarif-error-verbose.case.json +++ b/tests/fixtures/cli_ownir/bands-sarif-error-verbose.case.json @@ -14,7 +14,7 @@ "env": {}, "expected": { "exit": 1, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n },\n {\n \"id\": \"OWN050\",\n \"shortDescription\": {\n \"text\": \"declaring type unresolved -- leakage analysis skipped\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN050\",\n \"level\": \"note\",\n \"message\": {\n \"text\": \"cannot verify 'ext.Unknown' \\u2014 its declaring type is an unresolved reference (build the project or pass references); leakage analysis skipped [resource: unresolved reference]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 13\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"unresolved reference\",\n \"component\": \"Vm\",\n \"event\": \"ext.Unknown\",\n \"handler\": \"OnU\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n },\n {\n \"id\": \"OWN050\",\n \"shortDescription\": {\n \"text\": \"declaring type unresolved -- leakage analysis skipped\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN050\",\n \"level\": \"note\",\n \"message\": {\n \"text\": \"cannot verify 'ext.Unknown' \\u2014 its declaring type is an unresolved reference (build the project or pass references); leakage analysis skipped [resource: unresolved reference]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 13\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"unresolved reference\",\n \"component\": \"Vm\",\n \"event\": \"ext.Unknown\",\n \"handler\": \"OnU\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", "stderr": "\n2 findings, 1 advisory (OWN050), 1 suppressed ([OwnIgnore]).\n by code: OWN001=3, OWN050=1\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/bands-sarif-warning-normal.case.json b/tests/fixtures/cli_ownir/bands-sarif-warning-normal.case.json index d6dc0575..7751333d 100644 --- a/tests/fixtures/cli_ownir/bands-sarif-warning-normal.case.json +++ b/tests/fixtures/cli_ownir/bands-sarif-warning-normal.case.json @@ -14,7 +14,7 @@ "env": {}, "expected": { "exit": 1, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n },\n {\n \"id\": \"OWN050\",\n \"shortDescription\": {\n \"text\": \"declaring type unresolved -- leakage analysis skipped\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN050\",\n \"level\": \"note\",\n \"message\": {\n \"text\": \"cannot verify 'ext.Unknown' \\u2014 its declaring type is an unresolved reference (build the project or pass references); leakage analysis skipped [resource: unresolved reference]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 13\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"unresolved reference\",\n \"component\": \"Vm\",\n \"event\": \"ext.Unknown\",\n \"handler\": \"OnU\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n },\n {\n \"id\": \"OWN050\",\n \"shortDescription\": {\n \"text\": \"declaring type unresolved -- leakage analysis skipped\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN050\",\n \"level\": \"note\",\n \"message\": {\n \"text\": \"cannot verify 'ext.Unknown' \\u2014 its declaring type is an unresolved reference (build the project or pass references); leakage analysis skipped [resource: unresolved reference]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 13\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"unresolved reference\",\n \"component\": \"Vm\",\n \"event\": \"ext.Unknown\",\n \"handler\": \"OnU\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", "stderr": "\n2 findings, 1 advisory (OWN050), 1 suppressed ([OwnIgnore]).\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/bands-sarif-warning-quiet.case.json b/tests/fixtures/cli_ownir/bands-sarif-warning-quiet.case.json index 19cb988e..24192df1 100644 --- a/tests/fixtures/cli_ownir/bands-sarif-warning-quiet.case.json +++ b/tests/fixtures/cli_ownir/bands-sarif-warning-quiet.case.json @@ -14,7 +14,7 @@ "env": {}, "expected": { "exit": 1, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", "stderr": "\n2 findings (1 advisory hidden), 1 suppressed ([OwnIgnore]).\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/bands-sarif-warning-verbose.case.json b/tests/fixtures/cli_ownir/bands-sarif-warning-verbose.case.json index e0ba5250..33e6a782 100644 --- a/tests/fixtures/cli_ownir/bands-sarif-warning-verbose.case.json +++ b/tests/fixtures/cli_ownir/bands-sarif-warning-verbose.case.json @@ -14,7 +14,7 @@ "env": {}, "expected": { "exit": 1, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n },\n {\n \"id\": \"OWN050\",\n \"shortDescription\": {\n \"text\": \"declaring type unresolved -- leakage analysis skipped\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN050\",\n \"level\": \"note\",\n \"message\": {\n \"text\": \"cannot verify 'ext.Unknown' \\u2014 its declaring type is an unresolved reference (build the project or pass references); leakage analysis skipped [resource: unresolved reference]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 13\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"unresolved reference\",\n \"component\": \"Vm\",\n \"event\": \"ext.Unknown\",\n \"handler\": \"OnU\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n },\n {\n \"id\": \"OWN050\",\n \"shortDescription\": {\n \"text\": \"declaring type unresolved -- leakage analysis skipped\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Injected' is subscribed (handler 'OnI') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'Vm' alive (possible leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Injected\",\n \"handler\": \"OnI\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 11\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n },\n {\n \"ruleId\": \"OWN050\",\n \"level\": \"note\",\n \"message\": {\n \"text\": \"cannot verify 'ext.Unknown' \\u2014 its declaring type is an unresolved reference (build the project or pass references); leakage analysis skipped [resource: unresolved reference]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 13\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"unresolved reference\",\n \"component\": \"Vm\",\n \"event\": \"ext.Unknown\",\n \"handler\": \"OnU\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Ignored' is subscribed (handler 'OnG') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 12\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Ignored\",\n \"handler\": \"OnG\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", "stderr": "\n2 findings, 1 advisory (OWN050), 1 suppressed ([OwnIgnore]).\n by code: OWN001=3, OWN050=1\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/clean-sarif.case.json b/tests/fixtures/cli_ownir/clean-sarif.case.json index a78e26c9..ced1ee02 100644 --- a/tests/fixtures/cli_ownir/clean-sarif.case.json +++ b/tests/fixtures/cli_ownir/clean-sarif.case.json @@ -10,7 +10,7 @@ "env": {}, "expected": { "exit": 0, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": []\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": []\n }\n ]\n}\n", "stderr": "../verdict_renders/render_empty.facts.json: ok — no subscription leaks found\n\n0 findings.\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/inputs/empty_ignore_reason.facts.json b/tests/fixtures/cli_ownir/inputs/empty_ignore_reason.facts.json index 5ad23da6..0b9bc4d5 100644 --- a/tests/fixtures/cli_ownir/inputs/empty_ignore_reason.facts.json +++ b/tests/fixtures/cli_ownir/inputs/empty_ignore_reason.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "EmptyReason", "_doc": [ "BR-V6: a reason-less [OwnIgnore] never suppresses. `ignore_reason` is", diff --git a/tests/fixtures/cli_ownir/inputs/nonascii_file.facts.json b/tests/fixtures/cli_ownir/inputs/nonascii_file.facts.json index 6c64c8c1..e91b4c88 100644 --- a/tests/fixtures/cli_ownir/inputs/nonascii_file.facts.json +++ b/tests/fixtures/cli_ownir/inputs/nonascii_file.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "NonAscii", "_doc": [ "A component whose FILE carries non-ASCII (and an astral character):", diff --git "a/tests/fixtures/cli_ownir/inputs/pa th \303\274n\303\257c\303\270d\303\251/facts.json" "b/tests/fixtures/cli_ownir/inputs/pa th \303\274n\303\257c\303\270d\303\251/facts.json" index de27162e..bc936394 100644 --- "a/tests/fixtures/cli_ownir/inputs/pa th \303\274n\303\257c\303\270d\303\251/facts.json" +++ "b/tests/fixtures/cli_ownir/inputs/pa th \303\274n\303\257c\303\270d\303\251/facts.json" @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "SpacedPath", "_doc": [ "Reached through a directory whose name carries a space and non-ASCII:", diff --git a/tests/fixtures/cli_ownir/inputs/suppressed_only.facts.json b/tests/fixtures/cli_ownir/inputs/suppressed_only.facts.json index a0432bd4..152796e8 100644 --- a/tests/fixtures/cli_ownir/inputs/suppressed_only.facts.json +++ b/tests/fixtures/cli_ownir/inputs/suppressed_only.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "SuppressedOnly", "_doc": [ "Every finding is [OwnIgnore]-suppressed: the run prints the `ok` line", diff --git a/tests/fixtures/cli_ownir/leaky-sarif-error.case.json b/tests/fixtures/cli_ownir/leaky-sarif-error.case.json index f996a4f2..487f8375 100644 --- a/tests/fixtures/cli_ownir/leaky-sarif-error.case.json +++ b/tests/fixtures/cli_ownir/leaky-sarif-error.case.json @@ -12,7 +12,7 @@ "env": {}, "expected": { "exit": 1, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Anchored' is subscribed (handler 'OnA') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 9,\n \"startColumn\": 17\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Anchored\",\n \"handler\": \"OnA\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Bare' is subscribed (handler 'OnB') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Bare\",\n \"handler\": \"OnB\"\n }\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Anchored' is subscribed (handler 'OnA') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 9,\n \"startColumn\": 17\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Anchored\",\n \"handler\": \"OnA\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Bare' is subscribed (handler 'OnB') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Bare\",\n \"handler\": \"OnB\"\n }\n }\n ]\n }\n ]\n}\n", "stderr": "\n2 findings.\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/leaky-sarif-warning.case.json b/tests/fixtures/cli_ownir/leaky-sarif-warning.case.json index 1720818c..f42858e7 100644 --- a/tests/fixtures/cli_ownir/leaky-sarif-warning.case.json +++ b/tests/fixtures/cli_ownir/leaky-sarif-warning.case.json @@ -12,7 +12,7 @@ "env": {}, "expected": { "exit": 1, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Anchored' is subscribed (handler 'OnA') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 9,\n \"startColumn\": 17\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Anchored\",\n \"handler\": \"OnA\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Bare' is subscribed (handler 'OnB') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Bare\",\n \"handler\": \"OnB\"\n }\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Anchored' is subscribed (handler 'OnA') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 9,\n \"startColumn\": 17\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Anchored\",\n \"handler\": \"OnA\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"warning\",\n \"message\": {\n \"text\": \"event 'bus.Bare' is subscribed (handler 'OnB') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Bare\",\n \"handler\": \"OnB\"\n }\n }\n ]\n }\n ]\n}\n", "stderr": "\n2 findings.\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/path-backslash-file-sarif.case.json b/tests/fixtures/cli_ownir/path-backslash-file-sarif.case.json index 8a0b95d7..791e0a63 100644 --- a/tests/fixtures/cli_ownir/path-backslash-file-sarif.case.json +++ b/tests/fixtures/cli_ownir/path-backslash-file-sarif.case.json @@ -10,7 +10,7 @@ "env": {}, "expected": { "exit": 1, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.50% off\\r\\nnext' is subscribed (handler 'OnE') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"src/gen:a,b.cs\"\n },\n \"region\": {\n \"startLine\": 7\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.50% off\\r\\nnext\",\n \"handler\": \"OnE\"\n }\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.50% off\\r\\nnext' is subscribed (handler 'OnE') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"src/gen:a,b.cs\"\n },\n \"region\": {\n \"startLine\": 7\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.50% off\\r\\nnext\",\n \"handler\": \"OnE\"\n }\n }\n ]\n }\n ]\n}\n", "stderr": "\n1 finding.\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/path-nonascii-file-sarif.case.json b/tests/fixtures/cli_ownir/path-nonascii-file-sarif.case.json index ad9bd923..5a6a0a32 100644 --- a/tests/fixtures/cli_ownir/path-nonascii-file-sarif.case.json +++ b/tests/fixtures/cli_ownir/path-nonascii-file-sarif.case.json @@ -10,7 +10,7 @@ "env": {}, "expected": { "exit": 1, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"src/\\u00dcn\\u00efc\\u00f8d\\u00e9/\\u0412\\u044c\\u044e_\\ud83d\\ude00.cs\"\n },\n \"region\": {\n \"startLine\": 4\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"src/\\u00dcn\\u00efc\\u00f8d\\u00e9/\\u0412\\u044c\\u044e_\\ud83d\\ude00.cs\"\n },\n \"region\": {\n \"startLine\": 4\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n }\n }\n ]\n }\n ]\n}\n", "stderr": "\n1 finding.\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/refuse-version-mismatch.case.json b/tests/fixtures/cli_ownir/refuse-version-mismatch.case.json index dfce65c6..2e2a7783 100644 --- a/tests/fixtures/cli_ownir/refuse-version-mismatch.case.json +++ b/tests/fixtures/cli_ownir/refuse-version-mismatch.case.json @@ -9,7 +9,7 @@ "expected": { "exit": 2, "stdout": "", - "stderr": "inputs/version_mismatch.facts.json: error: OwnIR facts are schema v99, but this core understands v1. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it.\n", + "stderr": "inputs/version_mismatch.facts.json: error: OwnIR facts are schema v99, but this core understands v2. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it.\n", "os_error_tail": null } } diff --git a/tests/fixtures/cli_ownir/sarif-ascii-escape-em-dash.case.json b/tests/fixtures/cli_ownir/sarif-ascii-escape-em-dash.case.json index 20d8683a..5261f0be 100644 --- a/tests/fixtures/cli_ownir/sarif-ascii-escape-em-dash.case.json +++ b/tests/fixtures/cli_ownir/sarif-ascii-escape-em-dash.case.json @@ -10,7 +10,7 @@ "env": {}, "expected": { "exit": 1, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Anchored' is subscribed (handler 'OnA') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 9,\n \"startColumn\": 17\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Anchored\",\n \"handler\": \"OnA\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Bare' is subscribed (handler 'OnB') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Bare\",\n \"handler\": \"OnB\"\n }\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Anchored' is subscribed (handler 'OnA') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 9,\n \"startColumn\": 17\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Anchored\",\n \"handler\": \"OnA\"\n }\n },\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'bus.Bare' is subscribed (handler 'OnB') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 10\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"bus.Bare\",\n \"handler\": \"OnB\"\n }\n }\n ]\n }\n ]\n}\n", "stderr": "\n2 findings.\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/suppressed-only-sarif.case.json b/tests/fixtures/cli_ownir/suppressed-only-sarif.case.json index ff8723f4..b11da31b 100644 --- a/tests/fixtures/cli_ownir/suppressed-only-sarif.case.json +++ b/tests/fixtures/cli_ownir/suppressed-only-sarif.case.json @@ -10,7 +10,7 @@ "env": {}, "expected": { "exit": 0, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 7\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [\n {\n \"id\": \"OWN001\",\n \"shortDescription\": {\n \"text\": \"owned resource not released on all paths (possible leak)\"\n }\n }\n ],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": [\n {\n \"ruleId\": \"OWN001\",\n \"level\": \"error\",\n \"message\": {\n \"text\": \"event 'SystemEvents.Static' is subscribed (handler 'OnS') but never unsubscribed \\u2014 the source keeps 'Vm' alive (leak) [resource: subscription token]\"\n },\n \"locations\": [\n {\n \"physicalLocation\": {\n \"artifactLocation\": {\n \"uri\": \"Vm.cs\"\n },\n \"region\": {\n \"startLine\": 7\n }\n }\n }\n ],\n \"properties\": {\n \"resourceKind\": \"subscription token\",\n \"component\": \"Vm\",\n \"event\": \"SystemEvents.Static\",\n \"handler\": \"OnS\"\n },\n \"suppressions\": [\n {\n \"kind\": \"inSource\",\n \"justification\": \"owned by the host container\"\n }\n ]\n }\n ]\n }\n ]\n}\n", "stderr": "inputs/suppressed_only.facts.json: ok — no subscription leaks found\n\n0 findings, 1 suppressed ([OwnIgnore]).\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/usage-duplicate-flag-last-wins.case.json b/tests/fixtures/cli_ownir/usage-duplicate-flag-last-wins.case.json index 60e0fb9b..a465e69f 100644 --- a/tests/fixtures/cli_ownir/usage-duplicate-flag-last-wins.case.json +++ b/tests/fixtures/cli_ownir/usage-duplicate-flag-last-wins.case.json @@ -10,7 +10,7 @@ "env": {}, "expected": { "exit": 0, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": []\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": []\n }\n ]\n}\n", "stderr": "../verdict_renders/render_empty.facts.json: ok — no subscription leaks found\n\n0 findings.\n", "os_error_tail": null } diff --git a/tests/fixtures/cli_ownir/usage-equals-spelling-accepted.case.json b/tests/fixtures/cli_ownir/usage-equals-spelling-accepted.case.json index 61942cdd..eba750b5 100644 --- a/tests/fixtures/cli_ownir/usage-equals-spelling-accepted.case.json +++ b/tests/fixtures/cli_ownir/usage-equals-spelling-accepted.case.json @@ -9,7 +9,7 @@ "env": {}, "expected": { "exit": 0, - "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [],\n \"properties\": {\n \"ownirSchemaVersion\": 1\n }\n }\n },\n \"results\": []\n }\n ]\n}\n", + "stdout": "{\n \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n \"version\": \"2.1.0\",\n \"runs\": [\n {\n \"tool\": {\n \"driver\": {\n \"name\": \"Owen\",\n \"informationUri\": \"https://github.com/PhysShell/Own.NET\",\n \"rules\": [],\n \"properties\": {\n \"ownirSchemaVersion\": 2\n }\n }\n },\n \"results\": []\n }\n ]\n}\n", "stderr": "../verdict_renders/render_empty.facts.json: ok — no subscription leaks found\n\n0 findings.\n", "os_error_tail": null } diff --git a/tests/fixtures/fix_candidates/AdditiveSections.cs b/tests/fixtures/fix_candidates/AdditiveSections.cs index 91d99d10..f9187484 100644 --- a/tests/fixtures/fix_candidates/AdditiveSections.cs +++ b/tests/fixtures/fix_candidates/AdditiveSections.cs @@ -91,3 +91,53 @@ public static void Run(Store store) } } } + +// heap_effects — OwnIR v2 (H1): a state-protocol region holding a call the core must prove +// harmless (a `proven_call`), which makes the extractor write the `heap_effects` section. The +// protocol is declared here, by attribute name, so the file stays self-contained. +namespace Own.Samples.FixCandidates.Additive.Protocols +{ + using System; + + [AttributeUsage(AttributeTargets.Struct)] + public sealed class ProtocolTokenAttribute : Attribute { } + + [AttributeUsage(AttributeTargets.Method)] + public sealed class ProtocolRegionAttribute : Attribute { } + + public sealed class Door + { + public bool IsOpen { get; internal set; } + } + + [ProtocolToken] + public readonly ref struct ClosedDoor + { + private readonly Door _door; + internal ClosedDoor(Door door) => _door = door; + + public void Open() => _door.IsOpen = true; + } + + public delegate void ClosedRegion(ClosedDoor closed); + + public static class Doors + { + [ProtocolRegion] + public static void WithClosed(Door door, ClosedRegion body) => body(new ClosedDoor(door)); + } + + public static class Handler + { + static int Twice(int x) => x * 2; + + public static void Run(Door door) + { + Doors.WithClosed(door, closed => + { + var n = Twice(21); + closed.Open(); + }); + } + } +} diff --git a/tests/fixtures/lowered/alias_join_cases.facts.json b/tests/fixtures/lowered/alias_join_cases.facts.json index 6f6124d8..f070761f 100644 --- a/tests/fixtures/lowered/alias_join_cases.facts.json +++ b/tests/fixtures/lowered/alias_join_cases.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Alias", "functions": [ { diff --git a/tests/fixtures/lowered/flow_kill_on_rebind.facts.json b/tests/fixtures/lowered/flow_kill_on_rebind.facts.json index 1d65275e..45772f6c 100644 --- a/tests/fixtures/lowered/flow_kill_on_rebind.facts.json +++ b/tests/fixtures/lowered/flow_kill_on_rebind.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Rebind", "functions": [ { diff --git a/tests/fixtures/lowered/flow_unmapped_refs.facts.json b/tests/fixtures/lowered/flow_unmapped_refs.facts.json index 93aa73b2..54ea40ab 100644 --- a/tests/fixtures/lowered/flow_unmapped_refs.facts.json +++ b/tests/fixtures/lowered/flow_unmapped_refs.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Unmapped", "functions": [ { diff --git a/tests/fixtures/lowered/fn_params_ordering.facts.json b/tests/fixtures/lowered/fn_params_ordering.facts.json index 9bd29f2d..cdf4d85e 100644 --- a/tests/fixtures/lowered/fn_params_ordering.facts.json +++ b/tests/fixtures/lowered/fn_params_ordering.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Params", "functions": [ { diff --git a/tests/fixtures/lowered/handles_global_counters.facts.json b/tests/fixtures/lowered/handles_global_counters.facts.json index 94d7c7b6..d08e8732 100644 --- a/tests/fixtures/lowered/handles_global_counters.facts.json +++ b/tests/fixtures/lowered/handles_global_counters.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Counters", "components": [ { diff --git a/tests/fixtures/lowered/handles_null_metadata.facts.json b/tests/fixtures/lowered/handles_null_metadata.facts.json index 8f49eef2..59525ea7 100644 --- a/tests/fixtures/lowered/handles_null_metadata.facts.json +++ b/tests/fixtures/lowered/handles_null_metadata.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "NullMeta", "components": [ { diff --git a/tests/fixtures/lowered/hoist_neg_early_return.facts.json b/tests/fixtures/lowered/hoist_neg_early_return.facts.json index 65e99f30..36f694ca 100644 --- a/tests/fixtures/lowered/hoist_neg_early_return.facts.json +++ b/tests/fixtures/lowered/hoist_neg_early_return.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "HoistNeg3", "functions": [ { diff --git a/tests/fixtures/lowered/hoist_neg_nested_depth.facts.json b/tests/fixtures/lowered/hoist_neg_nested_depth.facts.json index 26eb4ec0..a8612f19 100644 --- a/tests/fixtures/lowered/hoist_neg_nested_depth.facts.json +++ b/tests/fixtures/lowered/hoist_neg_nested_depth.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "HoistNeg1", "functions": [ { diff --git a/tests/fixtures/lowered/hoist_neg_while_body.facts.json b/tests/fixtures/lowered/hoist_neg_while_body.facts.json index 4fd47302..aa05bfe3 100644 --- a/tests/fixtures/lowered/hoist_neg_while_body.facts.json +++ b/tests/fixtures/lowered/hoist_neg_while_body.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "HoistNeg2", "functions": [ { diff --git a/tests/fixtures/lowered/hoist_pool_kind.facts.json b/tests/fixtures/lowered/hoist_pool_kind.facts.json index e4857ec9..7771c556 100644 --- a/tests/fixtures/lowered/hoist_pool_kind.facts.json +++ b/tests/fixtures/lowered/hoist_pool_kind.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "HoistPool", "functions": [ { diff --git a/tests/fixtures/lowered/hoist_positive_release.facts.json b/tests/fixtures/lowered/hoist_positive_release.facts.json index ec736570..77fc5e1d 100644 --- a/tests/fixtures/lowered/hoist_positive_release.facts.json +++ b/tests/fixtures/lowered/hoist_positive_release.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Hoist", "functions": [ { diff --git a/tests/fixtures/lowered/hoist_positive_use_only.facts.json b/tests/fixtures/lowered/hoist_positive_use_only.facts.json index 83a74b73..f3943b78 100644 --- a/tests/fixtures/lowered/hoist_positive_use_only.facts.json +++ b/tests/fixtures/lowered/hoist_positive_use_only.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "HoistUse", "functions": [ { diff --git a/tests/fixtures/lowered/lines_preserved.facts.json b/tests/fixtures/lowered/lines_preserved.facts.json index 740d921b..061a825d 100644 --- a/tests/fixtures/lowered/lines_preserved.facts.json +++ b/tests/fixtures/lowered/lines_preserved.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Lines", "components": [ { diff --git a/tests/fixtures/lowered/manifest.json b/tests/fixtures/lowered/manifest.json index 6bb93d0c..690f9e7f 100644 --- a/tests/fixtures/lowered/manifest.json +++ b/tests/fixtures/lowered/manifest.json @@ -147,6 +147,83 @@ ], "rust_replay": true }, + { + "name": "proven_call_bad_section", + "rules": [ + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "proven_call_empty_callee", + "rules": [ + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "proven_call_missing_callee_record", + "rules": [ + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "proven_call_no_section", + "rules": [ + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "proven_call_no_site_record", + "rules": [ + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "proven_call_outside_region", + "rules": [ + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "proven_call_site_not_a_string", + "rules": [ + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "proven_call_unknown_callee", + "rules": [ + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "proven_call_unknown_site", + "rules": [ + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "proven_call_virtual_in_site", + "rules": [ + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "proven_call_wrong_callee", + "rules": [ + "BR-L14" + ], + "rust_replay": true + }, { "name": "routing_r1_unresolved", "rules": [ @@ -221,6 +298,86 @@ ], "rust_replay": true }, + { + "name": "typestate_cs_h1a_harmless_call", + "rules": [ + "BR-L13", + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "typestate_cs_h1b_transitive_pure", + "rules": [ + "BR-L13", + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "typestate_cs_h1c_pure_scc", + "rules": [ + "BR-L13", + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "typestate_cs_h1d_global_state", + "rules": [ + "BR-L13", + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "typestate_cs_h1e_transitive_global", + "rules": [ + "BR-L13", + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "typestate_cs_h1f_polluted_scc", + "rules": [ + "BR-L13", + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "typestate_cs_h1g_transitive_unknown", + "rules": [ + "BR-L13", + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "typestate_cs_h1h_mutates_entity", + "rules": [ + "BR-L13", + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "typestate_cs_h1i_escapes_entity", + "rules": [ + "BR-L13", + "BR-L14" + ], + "rust_replay": true + }, + { + "name": "typestate_cs_h1j_mutates_outer_value", + "rules": [ + "BR-L13", + "BR-L14" + ], + "rust_replay": true + }, { "name": "typestate_cs_l10_region_inside_try", "rules": [ diff --git a/tests/fixtures/lowered/mos_call_channel_overload_sig.facts.json b/tests/fixtures/lowered/mos_call_channel_overload_sig.facts.json index 4bd22d8f..5babcd62 100644 --- a/tests/fixtures/lowered/mos_call_channel_overload_sig.facts.json +++ b/tests/fixtures/lowered/mos_call_channel_overload_sig.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Overloads", "functions": [ { diff --git a/tests/fixtures/lowered/mos_call_direct_consume.facts.json b/tests/fixtures/lowered/mos_call_direct_consume.facts.json index 3b00bf1f..2c088070 100644 --- a/tests/fixtures/lowered/mos_call_direct_consume.facts.json +++ b/tests/fixtures/lowered/mos_call_direct_consume.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Direct", "functions": [ { diff --git a/tests/fixtures/lowered/mos_call_unknown_drop.facts.json b/tests/fixtures/lowered/mos_call_unknown_drop.facts.json index 1ecbe439..d30f3369 100644 --- a/tests/fixtures/lowered/mos_call_unknown_drop.facts.json +++ b/tests/fixtures/lowered/mos_call_unknown_drop.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Drop", "functions": [ { diff --git a/tests/fixtures/lowered/mos_fresh_mint.facts.json b/tests/fixtures/lowered/mos_fresh_mint.facts.json index fcb16e30..4efe5d04 100644 --- a/tests/fixtures/lowered/mos_fresh_mint.facts.json +++ b/tests/fixtures/lowered/mos_fresh_mint.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Fresh", "functions": [ { diff --git a/tests/fixtures/lowered/mos_killsite_toplevel.facts.json b/tests/fixtures/lowered/mos_killsite_toplevel.facts.json index 18a69151..0931accb 100644 --- a/tests/fixtures/lowered/mos_killsite_toplevel.facts.json +++ b/tests/fixtures/lowered/mos_killsite_toplevel.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "KillSite", "functions": [ { diff --git a/tests/fixtures/lowered/mos_untrack_inbranch.facts.json b/tests/fixtures/lowered/mos_untrack_inbranch.facts.json index 78b93728..3ebca4b6 100644 --- a/tests/fixtures/lowered/mos_untrack_inbranch.facts.json +++ b/tests/fixtures/lowered/mos_untrack_inbranch.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Untrack", "functions": [ { diff --git a/tests/fixtures/lowered/proven_call_bad_section.facts.json b/tests/fixtures/lowered/proven_call_bad_section.facts.json new file mode 100644 index 00000000..9ed8066a --- /dev/null +++ b/tests/fixtures/lowered/proven_call_bad_section.facts.json @@ -0,0 +1,132 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 9, + "methods": [ + { + "key": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/proven_call_bad_section.golden.json b/tests/fixtures/lowered/proven_call_bad_section.golden.json new file mode 100644 index 00000000..e3ebbc93 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_bad_section.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'heap_effects' section is malformed — heap-effect facts: heap_effects_version must be 1" +} diff --git a/tests/fixtures/lowered/proven_call_empty_callee.facts.json b/tests/fixtures/lowered/proven_call_empty_callee.facts.json new file mode 100644 index 00000000..c85e44d5 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_empty_callee.facts.json @@ -0,0 +1,132 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "callee": "", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/proven_call_empty_callee.golden.json b/tests/fixtures/lowered/proven_call_empty_callee.golden.json new file mode 100644 index 00000000..0b603421 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_empty_callee.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR flow op 'proven_call' needs a non-empty string 'site' and a non-empty string 'callee' (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18)" +} diff --git a/tests/fixtures/lowered/proven_call_missing_callee_record.facts.json b/tests/fixtures/lowered/proven_call_missing_callee_record.facts.json new file mode 100644 index 00000000..2eb09a00 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_missing_callee_record.facts.json @@ -0,0 +1,111 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/proven_call_missing_callee_record.golden.json b/tests/fixtures/lowered/proven_call_missing_callee_record.golden.json new file mode 100644 index 00000000..5e923a08 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_missing_callee_record.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)' is not proven harmless: 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)' has no summary (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/lowered/proven_call_no_section.facts.json b/tests/fixtures/lowered/proven_call_no_section.facts.json new file mode 100644 index 00000000..e40e026a --- /dev/null +++ b/tests/fixtures/lowered/proven_call_no_section.facts.json @@ -0,0 +1,80 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + } +} diff --git a/tests/fixtures/lowered/proven_call_no_section.golden.json b/tests/fixtures/lowered/proven_call_no_section.golden.json new file mode 100644 index 00000000..d51d85f1 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_no_section.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) needs the 'heap_effects' section — refused: a call with no effect evidence is not harmless" +} diff --git a/tests/fixtures/lowered/proven_call_no_site_record.facts.json b/tests/fixtures/lowered/proven_call_no_site_record.facts.json new file mode 100644 index 00000000..eaca8045 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_no_site_record.facts.json @@ -0,0 +1,106 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/proven_call_no_site_record.golden.json b/tests/fixtures/lowered/proven_call_no_site_record.golden.json new file mode 100644 index 00000000..58cbd910 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_no_site_record.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' site 'site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21' has no record in 'heap_effects' (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: no evidence is not harmless" +} diff --git a/tests/fixtures/lowered/proven_call_outside_region.facts.json b/tests/fixtures/lowered/proven_call_outside_region.facts.json new file mode 100644 index 00000000..2483b74b --- /dev/null +++ b/tests/fixtures/lowered/proven_call_outside_region.facts.json @@ -0,0 +1,132 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "line": 18 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/proven_call_outside_region.golden.json b/tests/fixtures/lowered/proven_call_outside_region.golden.json new file mode 100644 index 00000000..52a09ecf --- /dev/null +++ b/tests/fixtures/lowered/proven_call_outside_region.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' outside a borrow_mut region (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: the op admits a call only inside an exclusive region" +} diff --git a/tests/fixtures/lowered/proven_call_site_not_a_string.facts.json b/tests/fixtures/lowered/proven_call_site_not_a_string.facts.json new file mode 100644 index 00000000..eb60a326 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_site_not_a_string.facts.json @@ -0,0 +1,132 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": 7, + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/proven_call_site_not_a_string.golden.json b/tests/fixtures/lowered/proven_call_site_not_a_string.golden.json new file mode 100644 index 00000000..0b603421 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_site_not_a_string.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR flow op 'proven_call' needs a non-empty string 'site' and a non-empty string 'callee' (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18)" +} diff --git a/tests/fixtures/lowered/proven_call_unknown_callee.facts.json b/tests/fixtures/lowered/proven_call_unknown_callee.facts.json new file mode 100644 index 00000000..3d84971e --- /dev/null +++ b/tests/fixtures/lowered/proven_call_unknown_callee.facts.json @@ -0,0 +1,134 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [], + "unknown": [ + "dynamic" + ] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/proven_call_unknown_callee.golden.json b/tests/fixtures/lowered/proven_call_unknown_callee.golden.json new file mode 100644 index 00000000..fbda4554 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_unknown_callee.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)' is not proven harmless: 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)': writes.instance is unknown (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/lowered/proven_call_unknown_site.facts.json b/tests/fixtures/lowered/proven_call_unknown_site.facts.json new file mode 100644 index 00000000..05ab1508 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_unknown_site.facts.json @@ -0,0 +1,134 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [ + "expression Await" + ] + } + ] + } +} diff --git a/tests/fixtures/lowered/proven_call_unknown_site.golden.json b/tests/fixtures/lowered/proven_call_unknown_site.golden.json new file mode 100644 index 00000000..bbba906f --- /dev/null +++ b/tests/fixtures/lowered/proven_call_unknown_site.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)' is not proven harmless: the call site: writes.instance is unknown (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/lowered/proven_call_virtual_in_site.facts.json b/tests/fixtures/lowered/proven_call_virtual_in_site.facts.json new file mode 100644 index 00000000..bd5d55cc --- /dev/null +++ b/tests/fixtures/lowered/proven_call_virtual_in_site.facts.json @@ -0,0 +1,142 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + }, + { + "id": 1, + "callee": "Own.Protocols.Cases.IClock.Ticks()", + "dispatch": "virtual", + "receiver": [ + "heap" + ], + "args": [], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/proven_call_virtual_in_site.golden.json b/tests/fixtures/lowered/proven_call_virtual_in_site.golden.json new file mode 100644 index 00000000..ecbdad29 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_virtual_in_site.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)' is not proven harmless: 'Own.Protocols.Cases.IClock.Ticks()' is virtual (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/lowered/proven_call_wrong_callee.facts.json b/tests/fixtures/lowered/proven_call_wrong_callee.facts.json new file mode 100644 index 00000000..a0f83cc5 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_wrong_callee.facts.json @@ -0,0 +1,132 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Thrice(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/proven_call_wrong_callee.golden.json b/tests/fixtures/lowered/proven_call_wrong_callee.golden.json new file mode 100644 index 00000000..20d9ed86 --- /dev/null +++ b/tests/fixtures/lowered/proven_call_wrong_callee.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1aHarmlessCall.Thrice(int)' is not proven harmless: the site does not call 'Own.Protocols.Cases.H1aHarmlessCall.Thrice(int)' directly (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/lowered/routing_r1_unresolved.facts.json b/tests/fixtures/lowered/routing_r1_unresolved.facts.json index aa5da99e..a98f3999 100644 --- a/tests/fixtures/lowered/routing_r1_unresolved.facts.json +++ b/tests/fixtures/lowered/routing_r1_unresolved.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "R1", "components": [ { diff --git a/tests/fixtures/lowered/routing_r2_subscribe_self.facts.json b/tests/fixtures/lowered/routing_r2_subscribe_self.facts.json index 1a9a4879..657e4711 100644 --- a/tests/fixtures/lowered/routing_r2_subscribe_self.facts.json +++ b/tests/fixtures/lowered/routing_r2_subscribe_self.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "R2", "components": [ { diff --git a/tests/fixtures/lowered/routing_r3_capture_static.facts.json b/tests/fixtures/lowered/routing_r3_capture_static.facts.json index 74077eab..ee30d7ef 100644 --- a/tests/fixtures/lowered/routing_r3_capture_static.facts.json +++ b/tests/fixtures/lowered/routing_r3_capture_static.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "R3", "components": [ { diff --git a/tests/fixtures/lowered/routing_r4_returned_fresh.facts.json b/tests/fixtures/lowered/routing_r4_returned_fresh.facts.json index adb55f8d..1000b323 100644 --- a/tests/fixtures/lowered/routing_r4_returned_fresh.facts.json +++ b/tests/fixtures/lowered/routing_r4_returned_fresh.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "R4", "components": [ { diff --git a/tests/fixtures/lowered/routing_r5_di_capture.facts.json b/tests/fixtures/lowered/routing_r5_di_capture.facts.json index d3e70e6b..97c88040 100644 --- a/tests/fixtures/lowered/routing_r5_di_capture.facts.json +++ b/tests/fixtures/lowered/routing_r5_di_capture.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "R5", "components": [ { diff --git a/tests/fixtures/lowered/routing_r6_token_kinds.facts.json b/tests/fixtures/lowered/routing_r6_token_kinds.facts.json index 5e87ce03..cb8daffd 100644 --- a/tests/fixtures/lowered/routing_r6_token_kinds.facts.json +++ b/tests/fixtures/lowered/routing_r6_token_kinds.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "R6", "components": [ { diff --git a/tests/fixtures/lowered/tolerant_unknown_kind.facts.json b/tests/fixtures/lowered/tolerant_unknown_kind.facts.json index ed817928..9b1f8004 100644 --- a/tests/fixtures/lowered/tolerant_unknown_kind.facts.json +++ b/tests/fixtures/lowered/tolerant_unknown_kind.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "OD2", "components": [ { diff --git a/tests/fixtures/lowered/typestate_cs_a1_alias_of_entity.facts.json b/tests/fixtures/lowered/typestate_cs_a1_alias_of_entity.facts.json index 6d4eee76..ae8e1317 100644 --- a/tests/fixtures/lowered/typestate_cs_a1_alias_of_entity.facts.json +++ b/tests/fixtures/lowered/typestate_cs_a1_alias_of_entity.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_a2_entity_through_indexer.facts.json b/tests/fixtures/lowered/typestate_cs_a2_entity_through_indexer.facts.json index 1d232591..32eb94df 100644 --- a/tests/fixtures/lowered/typestate_cs_a2_entity_through_indexer.facts.json +++ b/tests/fixtures/lowered/typestate_cs_a2_entity_through_indexer.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_g6_capability_not_spent.facts.json b/tests/fixtures/lowered/typestate_cs_g6_capability_not_spent.facts.json index 7ad4bfcb..c93a2962 100644 --- a/tests/fixtures/lowered/typestate_cs_g6_capability_not_spent.facts.json +++ b/tests/fixtures/lowered/typestate_cs_g6_capability_not_spent.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_h1a_harmless_call.facts.json b/tests/fixtures/lowered/typestate_cs_h1a_harmless_call.facts.json new file mode 100644 index 00000000..b671bb19 --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1a_harmless_call.facts.json @@ -0,0 +1,132 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/typestate_cs_h1a_harmless_call.golden.json b/tests/fixtures/lowered/typestate_cs_h1a_harmless_call.golden.json new file mode 100644 index 00000000..0238ae17 --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1a_harmless_call.golden.json @@ -0,0 +1,210 @@ +{ + "lowered_version": 2, + "module": "Extracted", + "resources": [ + { + "name": "Subscription", + "kind": "subscription token", + "members": [ + { + "role": "acquire", + "name": "Subscribe" + }, + { + "role": "release", + "name": "Dispose" + } + ] + }, + { + "name": "Timer", + "kind": "timer", + "members": [ + { + "role": "acquire", + "name": "Start" + }, + { + "role": "release", + "name": "Stop" + } + ] + }, + { + "name": "Disposable", + "kind": "disposable field", + "members": [ + { + "role": "acquire", + "name": "New" + }, + { + "role": "release", + "name": "Dispose" + } + ] + }, + { + "name": "PooledBuffer", + "kind": "pooled buffer", + "members": [ + { + "role": "acquire", + "name": "Rent" + }, + { + "role": "release", + "name": "Return" + } + ] + } + ], + "externs": [ + { + "name": "$consume", + "params": [ + { + "effect": "consume", + "type": "Disposable" + } + ] + }, + { + "name": "$borrow", + "params": [ + { + "effect": "borrow", + "type": "Disposable" + } + ] + }, + { + "name": "$borrow_mut", + "params": [ + { + "effect": "borrow_mut", + "type": "Disposable" + } + ] + } + ], + "lifetimes": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "lifetime": null, + "params": [], + "ret": null, + "body": [ + { + "stmt": "acquire", + "handle": "loc_0", + "resource": "Disposable", + "line": 16 + }, + { + "stmt": "borrow_mut", + "owner": "loc_0", + "binding": "brw_1", + "body": [ + { + "stmt": "acquire", + "handle": "loc_2", + "resource": "Disposable", + "line": 16 + }, + { + "stmt": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "loc_2", + "brw_1" + ], + "line": 19 + } + ], + "line": 16 + }, + { + "stmt": "release", + "handle": "loc_0", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "lifetime": null, + "params": [ + { + "handle": "parg_3", + "type": { + "name": "Disposable", + "borrowed": false, + "mutable": false + }, + "line": 80, + "lifetime": null + }, + { + "handle": "parg_4", + "type": { + "name": "Disposable", + "borrowed": true, + "mutable": true + }, + "line": 80, + "lifetime": null + } + ], + "ret": null, + "body": [ + { + "stmt": "release", + "handle": "parg_3", + "line": 80 + } + ] + } + ], + "handles": [ + { + "handle": "loc_0", + "component": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 16, + "event": "order", + "resource": "flow-local", + "ever_released": true, + "pool": false + }, + { + "handle": "loc_2", + "component": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 16, + "event": "approved", + "resource": "flow-local", + "ever_released": false, + "pool": false + }, + { + "handle": "parg_3", + "component": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 80, + "event": "token", + "resource": "flow-local", + "ever_released": true + }, + { + "handle": "parg_4", + "component": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 80, + "event": "entity", + "resource": "flow-local", + "ever_released": false + } + ] +} diff --git a/tests/fixtures/lowered/typestate_cs_h1b_transitive_pure.facts.json b/tests/fixtures/lowered/typestate_cs_h1b_transitive_pure.facts.json new file mode 100644 index 00000000..862e7ca6 --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1b_transitive_pure.facts.json @@ -0,0 +1,164 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1bTransitivePure.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs:18:21", + "callee": "Own.Protocols.Cases.H1bTransitivePure.A(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1bTransitivePure.A(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs", + "line": 10, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1bTransitivePure.B(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 10 + } + ], + "unknown": [] + }, + { + "key": "Own.Protocols.Cases.H1bTransitivePure.B(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs:18:21", + "file": "frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1bTransitivePure.A(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/typestate_cs_h1b_transitive_pure.golden.json b/tests/fixtures/lowered/typestate_cs_h1b_transitive_pure.golden.json new file mode 100644 index 00000000..f7df56ca --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1b_transitive_pure.golden.json @@ -0,0 +1,210 @@ +{ + "lowered_version": 2, + "module": "Extracted", + "resources": [ + { + "name": "Subscription", + "kind": "subscription token", + "members": [ + { + "role": "acquire", + "name": "Subscribe" + }, + { + "role": "release", + "name": "Dispose" + } + ] + }, + { + "name": "Timer", + "kind": "timer", + "members": [ + { + "role": "acquire", + "name": "Start" + }, + { + "role": "release", + "name": "Stop" + } + ] + }, + { + "name": "Disposable", + "kind": "disposable field", + "members": [ + { + "role": "acquire", + "name": "New" + }, + { + "role": "release", + "name": "Dispose" + } + ] + }, + { + "name": "PooledBuffer", + "kind": "pooled buffer", + "members": [ + { + "role": "acquire", + "name": "Rent" + }, + { + "role": "release", + "name": "Return" + } + ] + } + ], + "externs": [ + { + "name": "$consume", + "params": [ + { + "effect": "consume", + "type": "Disposable" + } + ] + }, + { + "name": "$borrow", + "params": [ + { + "effect": "borrow", + "type": "Disposable" + } + ] + }, + { + "name": "$borrow_mut", + "params": [ + { + "effect": "borrow_mut", + "type": "Disposable" + } + ] + } + ], + "lifetimes": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1bTransitivePure.Run", + "lifetime": null, + "params": [], + "ret": null, + "body": [ + { + "stmt": "acquire", + "handle": "loc_0", + "resource": "Disposable", + "line": 16 + }, + { + "stmt": "borrow_mut", + "owner": "loc_0", + "binding": "brw_1", + "body": [ + { + "stmt": "acquire", + "handle": "loc_2", + "resource": "Disposable", + "line": 16 + }, + { + "stmt": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "loc_2", + "brw_1" + ], + "line": 19 + } + ], + "line": 16 + }, + { + "stmt": "release", + "handle": "loc_0", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "lifetime": null, + "params": [ + { + "handle": "parg_3", + "type": { + "name": "Disposable", + "borrowed": false, + "mutable": false + }, + "line": 80, + "lifetime": null + }, + { + "handle": "parg_4", + "type": { + "name": "Disposable", + "borrowed": true, + "mutable": true + }, + "line": 80, + "lifetime": null + } + ], + "ret": null, + "body": [ + { + "stmt": "release", + "handle": "parg_3", + "line": 80 + } + ] + } + ], + "handles": [ + { + "handle": "loc_0", + "component": "Own.Protocols.Cases.H1bTransitivePure.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs", + "line": 16, + "event": "order", + "resource": "flow-local", + "ever_released": true, + "pool": false + }, + { + "handle": "loc_2", + "component": "Own.Protocols.Cases.H1bTransitivePure.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs", + "line": 16, + "event": "approved", + "resource": "flow-local", + "ever_released": false, + "pool": false + }, + { + "handle": "parg_3", + "component": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 80, + "event": "token", + "resource": "flow-local", + "ever_released": true + }, + { + "handle": "parg_4", + "component": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 80, + "event": "entity", + "resource": "flow-local", + "ever_released": false + } + ] +} diff --git a/tests/fixtures/lowered/typestate_cs_h1c_pure_scc.facts.json b/tests/fixtures/lowered/typestate_cs_h1c_pure_scc.facts.json new file mode 100644 index 00000000..248975a3 --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1c_pure_scc.facts.json @@ -0,0 +1,175 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1cPureScc.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs:18:24", + "callee": "Own.Protocols.Cases.H1cPureScc.Even(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1cPureScc.Even(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs", + "line": 10, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "n", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1cPureScc.Odd(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 10 + } + ], + "unknown": [] + }, + { + "key": "Own.Protocols.Cases.H1cPureScc.Odd(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "n", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1cPureScc.Even(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 11 + } + ], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs:18:24", + "file": "frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1cPureScc.Even(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/typestate_cs_h1c_pure_scc.golden.json b/tests/fixtures/lowered/typestate_cs_h1c_pure_scc.golden.json new file mode 100644 index 00000000..ee6210d8 --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1c_pure_scc.golden.json @@ -0,0 +1,210 @@ +{ + "lowered_version": 2, + "module": "Extracted", + "resources": [ + { + "name": "Subscription", + "kind": "subscription token", + "members": [ + { + "role": "acquire", + "name": "Subscribe" + }, + { + "role": "release", + "name": "Dispose" + } + ] + }, + { + "name": "Timer", + "kind": "timer", + "members": [ + { + "role": "acquire", + "name": "Start" + }, + { + "role": "release", + "name": "Stop" + } + ] + }, + { + "name": "Disposable", + "kind": "disposable field", + "members": [ + { + "role": "acquire", + "name": "New" + }, + { + "role": "release", + "name": "Dispose" + } + ] + }, + { + "name": "PooledBuffer", + "kind": "pooled buffer", + "members": [ + { + "role": "acquire", + "name": "Rent" + }, + { + "role": "release", + "name": "Return" + } + ] + } + ], + "externs": [ + { + "name": "$consume", + "params": [ + { + "effect": "consume", + "type": "Disposable" + } + ] + }, + { + "name": "$borrow", + "params": [ + { + "effect": "borrow", + "type": "Disposable" + } + ] + }, + { + "name": "$borrow_mut", + "params": [ + { + "effect": "borrow_mut", + "type": "Disposable" + } + ] + } + ], + "lifetimes": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1cPureScc.Run", + "lifetime": null, + "params": [], + "ret": null, + "body": [ + { + "stmt": "acquire", + "handle": "loc_0", + "resource": "Disposable", + "line": 16 + }, + { + "stmt": "borrow_mut", + "owner": "loc_0", + "binding": "brw_1", + "body": [ + { + "stmt": "acquire", + "handle": "loc_2", + "resource": "Disposable", + "line": 16 + }, + { + "stmt": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "loc_2", + "brw_1" + ], + "line": 19 + } + ], + "line": 16 + }, + { + "stmt": "release", + "handle": "loc_0", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "lifetime": null, + "params": [ + { + "handle": "parg_3", + "type": { + "name": "Disposable", + "borrowed": false, + "mutable": false + }, + "line": 80, + "lifetime": null + }, + { + "handle": "parg_4", + "type": { + "name": "Disposable", + "borrowed": true, + "mutable": true + }, + "line": 80, + "lifetime": null + } + ], + "ret": null, + "body": [ + { + "stmt": "release", + "handle": "parg_3", + "line": 80 + } + ] + } + ], + "handles": [ + { + "handle": "loc_0", + "component": "Own.Protocols.Cases.H1cPureScc.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs", + "line": 16, + "event": "order", + "resource": "flow-local", + "ever_released": true, + "pool": false + }, + { + "handle": "loc_2", + "component": "Own.Protocols.Cases.H1cPureScc.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs", + "line": 16, + "event": "approved", + "resource": "flow-local", + "ever_released": false, + "pool": false + }, + { + "handle": "parg_3", + "component": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 80, + "event": "token", + "resource": "flow-local", + "ever_released": true + }, + { + "handle": "parg_4", + "component": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 80, + "event": "entity", + "resource": "flow-local", + "ever_released": false + } + ] +} diff --git a/tests/fixtures/lowered/typestate_cs_h1d_global_state.facts.json b/tests/fixtures/lowered/typestate_cs_h1d_global_state.facts.json new file mode 100644 index 00000000..fc30ff1e --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1d_global_state.facts.json @@ -0,0 +1,129 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1dGlobalState.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1d_global_state.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1d_global_state.cs:18:13", + "callee": "Own.Protocols.Cases.H1dGlobalState.TouchesGlobalState()", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1dGlobalState.TouchesGlobalState()", + "file": "frontend/roslyn/protocol-samples/cases/H1d_global_state.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [ + { + "kind": "static", + "target": [] + } + ], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1d_global_state.cs:18:13", + "file": "frontend/roslyn/protocol-samples/cases/H1d_global_state.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1dGlobalState.TouchesGlobalState()", + "dispatch": "direct", + "receiver": null, + "args": [], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/typestate_cs_h1d_global_state.golden.json b/tests/fixtures/lowered/typestate_cs_h1d_global_state.golden.json new file mode 100644 index 00000000..0b789122 --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1d_global_state.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1dGlobalState.TouchesGlobalState()' is not proven harmless: 'Own.Protocols.Cases.H1dGlobalState.TouchesGlobalState()': writes.static is may (frontend/roslyn/protocol-samples/cases/H1d_global_state.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/lowered/typestate_cs_h1e_transitive_global.facts.json b/tests/fixtures/lowered/typestate_cs_h1e_transitive_global.facts.json new file mode 100644 index 00000000..7af5d3cb --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1e_transitive_global.facts.json @@ -0,0 +1,161 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1eTransitiveGlobal.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 17 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 17, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 17 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs:19:21", + "callee": "Own.Protocols.Cases.H1eTransitiveGlobal.A(int)", + "line": 19 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 20 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 17 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1eTransitiveGlobal.A(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1eTransitiveGlobal.B()", + "dispatch": "direct", + "receiver": null, + "args": [], + "line": 11 + } + ], + "unknown": [] + }, + { + "key": "Own.Protocols.Cases.H1eTransitiveGlobal.B()", + "file": "frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs", + "line": 12, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [ + { + "kind": "static", + "target": [] + } + ], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs:19:21", + "file": "frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs", + "line": 19, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1eTransitiveGlobal.A(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 19 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/typestate_cs_h1e_transitive_global.golden.json b/tests/fixtures/lowered/typestate_cs_h1e_transitive_global.golden.json new file mode 100644 index 00000000..f620cd7b --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1e_transitive_global.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1eTransitiveGlobal.A(int)' is not proven harmless: 'Own.Protocols.Cases.H1eTransitiveGlobal.A(int)': writes.static is may (frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs:19) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/lowered/typestate_cs_h1f_polluted_scc.facts.json b/tests/fixtures/lowered/typestate_cs_h1f_polluted_scc.facts.json new file mode 100644 index 00000000..3e554b7b --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1f_polluted_scc.facts.json @@ -0,0 +1,180 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1fPollutedScc.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 17 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 17, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 17 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs:19:13", + "callee": "Own.Protocols.Cases.H1fPollutedScc.Ping(int)", + "line": 19 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 20 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 17 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1fPollutedScc.Ping(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "n", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1fPollutedScc.Pong(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 11 + } + ], + "unknown": [] + }, + { + "key": "Own.Protocols.Cases.H1fPollutedScc.Pong(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs", + "line": 12, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "n", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [ + { + "kind": "static", + "target": [] + } + ], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1fPollutedScc.Ping(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 12 + } + ], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs:19:13", + "file": "frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs", + "line": 19, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1fPollutedScc.Ping(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 19 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/typestate_cs_h1f_polluted_scc.golden.json b/tests/fixtures/lowered/typestate_cs_h1f_polluted_scc.golden.json new file mode 100644 index 00000000..26adb983 --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1f_polluted_scc.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1fPollutedScc.Ping(int)' is not proven harmless: 'Own.Protocols.Cases.H1fPollutedScc.Ping(int)': writes.static is may (frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs:19) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/lowered/typestate_cs_h1g_transitive_unknown.facts.json b/tests/fixtures/lowered/typestate_cs_h1g_transitive_unknown.facts.json new file mode 100644 index 00000000..8ceb8045 --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1g_transitive_unknown.facts.json @@ -0,0 +1,145 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1gTransitiveUnknown.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs:18:13", + "callee": "Own.Protocols.Cases.H1gTransitiveUnknown.A(int)", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1gTransitiveUnknown.A(int)", + "file": "frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs", + "line": 11, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "x", + "inert": true + } + ], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "System.Console.WriteLine(int)", + "dispatch": "extern", + "receiver": null, + "args": [ + [] + ], + "line": 11 + } + ], + "unknown": [ + "member of external type System.Console" + ] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs:18:13", + "file": "frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs", + "line": 18, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1gTransitiveUnknown.A(int)", + "dispatch": "direct", + "receiver": null, + "args": [ + [] + ], + "line": 18 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/typestate_cs_h1g_transitive_unknown.golden.json b/tests/fixtures/lowered/typestate_cs_h1g_transitive_unknown.golden.json new file mode 100644 index 00000000..76e4b670 --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1g_transitive_unknown.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1gTransitiveUnknown.A(int)' is not proven harmless: 'Own.Protocols.Cases.H1gTransitiveUnknown.A(int)': writes.instance is unknown (frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/lowered/typestate_cs_h1h_mutates_entity.facts.json b/tests/fixtures/lowered/typestate_cs_h1h_mutates_entity.facts.json new file mode 100644 index 00000000..aabab30c --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1h_mutates_entity.facts.json @@ -0,0 +1,79 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1hMutatesEntity.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1h_mutates_entity.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 15 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 15, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 15 + }, + { + "op": "use", + "var": "order", + "line": 17 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 18 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 15 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + } +} diff --git a/tests/fixtures/lowered/typestate_cs_h1h_mutates_entity.golden.json b/tests/fixtures/lowered/typestate_cs_h1h_mutates_entity.golden.json new file mode 100644 index 00000000..c302f3d8 --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1h_mutates_entity.golden.json @@ -0,0 +1,215 @@ +{ + "lowered_version": 2, + "module": "Extracted", + "resources": [ + { + "name": "Subscription", + "kind": "subscription token", + "members": [ + { + "role": "acquire", + "name": "Subscribe" + }, + { + "role": "release", + "name": "Dispose" + } + ] + }, + { + "name": "Timer", + "kind": "timer", + "members": [ + { + "role": "acquire", + "name": "Start" + }, + { + "role": "release", + "name": "Stop" + } + ] + }, + { + "name": "Disposable", + "kind": "disposable field", + "members": [ + { + "role": "acquire", + "name": "New" + }, + { + "role": "release", + "name": "Dispose" + } + ] + }, + { + "name": "PooledBuffer", + "kind": "pooled buffer", + "members": [ + { + "role": "acquire", + "name": "Rent" + }, + { + "role": "release", + "name": "Return" + } + ] + } + ], + "externs": [ + { + "name": "$consume", + "params": [ + { + "effect": "consume", + "type": "Disposable" + } + ] + }, + { + "name": "$borrow", + "params": [ + { + "effect": "borrow", + "type": "Disposable" + } + ] + }, + { + "name": "$borrow_mut", + "params": [ + { + "effect": "borrow_mut", + "type": "Disposable" + } + ] + } + ], + "lifetimes": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1hMutatesEntity.Run", + "lifetime": null, + "params": [], + "ret": null, + "body": [ + { + "stmt": "acquire", + "handle": "loc_0", + "resource": "Disposable", + "line": 15 + }, + { + "stmt": "borrow_mut", + "owner": "loc_0", + "binding": "brw_1", + "body": [ + { + "stmt": "acquire", + "handle": "loc_2", + "resource": "Disposable", + "line": 15 + }, + { + "stmt": "use", + "handle": "loc_0", + "line": 17 + }, + { + "stmt": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "loc_2", + "brw_1" + ], + "line": 18 + } + ], + "line": 15 + }, + { + "stmt": "release", + "handle": "loc_0", + "line": 15 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "lifetime": null, + "params": [ + { + "handle": "parg_3", + "type": { + "name": "Disposable", + "borrowed": false, + "mutable": false + }, + "line": 80, + "lifetime": null + }, + { + "handle": "parg_4", + "type": { + "name": "Disposable", + "borrowed": true, + "mutable": true + }, + "line": 80, + "lifetime": null + } + ], + "ret": null, + "body": [ + { + "stmt": "release", + "handle": "parg_3", + "line": 80 + } + ] + } + ], + "handles": [ + { + "handle": "loc_0", + "component": "Own.Protocols.Cases.H1hMutatesEntity.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1h_mutates_entity.cs", + "line": 15, + "event": "order", + "resource": "flow-local", + "ever_released": true, + "pool": false + }, + { + "handle": "loc_2", + "component": "Own.Protocols.Cases.H1hMutatesEntity.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1h_mutates_entity.cs", + "line": 15, + "event": "approved", + "resource": "flow-local", + "ever_released": false, + "pool": false + }, + { + "handle": "parg_3", + "component": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 80, + "event": "token", + "resource": "flow-local", + "ever_released": true + }, + { + "handle": "parg_4", + "component": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 80, + "event": "entity", + "resource": "flow-local", + "ever_released": false + } + ] +} diff --git a/tests/fixtures/lowered/typestate_cs_h1i_escapes_entity.facts.json b/tests/fixtures/lowered/typestate_cs_h1i_escapes_entity.facts.json new file mode 100644 index 00000000..8473f76d --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1i_escapes_entity.facts.json @@ -0,0 +1,79 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1iEscapesEntity.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1i_escapes_entity.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 16 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 16, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 16 + }, + { + "op": "use", + "var": "order", + "line": 18 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 19 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + } +} diff --git a/tests/fixtures/lowered/typestate_cs_h1i_escapes_entity.golden.json b/tests/fixtures/lowered/typestate_cs_h1i_escapes_entity.golden.json new file mode 100644 index 00000000..7c36a60e --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1i_escapes_entity.golden.json @@ -0,0 +1,215 @@ +{ + "lowered_version": 2, + "module": "Extracted", + "resources": [ + { + "name": "Subscription", + "kind": "subscription token", + "members": [ + { + "role": "acquire", + "name": "Subscribe" + }, + { + "role": "release", + "name": "Dispose" + } + ] + }, + { + "name": "Timer", + "kind": "timer", + "members": [ + { + "role": "acquire", + "name": "Start" + }, + { + "role": "release", + "name": "Stop" + } + ] + }, + { + "name": "Disposable", + "kind": "disposable field", + "members": [ + { + "role": "acquire", + "name": "New" + }, + { + "role": "release", + "name": "Dispose" + } + ] + }, + { + "name": "PooledBuffer", + "kind": "pooled buffer", + "members": [ + { + "role": "acquire", + "name": "Rent" + }, + { + "role": "release", + "name": "Return" + } + ] + } + ], + "externs": [ + { + "name": "$consume", + "params": [ + { + "effect": "consume", + "type": "Disposable" + } + ] + }, + { + "name": "$borrow", + "params": [ + { + "effect": "borrow", + "type": "Disposable" + } + ] + }, + { + "name": "$borrow_mut", + "params": [ + { + "effect": "borrow_mut", + "type": "Disposable" + } + ] + } + ], + "lifetimes": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1iEscapesEntity.Run", + "lifetime": null, + "params": [], + "ret": null, + "body": [ + { + "stmt": "acquire", + "handle": "loc_0", + "resource": "Disposable", + "line": 16 + }, + { + "stmt": "borrow_mut", + "owner": "loc_0", + "binding": "brw_1", + "body": [ + { + "stmt": "acquire", + "handle": "loc_2", + "resource": "Disposable", + "line": 16 + }, + { + "stmt": "use", + "handle": "loc_0", + "line": 18 + }, + { + "stmt": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "loc_2", + "brw_1" + ], + "line": 19 + } + ], + "line": 16 + }, + { + "stmt": "release", + "handle": "loc_0", + "line": 16 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "lifetime": null, + "params": [ + { + "handle": "parg_3", + "type": { + "name": "Disposable", + "borrowed": false, + "mutable": false + }, + "line": 80, + "lifetime": null + }, + { + "handle": "parg_4", + "type": { + "name": "Disposable", + "borrowed": true, + "mutable": true + }, + "line": 80, + "lifetime": null + } + ], + "ret": null, + "body": [ + { + "stmt": "release", + "handle": "parg_3", + "line": 80 + } + ] + } + ], + "handles": [ + { + "handle": "loc_0", + "component": "Own.Protocols.Cases.H1iEscapesEntity.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1i_escapes_entity.cs", + "line": 16, + "event": "order", + "resource": "flow-local", + "ever_released": true, + "pool": false + }, + { + "handle": "loc_2", + "component": "Own.Protocols.Cases.H1iEscapesEntity.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1i_escapes_entity.cs", + "line": 16, + "event": "approved", + "resource": "flow-local", + "ever_released": false, + "pool": false + }, + { + "handle": "parg_3", + "component": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 80, + "event": "token", + "resource": "flow-local", + "ever_released": true + }, + { + "handle": "parg_4", + "component": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 80, + "event": "entity", + "resource": "flow-local", + "ever_released": false + } + ] +} diff --git a/tests/fixtures/lowered/typestate_cs_h1j_mutates_outer_value.facts.json b/tests/fixtures/lowered/typestate_cs_h1j_mutates_outer_value.facts.json new file mode 100644 index 00000000..fe59b0fe --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1j_mutates_outer_value.facts.json @@ -0,0 +1,141 @@ +{ + "ownir_version": 2, + "module": "Extracted", + "components": [], + "services": [], + "functions": [ + { + "name": "Own.Protocols.Cases.H1jMutatesOuterValue.Run", + "file": "frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs", + "body": [ + { + "op": "acquire", + "var": "order", + "line": 18 + }, + { + "op": "borrow_mut", + "owner": "order", + "binding": "order.region1", + "line": 18, + "body": [ + { + "op": "acquire", + "var": "approved", + "line": 18 + }, + { + "op": "proven_call", + "site": "site:frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs:20:13", + "callee": "Own.Protocols.Cases.H1jMutatesOuterValue.Fill(int[])", + "line": 20 + }, + { + "op": "call", + "callee": "Own.Protocols.Sample.ApprovedOrder.Ship", + "args": [ + "approved", + "order.region1" + ], + "line": 21 + } + ] + }, + { + "op": "release", + "var": "order", + "line": 18 + } + ] + }, + { + "name": "Own.Protocols.Sample.ApprovedOrder.Ship", + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "params": [ + { + "name": "token", + "effect": "consume", + "line": 80 + }, + { + "name": "entity", + "effect": "borrow_mut", + "line": 80 + } + ], + "body": [ + { + "op": "release", + "var": "token", + "line": 80 + } + ] + } + ], + "stats": { + "methods_with_local": 0, + "methods_flow_analysed": 0, + "methods_skipped_unmodelled": 0 + }, + "heap_effects": { + "heap_effects_version": 1, + "methods": [ + { + "key": "Own.Protocols.Cases.H1jMutatesOuterValue.Fill(int[])", + "file": "frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs", + "line": 12, + "receiver": false, + "return_inert": true, + "params": [ + { + "index": 0, + "name": "buffer", + "inert": false + } + ], + "locals": [], + "derefs": [], + "writes": [ + { + "kind": "indirect", + "target": [ + "param:0" + ] + } + ], + "stores": [], + "returns": [], + "calls": [], + "unknown": [] + }, + { + "key": "site:frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs:20:13", + "file": "frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs", + "line": 20, + "receiver": false, + "return_inert": true, + "params": [], + "locals": [], + "derefs": [], + "writes": [], + "stores": [], + "returns": [], + "calls": [ + { + "id": 0, + "callee": "Own.Protocols.Cases.H1jMutatesOuterValue.Fill(int[])", + "dispatch": "direct", + "receiver": null, + "args": [ + [ + "heap" + ] + ], + "line": 20 + } + ], + "unknown": [] + } + ] + } +} diff --git a/tests/fixtures/lowered/typestate_cs_h1j_mutates_outer_value.golden.json b/tests/fixtures/lowered/typestate_cs_h1j_mutates_outer_value.golden.json new file mode 100644 index 00000000..2860b257 --- /dev/null +++ b/tests/fixtures/lowered/typestate_cs_h1j_mutates_outer_value.golden.json @@ -0,0 +1,4 @@ +{ + "lowered_version": 2, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1jMutatesOuterValue.Fill(int[])' is not proven harmless: 'Own.Protocols.Cases.H1jMutatesOuterValue.Fill(int[])': parameter 0 is borrow_mut (frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs:20) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/lowered/typestate_cs_l10_region_inside_try.facts.json b/tests/fixtures/lowered/typestate_cs_l10_region_inside_try.facts.json index 7ee861d3..8fd7261a 100644 --- a/tests/fixtures/lowered/typestate_cs_l10_region_inside_try.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l10_region_inside_try.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l11_region_beside_disposable.facts.json b/tests/fixtures/lowered/typestate_cs_l11_region_beside_disposable.facts.json index 6b5588d8..d2162550 100644 --- a/tests/fixtures/lowered/typestate_cs_l11_region_beside_disposable.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l11_region_beside_disposable.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l12_region_beside_leaked_disposable.facts.json b/tests/fixtures/lowered/typestate_cs_l12_region_beside_leaked_disposable.facts.json index 8908084c..f718ea6c 100644 --- a/tests/fixtures/lowered/typestate_cs_l12_region_beside_leaked_disposable.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l12_region_beside_leaked_disposable.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l13_values_captured_into_region.facts.json b/tests/fixtures/lowered/typestate_cs_l13_values_captured_into_region.facts.json index 813bda94..5ddde99e 100644 --- a/tests/fixtures/lowered/typestate_cs_l13_values_captured_into_region.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l13_values_captured_into_region.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l1_stale_capability.facts.json b/tests/fixtures/lowered/typestate_cs_l1_stale_capability.facts.json index 733b1354..44478ef9 100644 --- a/tests/fixtures/lowered/typestate_cs_l1_stale_capability.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l1_stale_capability.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l2_copied_capability.facts.json b/tests/fixtures/lowered/typestate_cs_l2_copied_capability.facts.json index eb4bac95..7b10078e 100644 --- a/tests/fixtures/lowered/typestate_cs_l2_copied_capability.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l2_copied_capability.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l3_raw_mutation.facts.json b/tests/fixtures/lowered/typestate_cs_l3_raw_mutation.facts.json index f625405d..53693795 100644 --- a/tests/fixtures/lowered/typestate_cs_l3_raw_mutation.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l3_raw_mutation.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l4_raw_escape.facts.json b/tests/fixtures/lowered/typestate_cs_l4_raw_escape.facts.json index 0b31942f..2885193b 100644 --- a/tests/fixtures/lowered/typestate_cs_l4_raw_escape.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l4_raw_escape.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l5_normal_transition.facts.json b/tests/fixtures/lowered/typestate_cs_l5_normal_transition.facts.json index 532f9b78..01f3d423 100644 --- a/tests/fixtures/lowered/typestate_cs_l5_normal_transition.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l5_normal_transition.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l6_two_transitions.facts.json b/tests/fixtures/lowered/typestate_cs_l6_two_transitions.facts.json index a67ac375..dccf3718 100644 --- a/tests/fixtures/lowered/typestate_cs_l6_two_transitions.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l6_two_transitions.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l6b_chained_transitions.facts.json b/tests/fixtures/lowered/typestate_cs_l6b_chained_transitions.facts.json index f4a08ce2..987035ce 100644 --- a/tests/fixtures/lowered/typestate_cs_l6b_chained_transitions.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l6b_chained_transitions.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l7_read_after_region.facts.json b/tests/fixtures/lowered/typestate_cs_l7_read_after_region.facts.json index 29500f8c..2789fe51 100644 --- a/tests/fixtures/lowered/typestate_cs_l7_read_after_region.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l7_read_after_region.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l8_branch_inside_region.facts.json b/tests/fixtures/lowered/typestate_cs_l8_branch_inside_region.facts.json index 3aadeee4..9039920b 100644 --- a/tests/fixtures/lowered/typestate_cs_l8_branch_inside_region.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l8_branch_inside_region.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_l9_opaque_calls_around_region.facts.json b/tests/fixtures/lowered/typestate_cs_l9_opaque_calls_around_region.facts.json index ffe52534..86bfb23c 100644 --- a/tests/fixtures/lowered/typestate_cs_l9_opaque_calls_around_region.facts.json +++ b/tests/fixtures/lowered/typestate_cs_l9_opaque_calls_around_region.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_cs_x1_nested_region_same_entity.facts.json b/tests/fixtures/lowered/typestate_cs_x1_nested_region_same_entity.facts.json index 678406a7..fb31ddc8 100644 --- a/tests/fixtures/lowered/typestate_cs_x1_nested_region_same_entity.facts.json +++ b/tests/fixtures/lowered/typestate_cs_x1_nested_region_same_entity.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_ef_orderbackend.facts.json b/tests/fixtures/lowered/typestate_ef_orderbackend.facts.json index 4b0f69b4..2431be23 100644 --- a/tests/fixtures/lowered/typestate_ef_orderbackend.facts.json +++ b/tests/fixtures/lowered/typestate_ef_orderbackend.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "services": [], diff --git a/tests/fixtures/lowered/typestate_g6_capability_not_spent.facts.json b/tests/fixtures/lowered/typestate_g6_capability_not_spent.facts.json index a8375c28..0e4c473f 100644 --- a/tests/fixtures/lowered/typestate_g6_capability_not_spent.facts.json +++ b/tests/fixtures/lowered/typestate_g6_capability_not_spent.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_l1_stale_capability.facts.json b/tests/fixtures/lowered/typestate_l1_stale_capability.facts.json index 4331c126..febcdfec 100644 --- a/tests/fixtures/lowered/typestate_l1_stale_capability.facts.json +++ b/tests/fixtures/lowered/typestate_l1_stale_capability.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_l2_copied_capability.facts.json b/tests/fixtures/lowered/typestate_l2_copied_capability.facts.json index 6e627b7c..59de0e11 100644 --- a/tests/fixtures/lowered/typestate_l2_copied_capability.facts.json +++ b/tests/fixtures/lowered/typestate_l2_copied_capability.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_l3_raw_entity_mutation.facts.json b/tests/fixtures/lowered/typestate_l3_raw_entity_mutation.facts.json index 94ddaf0e..633d1666 100644 --- a/tests/fixtures/lowered/typestate_l3_raw_entity_mutation.facts.json +++ b/tests/fixtures/lowered/typestate_l3_raw_entity_mutation.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_l3b_second_region.facts.json b/tests/fixtures/lowered/typestate_l3b_second_region.facts.json index 07033b31..beb30a7e 100644 --- a/tests/fixtures/lowered/typestate_l3b_second_region.facts.json +++ b/tests/fixtures/lowered/typestate_l3b_second_region.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_l4_raw_entity_unknown_call.facts.json b/tests/fixtures/lowered/typestate_l4_raw_entity_unknown_call.facts.json index e1f9d18e..9038a934 100644 --- a/tests/fixtures/lowered/typestate_l4_raw_entity_unknown_call.facts.json +++ b/tests/fixtures/lowered/typestate_l4_raw_entity_unknown_call.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_l4b_raw_entity_shared_call.facts.json b/tests/fixtures/lowered/typestate_l4b_raw_entity_shared_call.facts.json index 2f8aeefa..c0d377a5 100644 --- a/tests/fixtures/lowered/typestate_l4b_raw_entity_shared_call.facts.json +++ b/tests/fixtures/lowered/typestate_l4b_raw_entity_shared_call.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_l4c_raw_entity_consumed.facts.json b/tests/fixtures/lowered/typestate_l4c_raw_entity_consumed.facts.json index 3707b5d2..43dfeec4 100644 --- a/tests/fixtures/lowered/typestate_l4c_raw_entity_consumed.facts.json +++ b/tests/fixtures/lowered/typestate_l4c_raw_entity_consumed.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_l4d_token_unknown_call.facts.json b/tests/fixtures/lowered/typestate_l4d_token_unknown_call.facts.json index cd2b9b63..d3946825 100644 --- a/tests/fixtures/lowered/typestate_l4d_token_unknown_call.facts.json +++ b/tests/fixtures/lowered/typestate_l4d_token_unknown_call.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_l5_normal_transition.facts.json b/tests/fixtures/lowered/typestate_l5_normal_transition.facts.json index d3b4e286..9ef01908 100644 --- a/tests/fixtures/lowered/typestate_l5_normal_transition.facts.json +++ b/tests/fixtures/lowered/typestate_l5_normal_transition.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_l5b_two_transitions.facts.json b/tests/fixtures/lowered/typestate_l5b_two_transitions.facts.json index 295e58c9..d41d66a5 100644 --- a/tests/fixtures/lowered/typestate_l5b_two_transitions.facts.json +++ b/tests/fixtures/lowered/typestate_l5b_two_transitions.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_l5c_read_after_region.facts.json b/tests/fixtures/lowered/typestate_l5c_read_after_region.facts.json index d43777d7..af017433 100644 --- a/tests/fixtures/lowered/typestate_l5c_read_after_region.facts.json +++ b/tests/fixtures/lowered/typestate_l5c_read_after_region.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_n1_token_spent_on_other_entity.facts.json b/tests/fixtures/lowered/typestate_n1_token_spent_on_other_entity.facts.json index d1dc9fc4..39fea2db 100644 --- a/tests/fixtures/lowered/typestate_n1_token_spent_on_other_entity.facts.json +++ b/tests/fixtures/lowered/typestate_n1_token_spent_on_other_entity.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_n2_two_tokens_one_region.facts.json b/tests/fixtures/lowered/typestate_n2_two_tokens_one_region.facts.json index afa9543a..2d27e9b1 100644 --- a/tests/fixtures/lowered/typestate_n2_two_tokens_one_region.facts.json +++ b/tests/fixtures/lowered/typestate_n2_two_tokens_one_region.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_n3_raw_mutation_inferred_effect.facts.json b/tests/fixtures/lowered/typestate_n3_raw_mutation_inferred_effect.facts.json index f0f679db..87499d26 100644 --- a/tests/fixtures/lowered/typestate_n3_raw_mutation_inferred_effect.facts.json +++ b/tests/fixtures/lowered/typestate_n3_raw_mutation_inferred_effect.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_n4_token_outlives_region.facts.json b/tests/fixtures/lowered/typestate_n4_token_outlives_region.facts.json index dca24eb8..a6ebc743 100644 --- a/tests/fixtures/lowered/typestate_n4_token_outlives_region.facts.json +++ b/tests/fixtures/lowered/typestate_n4_token_outlives_region.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_w1_loan_wordings.facts.json b/tests/fixtures/lowered/typestate_w1_loan_wordings.facts.json index 41bfc219..d499f516 100644 --- a/tests/fixtures/lowered/typestate_w1_loan_wordings.facts.json +++ b/tests/fixtures/lowered/typestate_w1_loan_wordings.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/typestate_w2_loan_wordings_pooled.facts.json b/tests/fixtures/lowered/typestate_w2_loan_wordings_pooled.facts.json index 113a898f..c20a8e28 100644 --- a/tests/fixtures/lowered/typestate_w2_loan_wordings_pooled.facts.json +++ b/tests/fixtures/lowered/typestate_w2_loan_wordings_pooled.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TypestateGate", "functions": [ { diff --git a/tests/fixtures/lowered/vocab_unknown_op.facts.json b/tests/fixtures/lowered/vocab_unknown_op.facts.json index f091a7fc..05f1c9e8 100644 --- a/tests/fixtures/lowered/vocab_unknown_op.facts.json +++ b/tests/fixtures/lowered/vocab_unknown_op.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Vocab", "functions": [ { diff --git a/tests/fixtures/ownir/capture.facts.json b/tests/fixtures/ownir/capture.facts.json index 5ff5b528..bf30ffd3 100644 --- a/tests/fixtures/ownir/capture.facts.json +++ b/tests/fixtures/ownir/capture.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "WpfApp", "components": [ { diff --git a/tests/fixtures/ownir/contract_inference.facts.json b/tests/fixtures/ownir/contract_inference.facts.json index b7704a95..5ee17a78 100644 --- a/tests/fixtures/ownir/contract_inference.facts.json +++ b/tests/fixtures/ownir/contract_inference.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "InferBridge", "functions": [ { diff --git a/tests/fixtures/ownir/di.facts.json b/tests/fixtures/ownir/di.facts.json index 53a90c0e..7d0e09f0 100644 --- a/tests/fixtures/ownir/di.facts.json +++ b/tests/fixtures/ownir/di.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DiDemo", "components": [], "services": [ diff --git a/tests/fixtures/ownir/di_capture.facts.json b/tests/fixtures/ownir/di_capture.facts.json index c5f0f536..5069f387 100644 --- a/tests/fixtures/ownir/di_capture.facts.json +++ b/tests/fixtures/ownir/di_capture.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DiZombie", "components": [ { diff --git a/tests/fixtures/ownir/disposable.facts.json b/tests/fixtures/ownir/disposable.facts.json index b5e87e10..a240170f 100644 --- a/tests/fixtures/ownir/disposable.facts.json +++ b/tests/fixtures/ownir/disposable.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "WpfDisposables", "components": [ { diff --git a/tests/fixtures/ownir/flow_column_anchors.facts.json b/tests/fixtures/ownir/flow_column_anchors.facts.json index b0990a35..6f7a425f 100644 --- a/tests/fixtures/ownir/flow_column_anchors.facts.json +++ b/tests/fixtures/ownir/flow_column_anchors.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "ColumnAnchors", "_doc": [ "Own.NET#317: the optional 1-based `column` on the finding-anchor path.", diff --git a/tests/fixtures/ownir/flow_finally_switch.facts.json b/tests/fixtures/ownir/flow_finally_switch.facts.json index bf285a54..46584b70 100644 --- a/tests/fixtures/ownir/flow_finally_switch.facts.json +++ b/tests/fixtures/ownir/flow_finally_switch.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "comment": "IR the extractor now emits for finally-before-return and switch lowering. (1) FinallyReturnClean: a `return` inside try-with-finally runs the finally (release r) FIRST, so r is released on the return path -> silent (was bailed before). (2) FinallyReturnLeak: an early return with the dispose AFTER the try (empty finally) leaks on that path. (3) SwitchAllDispose: a no-default switch where every case disposes — modelled with the last case as the tail (no empty no-match branch), so it stays silent (Model A: no phantom-leak FP on an exhaustive switch). (4) SwitchOneLeak: a switch whose default/else branch leaks.", "components": [], diff --git a/tests/fixtures/ownir/flow_leak_on_else.facts.json b/tests/fixtures/ownir/flow_leak_on_else.facts.json index 38ac668d..b4a96e17 100644 --- a/tests/fixtures/ownir/flow_leak_on_else.facts.json +++ b/tests/fixtures/ownir/flow_leak_on_else.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "functions": [ diff --git a/tests/fixtures/ownir/flow_leak_two_exits.facts.json b/tests/fixtures/ownir/flow_leak_two_exits.facts.json index bdfdbc90..2101eb3f 100644 --- a/tests/fixtures/ownir/flow_leak_two_exits.facts.json +++ b/tests/fixtures/ownir/flow_leak_two_exits.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "functions": [ diff --git a/tests/fixtures/ownir/flow_nested_throw.facts.json b/tests/fixtures/ownir/flow_nested_throw.facts.json index dd988b71..e21f1fb2 100644 --- a/tests/fixtures/ownir/flow_nested_throw.facts.json +++ b/tests/fixtures/ownir/flow_nested_throw.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "comment": "Exception-edge RECALL slice: the IR the extractor now emits for three try shapes. (1) NestedThrowLeaks: the throw edge recurses into the `if` and lands before MayThrow() (a nested LEAF), where nestedLeak is still owned -> leaks. (2) DisposeInsideIfWithThrow: the same recursion, but the dispose precedes the throw in each branch, so cif is already released at the edge -> silent. (3) CtorThrowLeaksPrior: a `new` is a throw point; the edge before `var ctorLater = new ...` finds ctorPrior owned -> leaks, while ctorLater (acquired after the edge) is silent.", "components": [], diff --git a/tests/fixtures/ownir/flow_pool_partial.facts.json b/tests/fixtures/ownir/flow_pool_partial.facts.json index 312f2987..233e5b81 100644 --- a/tests/fixtures/ownir/flow_pool_partial.facts.json +++ b/tests/fixtures/ownir/flow_pool_partial.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "comment": "Pool buffers on the FLOW path must read as a 'pooled buffer' (Return wording / [resource: pooled buffer]), not the generic 'disposable' — the extractor stamps the acquire kind 'pool' for an ArrayPool Rent so the bridge words it right. (1) PartialPoolLeak: a Rent returned on the fall-through but NOT on the throw edge -> 'may not be returned to the pool on every path'. (2) NeverReturnedPool: a Rent never returned -> 'rented but never returned to the pool'. (3) DisposableControl: a plain disposable on the same partial shape keeps the IDisposable wording. Regression for the flow-path pool mislabel surfaced by the --body-throw-edges Npgsql capstone (CompositeBuilder/BitStringConverters ArrayPool rents).", "components": [], diff --git a/tests/fixtures/ownir/flow_while.facts.json b/tests/fixtures/ownir/flow_while.facts.json index b080c970..c75fe8e8 100644 --- a/tests/fixtures/ownir/flow_while.facts.json +++ b/tests/fixtures/ownir/flow_while.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "functions": [ diff --git a/tests/fixtures/ownir/handoff_contract.facts.json b/tests/fixtures/ownir/handoff_contract.facts.json index 31f7ede0..1f84733a 100644 --- a/tests/fixtures/ownir/handoff_contract.facts.json +++ b/tests/fixtures/ownir/handoff_contract.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "HandoffBridge", "functions": [ { diff --git a/tests/fixtures/ownir/local_disposable.facts.json b/tests/fixtures/ownir/local_disposable.facts.json index d4db5f31..65f25251 100644 --- a/tests/fixtures/ownir/local_disposable.facts.json +++ b/tests/fixtures/ownir/local_disposable.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Streams", "components": [ { diff --git a/tests/fixtures/ownir/pool.facts.json b/tests/fixtures/ownir/pool.facts.json index 02b261d3..9641b4c3 100644 --- a/tests/fixtures/ownir/pool.facts.json +++ b/tests/fixtures/ownir/pool.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "PoolApp", "components": [ { diff --git a/tests/fixtures/ownir/protocol_isloaded_clean.facts.json b/tests/fixtures/ownir/protocol_isloaded_clean.facts.json index d6655206..a94d7e5b 100644 --- a/tests/fixtures/ownir/protocol_isloaded_clean.facts.json +++ b/tests/fixtures/ownir/protocol_isloaded_clean.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "protocols": [ diff --git a/tests/fixtures/ownir/protocol_isloaded_violation.facts.json b/tests/fixtures/ownir/protocol_isloaded_violation.facts.json index 0daae80f..c75fd841 100644 --- a/tests/fixtures/ownir/protocol_isloaded_violation.facts.json +++ b/tests/fixtures/ownir/protocol_isloaded_violation.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "protocols": [ diff --git a/tests/fixtures/ownir/sample.facts.json b/tests/fixtures/ownir/sample.facts.json index 81bbac18..a9ea3440 100644 --- a/tests/fixtures/ownir/sample.facts.json +++ b/tests/fixtures/ownir/sample.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "WpfApp", "components": [ { diff --git a/tests/fixtures/ownir/subscribe.facts.json b/tests/fixtures/ownir/subscribe.facts.json index 61ec1a06..a7e7bcc6 100644 --- a/tests/fixtures/ownir/subscribe.facts.json +++ b/tests/fixtures/ownir/subscribe.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "WpfMessenger", "components": [ { diff --git a/tests/fixtures/ownir/timer.facts.json b/tests/fixtures/ownir/timer.facts.json index d0e257d6..59c3d7eb 100644 --- a/tests/fixtures/ownir/timer.facts.json +++ b/tests/fixtures/ownir/timer.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "WpfTimers", "components": [ { diff --git a/tests/fixtures/ownir/unitofwork_flow.facts.json b/tests/fixtures/ownir/unitofwork_flow.facts.json index 217885de..00a419cc 100644 --- a/tests/fixtures/ownir/unitofwork_flow.facts.json +++ b/tests/fixtures/ownir/unitofwork_flow.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "functions": [ diff --git a/tests/fixtures/ownir/unresolved.facts.json b/tests/fixtures/ownir/unresolved.facts.json index 6a420b51..904730a0 100644 --- a/tests/fixtures/ownir/unresolved.facts.json +++ b/tests/fixtures/ownir/unresolved.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "TierA", "components": [ { diff --git a/tests/fixtures/ownir_validation.json b/tests/fixtures/ownir_validation.json index b90bbffd..01e8c872 100644 --- a/tests/fixtures/ownir_validation.json +++ b/tests/fixtures/ownir_validation.json @@ -41,7 +41,7 @@ "why": "the current version stated explicitly", "section": "version", "document": { - "ownir_version": 1 + "ownir_version": 2 }, "raw": false, "verdict": "accept", @@ -53,7 +53,7 @@ "why": "every known section present but empty — shape-valid, nothing to check", "section": "root", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [], "services": [], "effects": [], @@ -71,7 +71,7 @@ "why": "an unrecognised TOP-LEVEL key is additive and accepted; the strict door gates known vocabulary, it is not a closed-world schema", "section": "root", "document": { - "ownir_version": 1, + "ownir_version": 2, "future_section": [ { "whatever": 1 @@ -88,7 +88,7 @@ "why": "a subscription with no `resource` defaults to 'subscription', which is a known kind", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -107,7 +107,7 @@ "why": "all eight known kinds in one document — the acceptance side of the closed vocabulary", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -149,7 +149,7 @@ "why": "column 1 is the smallest legal column — the boundary just inside the 1-based contract", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -170,7 +170,7 @@ "why": "all three DI lifetimes accepted", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "A", @@ -196,7 +196,7 @@ "why": "all four parameter effects accepted", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -230,7 +230,7 @@ "why": "`effect` is optional — absent is not the same as an unknown value", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -300,7 +300,7 @@ "raw": false, "verdict": "reject", "category": "version", - "message": "OwnIR facts are schema v99, but this core understands v1. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it." + "message": "OwnIR facts are schema v99, but this core understands v2. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it." }, { "name": "version-string", @@ -355,7 +355,7 @@ "why": "`components` must be an array", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": { "a": 1 } @@ -370,7 +370,7 @@ "why": "an array, but not of objects", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ 1, 2 @@ -386,7 +386,7 @@ "why": "each component's `subscriptions` must be an array of objects", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": 7 @@ -403,7 +403,7 @@ "why": "…of OBJECTS, not scalars", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -422,7 +422,7 @@ "why": "`resource` must be a string before its value can be checked", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -443,7 +443,7 @@ "why": "IR4: a present-but-unknown kind changes routing, so it is rejected at the door rather than mis-routed. A new kind must bump OWNIR_VERSION", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -464,7 +464,7 @@ "why": "the empty string is present-but-unknown, not absent", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -485,7 +485,7 @@ "why": "optional `type`, present ⇒ string", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -506,7 +506,7 @@ "why": "optional `source_type`, present ⇒ string", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -527,7 +527,7 @@ "why": "optional `source_provenance`, present ⇒ string", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -548,7 +548,7 @@ "why": "optional `ignore_reason`, present ⇒ string", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -569,7 +569,7 @@ "why": "#317: a column is 1-based or absent. `0` is a producer bug, and reading it as 'unknown' would hide the bug while looking correct", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -590,7 +590,7 @@ "why": "…and so is a negative column", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -611,7 +611,7 @@ "why": "the bool-is-int trap again: `True` would otherwise be accepted as column 1 — a fabricated coordinate. `shape`, not `location`: a bool has no integer form, so the 1-based rule never gets a value to judge", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -632,7 +632,7 @@ "why": "a string column has no integer form either — same axis, and the reference funnels it through the same message", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -653,7 +653,7 @@ "why": "`services` must be an array of objects", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": { "a": 1 } @@ -668,7 +668,7 @@ "why": "the DI lifetime is a closed set", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -686,7 +686,7 @@ "why": "the service name is the identity the DI graph joins on", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "", @@ -704,7 +704,7 @@ "why": "…and it must be a string", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": 7, @@ -722,7 +722,7 @@ "why": "`deps` is an array of strings", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -741,7 +741,7 @@ "why": "…of STRINGS", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -762,7 +762,7 @@ "why": "same for `weak_deps`", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -783,7 +783,7 @@ "why": "same for `root_resolves`", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -804,7 +804,7 @@ "why": "same for `scope_cached`", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -825,7 +825,7 @@ "why": "`file` is a string", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -844,7 +844,7 @@ "why": "`line` is an integer", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -863,7 +863,7 @@ "why": "…and a bool is not an integer", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -882,7 +882,7 @@ "why": "`ctor_file` is a string", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -901,7 +901,7 @@ "why": "`ctor_line` is an integer", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -920,7 +920,7 @@ "why": "`ctor_type` is a string", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -939,7 +939,7 @@ "why": "`root_resolve_sites` is an array of {type,file,line} objects", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -960,7 +960,7 @@ "why": "same for `scope_cache_sites`", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -981,7 +981,7 @@ "why": "`effects` must be an array of objects", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": { "a": 1 } @@ -996,7 +996,7 @@ "why": "`deps` is an array of strings", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "deps": [ @@ -1015,7 +1015,7 @@ "why": "`io` is a boolean", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "io": "yes" @@ -1032,7 +1032,7 @@ "why": "`line` is an integer", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "line": "3" @@ -1049,7 +1049,7 @@ "why": "`bindings` is an array of objects", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "bindings": [ @@ -1068,7 +1068,7 @@ "why": "binding `name` is a string", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "bindings": [ @@ -1089,7 +1089,7 @@ "why": "binding `init` is a string", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "bindings": [ @@ -1110,7 +1110,7 @@ "why": "binding `refs` is string array", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "bindings": [ @@ -1133,7 +1133,7 @@ "why": "binding `line` is an integer", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "bindings": [ @@ -1154,7 +1154,7 @@ "why": "`functions` must be an array of objects", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": { "a": 1 } @@ -1169,7 +1169,7 @@ "why": "`sig` present ⇒ string. It is the overload key MOS resolution joins on, so a non-string is not a cosmetic problem", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "sig": 7 @@ -1186,7 +1186,7 @@ "why": "`params` is an array of objects", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": "x" @@ -1203,7 +1203,7 @@ "why": "…of OBJECTS", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -1222,7 +1222,7 @@ "why": "the parameter name is the identity effects attach to", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -1243,7 +1243,7 @@ "why": "…and it must be a string", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -1264,7 +1264,7 @@ "why": "param `line` is an integer", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -1286,7 +1286,7 @@ "why": "the parameter effect is a closed set", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -1308,7 +1308,7 @@ "why": "`protocols` must be an array of objects", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": { "a": 1 } @@ -1323,7 +1323,7 @@ "why": "the protocol name is the identity verdicts map back by, so a duplicate is an identity collision, not a harmless repeat. Both records are individually VALID — the older version of this control used records with no `opens`/`closes`, which the reference refused for record shape long before it compared any names", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -1363,7 +1363,7 @@ "why": "`protocol_functions` must be an array of objects", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": { "a": 1 } @@ -1386,7 +1386,7 @@ "raw": false, "verdict": "reject", "category": "version", - "message": "OwnIR facts are schema v99, but this core understands v1. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it." + "message": "OwnIR facts are schema v99, but this core understands v2. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it." }, { "name": "order-version-before-resource", @@ -1407,7 +1407,7 @@ "raw": false, "verdict": "reject", "category": "version", - "message": "OwnIR facts are schema v99, but this core understands v1. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it." + "message": "OwnIR facts are schema v99, but this core understands v2. Build the Roslyn extractor and the Python core from the same commit — the OwnIR fact vocabulary changed between the version that produced this file and the one reading it." }, { "name": "order-root-before-version", @@ -1438,7 +1438,7 @@ "why": "`resource` must be a STRING before its value can be tested against the closed set — a shape failure, not a vocabulary one", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -1460,7 +1460,7 @@ "why": "sections are validated in declaration order: `components` before `services`, so a document breaking both reports components", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": { "a": 1 }, @@ -1478,7 +1478,7 @@ "why": "there is no default lifetime: an absent one is `None`, which is outside the closed set exactly like a misspelt one. This is the case `_svc()` could not express, and the port accepted it", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S" @@ -1495,7 +1495,7 @@ "why": "a service record with nothing in it: the lifetime gate fires first, so this is a vocabulary failure and not a missing-name one", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ {} ] @@ -1510,7 +1510,7 @@ "why": "an explicit null is the same as absent here — both are `None`, and neither is in the closed set", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -1528,7 +1528,7 @@ "why": "with a valid lifetime, an absent name reaches the identity check", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "lifetime": "singleton" @@ -1545,7 +1545,7 @@ "why": "the reference checks `lifetime` BEFORE `name`, so a record that breaks both is a vocabulary failure. A port that validates identity first reports `identity` and is wrong about which rule fired", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "", @@ -1563,7 +1563,7 @@ "why": "…and `name` before the remaining service fields", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "lifetime": "singleton", @@ -1582,7 +1582,7 @@ "why": "within one subscription, the resource vocabulary precedes the column contract", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -1604,7 +1604,7 @@ "why": "…and the column precedes the optional `type`", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -1626,7 +1626,7 @@ "why": "inside a function, `sig` is checked before the body's columns", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "sig": 7, @@ -1649,7 +1649,7 @@ "why": "and the BODY's columns are checked before `params` — the least obvious edge in the whole door, because params read like the more primitive thing", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -1676,7 +1676,7 @@ "why": "within a param, identity precedes the line", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -1698,7 +1698,7 @@ "why": "…the line precedes the column", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -1721,7 +1721,7 @@ "why": "…and the column precedes the effect vocabulary", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -1744,7 +1744,7 @@ "why": "a components SHAPE failure outranks a services VOCABULARY failure, because components is validated first — completely. A door that runs all semantic gates before any shape check reports the vocabulary error and inverts the contract", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": { "a": 1 }, @@ -1764,7 +1764,7 @@ "why": "same precedence with a column failure standing in for the shape one", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -1790,7 +1790,7 @@ "why": "and the same one section later: services before effects", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "lifetime": "bad" @@ -1810,7 +1810,7 @@ "why": "effects before functions", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": { "a": 1 }, @@ -1834,7 +1834,7 @@ "why": "functions before protocols", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -1856,7 +1856,7 @@ "why": "protocols before protocol_functions — the last edge in the chain", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "" @@ -1874,7 +1874,7 @@ "why": "column 1 on a flow op, nested and not — the acceptance twin the rejections below need", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -1920,7 +1920,7 @@ "why": "a non-array `body` is SKIPPED, not rejected: the reference returns early rather than raising. Pinned because it is the kind of tolerance a port silently tightens", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": 7 @@ -1937,7 +1937,7 @@ "why": "…and a non-object op inside the body is skipped the same way", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -1958,7 +1958,7 @@ "why": "the 1-based contract reaches flow ops, not just subscriptions", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -1980,7 +1980,7 @@ "why": "…negative likewise", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -2002,7 +2002,7 @@ "why": "…and the bool-is-int trap, which is a representability failure wherever it appears", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -2024,7 +2024,7 @@ "why": "recursion into `then` — a hoisted branch acquire", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -2051,7 +2051,7 @@ "why": "…into `else`", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -2078,7 +2078,7 @@ "why": "…into a loop `body`", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -2105,7 +2105,7 @@ "why": "…and through three levels, so a one-level-deep port fails here", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -2142,7 +2142,7 @@ "why": "the 1-based boundary on a parameter coordinate", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -2164,7 +2164,7 @@ "why": "the same contract on `params[].column` — a separate call site in the reference, and one the port did not have at all", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -2186,7 +2186,7 @@ "why": "…negative likewise", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -2208,7 +2208,7 @@ "why": "…and the bool-is-int trap on the third call site", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -2230,7 +2230,7 @@ "why": "…and a string, which has no integer form to be 1-based about", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -2252,7 +2252,7 @@ "why": "a name plus an opens/closes pair is a complete protocol", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2279,7 +2279,7 @@ "why": "every optional key at once: barriers, allow with narrowed args, an explicit scope, a description, and `exit_barriers` false — legal only BECAUSE a barrier is present", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2328,7 +2328,7 @@ "why": "the other matcher kind: `call`, with and without narrowed args", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2357,7 +2357,7 @@ "why": "two protocols with DIFFERENT names — the twin that makes the duplicate-name rejection discriminating rather than a test of 'more than one protocol is refused'", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "A", @@ -2397,7 +2397,7 @@ "why": "`protocols` is checked only for LIST-ness at the top; a scalar entry is refused by the record parser", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ 7 ] @@ -2412,7 +2412,7 @@ "why": "…and null is not a record", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ null ] @@ -2427,7 +2427,7 @@ "why": "the protocol name is required, not defaulted", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "opens": {}, @@ -2445,7 +2445,7 @@ "why": "…and must be non-empty", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "", @@ -2472,7 +2472,7 @@ "why": "…and a string", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": 7, @@ -2499,7 +2499,7 @@ "why": "a protocol without `opens` cannot state what it is tracking", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2520,7 +2520,7 @@ "why": "…and likewise `closes`", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2541,7 +2541,7 @@ "why": "a matcher is an object", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2564,7 +2564,7 @@ "why": "the matcher kind is a closed vocabulary (assign | call), fail-loud like a flow op", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2590,7 +2590,7 @@ "why": "…and absent is outside that set too", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2615,7 +2615,7 @@ "why": "the assign target is the member name the rule joins events by", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2642,7 +2642,7 @@ "why": "an opens/closes assign matcher must state the written boolean — 'any write opens' is not a checkable protocol", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2668,7 +2668,7 @@ "why": "…and that value is a boolean", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2695,7 +2695,7 @@ "why": "the callee is the name a call event joins by", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2721,7 +2721,7 @@ "why": "narrowed args are strings", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2750,7 +2750,7 @@ "why": "`barriers` is an array", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2778,7 +2778,7 @@ "why": "`allow` is an array", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2806,7 +2806,7 @@ "why": "`exit_barriers` is a boolean", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2834,7 +2834,7 @@ "why": "no barriers AND no exit barriers: the rule can structurally never fire, which the reference refuses as decoration. Every value here is correctly typed and in vocabulary — what fails is meaning, so the category is `well_formedness`", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2862,7 +2862,7 @@ "why": "a barrier identical to `opens` is dead — the walk checks opens first, so the barrier can never fire. Same category, different mechanism: the record is well-typed and means nothing", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2896,7 +2896,7 @@ "why": "`exit_barriers: false` is legal WITH a barrier — the twin that makes `protocol-never-fires` a rejection about meaning rather than a rejection of the field", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2930,7 +2930,7 @@ "why": "…and a barrier that is not `opens` is legal, which is what makes the equality the defect rather than the presence", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2964,7 +2964,7 @@ "why": "`scope` is an object", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -2992,7 +2992,7 @@ "why": "`scope.methods` is an array — a CONTAINER failure", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -3022,7 +3022,7 @@ "why": "…of non-empty method names. The reference raises one message for this and the case above; the ledger separates them because a missing container and an unusable name are different defects", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -3054,7 +3054,7 @@ "why": "`description` is a string", "section": "protocols", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -3082,7 +3082,7 @@ "why": "the name is read before `opens`/`closes` are required, so a record missing everything reports identity", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "" @@ -3099,7 +3099,7 @@ "why": "`opens` is parsed before `closes`", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": [ { "name": "P", @@ -3120,7 +3120,7 @@ "why": "`events` defaults to empty, so a name alone is a valid record", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M" @@ -3137,7 +3137,7 @@ "why": "all six event kinds including the two recursive ones — the acceptance side of the closed `ev` vocabulary", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3213,7 +3213,7 @@ "why": "like `protocols`, only list-ness is checked at the top", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ 7 ] @@ -3228,7 +3228,7 @@ "why": "…and null is not a record", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ null ] @@ -3243,7 +3243,7 @@ "why": "the method name is what a protocol's scope matches against", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "" @@ -3260,7 +3260,7 @@ "why": "…and it is required", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "file": "a.cs" @@ -3277,7 +3277,7 @@ "why": "`file` is optional but, present, a string", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3295,7 +3295,7 @@ "why": "`events` is an ordered array", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3313,7 +3313,7 @@ "why": "…of objects", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3333,7 +3333,7 @@ "why": "the `ev` discriminator is closed (IR4): a present-but-unknown value is rejected, never skipped", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3355,7 +3355,7 @@ "why": "…and an absent one is outside the set too", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3377,7 +3377,7 @@ "why": "an event line is an integer", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3400,7 +3400,7 @@ "why": "…and the bool-is-int trap reaches here as well", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3423,7 +3423,7 @@ "why": "an assign event's target is a name slot", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3446,7 +3446,7 @@ "why": "…its value is a boolean or absent (absent = an opaque write)", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3470,7 +3470,7 @@ "why": "a call event's callee is a name slot", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3493,7 +3493,7 @@ "why": "…its distinguished arg is a string or absent", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3517,7 +3517,7 @@ "why": "the event vocabulary is enforced recursively — inside `then`", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3544,7 +3544,7 @@ "why": "…inside `else`", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3571,7 +3571,7 @@ "why": "…and inside a loop body", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3598,7 +3598,7 @@ "why": "…through three levels, so a one-level-deep port fails here", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3631,7 +3631,7 @@ "why": "the `ev` vocabulary is tested before the line", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3654,7 +3654,7 @@ "why": "…and the line before the per-kind fields", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -3678,7 +3678,7 @@ "why": "a present null is not an absent section", "section": "root", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": null }, "raw": false, @@ -3691,7 +3691,7 @@ "why": "…same for services", "section": "root", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": null }, "raw": false, @@ -3704,7 +3704,7 @@ "why": "…effects", "section": "root", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": null }, "raw": false, @@ -3717,7 +3717,7 @@ "why": "…functions", "section": "root", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": null }, "raw": false, @@ -3730,7 +3730,7 @@ "why": "…protocols", "section": "root", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocols": null }, "raw": false, @@ -3743,7 +3743,7 @@ "why": "…and protocol_functions", "section": "root", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": null }, "raw": false, @@ -3756,7 +3756,7 @@ "why": "…and one level down", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": null @@ -3773,7 +3773,7 @@ "why": "…likewise params", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": null @@ -3790,7 +3790,7 @@ "why": "…and a null string array", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -3809,7 +3809,7 @@ "why": "…and null bindings", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "bindings": null @@ -3826,7 +3826,7 @@ "why": "a null scalar is not an absent scalar either", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -3845,7 +3845,7 @@ "why": "…same for a string scalar", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -3864,7 +3864,7 @@ "why": "…and `resource` null fails the string check before the vocabulary", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -3885,7 +3885,7 @@ "why": "the column is the exception: the reference returns early on None, so an explicit null IS accepted where a null line is not", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -3906,7 +3906,7 @@ "why": "…and a null effect is read as absent, not as an unknown value", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -3928,7 +3928,7 @@ "why": "…and a null `sig` is accepted, because the check is `is not None`", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "sig": null @@ -3945,7 +3945,7 @@ "why": "well-formed DI004/DI005 call-site metadata", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -3977,7 +3977,7 @@ "why": "every site field is defaulted, so `{}` is a legal site", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -3998,7 +3998,7 @@ "why": "the bool-is-int trap inside a site record", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4021,7 +4021,7 @@ "why": "…and a site `type` is a string", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4044,7 +4044,7 @@ "why": "…both site arrays carry the same contract", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4067,7 +4067,7 @@ "why": "the largest REPRESENTABLE line — accepted until the coordinate domain existed, now outside it. Representability and domain are two axes: this value still HAS a signed-64 form, which is exactly why it is `location` and not `shape`", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4086,7 +4086,7 @@ "why": "…and the smallest. The range is still closed at BOTH ends and a port that bounded only the top would pass a one-sided test — the ends have simply moved from the form to the domain", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4105,7 +4105,7 @@ "why": "…and the largest column, which now carries the same upper bound a line does", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -4126,7 +4126,7 @@ "why": "a negative line is REJECTED: it is not the 1-based column rule borrowed, it is the line's own domain — no producer emits one and nothing downstream can point at it (spec/OwnIR.md §4.2)", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4145,7 +4145,7 @@ "why": "…and zero is still the line default, unchanged: it means 'unknown / file-level' and is the bottom of the domain, not an edge case that survived", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4164,7 +4164,7 @@ "why": "one below the range: no representable signed-64 form", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4183,7 +4183,7 @@ "why": "…and one above. This is the value that used to escape into serde: it is still an integer to the parser, so a raw-layer check written as 'is it an integer' waves it through and the typed model refuses it afterwards — a rule living in the model instead of the door", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4202,7 +4202,7 @@ "why": "…the top of the band that is still integer-shaped to the parser", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4221,7 +4221,7 @@ "why": "…and past it, where the parser gives up on integer-ness entirely. Same verdict, same category, different route: the taxonomy must not be able to tell these apart", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4240,7 +4240,7 @@ "why": "a float is not a representable coordinate even when it is whole — and it lands in the same branch as `line-above-u64`, which is why one category over both is the honest reading rather than a convenience", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4259,7 +4259,7 @@ "why": "the constructor coordinate", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4278,7 +4278,7 @@ "why": "a root-resolve site coordinate", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4301,7 +4301,7 @@ "why": "…and the second site array, a separate loop in the reference", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -4324,7 +4324,7 @@ "why": "an effect coordinate", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "line": 9223372036854775808 @@ -4341,7 +4341,7 @@ "why": "…and a binding coordinate", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "bindings": [ @@ -4362,7 +4362,7 @@ "why": "a parameter coordinate", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -4384,7 +4384,7 @@ "why": "…and an event coordinate, which reaches the bound through the shared obligation parser rather than through `load()` directly", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -4407,7 +4407,7 @@ "why": "an unrepresentable column is a representability failure…", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -4428,7 +4428,7 @@ "why": "…by either parser route…", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -4449,7 +4449,7 @@ "why": "…as is a float, even a whole one. Previously recorded as `location` next to `line-float`'s `shape`, with a comment calling the difference intentional — the same violation classified two ways because the reference raises one message for both and the category had been read off the message instead of the mechanism", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -4470,7 +4470,7 @@ "why": "…and the 1-based rule still fires for a value that IS representable, so the new axis did not swallow the old one", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -4491,7 +4491,7 @@ "why": "a flow body nested exactly 32 levels is accepted — the boundary case that caught the reference's own off-by-one", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -4673,7 +4673,7 @@ "why": "…and one level further is refused", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -4860,7 +4860,7 @@ "why": "…through `else` as well", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -5047,7 +5047,7 @@ "why": "…and through a loop body", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -5234,7 +5234,7 @@ "why": "an event tree nested exactly 32 levels is accepted", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -5449,7 +5449,7 @@ "why": "…and one level further is refused", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -5670,7 +5670,7 @@ "why": "…through `else`…", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -5891,7 +5891,7 @@ "why": "…and a loop body", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -6112,7 +6112,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level'", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6131,7 +6131,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6150,7 +6150,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6169,7 +6169,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6188,7 +6188,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level'", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6207,7 +6207,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6226,7 +6226,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6245,7 +6245,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6264,7 +6264,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level'", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6287,7 +6287,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6310,7 +6310,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6333,7 +6333,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6356,7 +6356,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level'", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6379,7 +6379,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6402,7 +6402,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6425,7 +6425,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "services", "document": { - "ownir_version": 1, + "ownir_version": 2, "services": [ { "name": "S", @@ -6448,7 +6448,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level'", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "line": 0 @@ -6465,7 +6465,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "line": 2147483647 @@ -6482,7 +6482,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "line": -1 @@ -6499,7 +6499,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "line": 2147483648 @@ -6516,7 +6516,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level'", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "bindings": [ @@ -6537,7 +6537,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "bindings": [ @@ -6558,7 +6558,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "bindings": [ @@ -6579,7 +6579,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "effects", "document": { - "ownir_version": 1, + "ownir_version": 2, "effects": [ { "bindings": [ @@ -6600,7 +6600,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level'", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -6622,7 +6622,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -6644,7 +6644,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -6666,7 +6666,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -6688,7 +6688,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level'", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -6711,7 +6711,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -6734,7 +6734,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -6757,7 +6757,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "protocol_functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "name": "M", @@ -6780,7 +6780,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level' — a field `load()` checked NOWHERE before this change, not even for type (§4.2's recorded exception, now closed)", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -6801,7 +6801,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -6822,7 +6822,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -6843,7 +6843,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -6864,7 +6864,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level' — a field `load()` checked NOWHERE before this change, not even for type (§4.2's recorded exception, now closed)", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -6886,7 +6886,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -6908,7 +6908,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -6930,7 +6930,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -6952,7 +6952,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level' — a field `load()` checked NOWHERE before this change, not even for type (§4.2's recorded exception, now closed)", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -6979,7 +6979,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7006,7 +7006,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7033,7 +7033,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7060,7 +7060,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level' — a field `load()` checked NOWHERE before this change, not even for type (§4.2's recorded exception, now closed)", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7087,7 +7087,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7114,7 +7114,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7141,7 +7141,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7168,7 +7168,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level' — a field `load()` checked NOWHERE before this change, not even for type (§4.2's recorded exception, now closed)", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7195,7 +7195,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7222,7 +7222,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7249,7 +7249,7 @@ "why": "…and one above the top, the value a port that kept the old signed-64 bound would still accept", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7276,7 +7276,7 @@ "why": "a string line has no integer form — `shape`, on the other axis from the domain rejections above", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -7297,7 +7297,7 @@ "why": "…and the bool-is-int trap, which would otherwise read as line 1", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -7318,7 +7318,7 @@ "why": "…and a PRESENT null, which is not the same as absent: the reference reads the slot with a `0` default, so only an absent key takes it", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -7339,7 +7339,7 @@ "why": "a string line has no integer form — `shape`, on the other axis from the domain rejections above", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7361,7 +7361,7 @@ "why": "…and the bool-is-int trap, which would otherwise read as line 1", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7383,7 +7383,7 @@ "why": "…and a PRESENT null, which is not the same as absent: the reference reads the slot with a `0` default, so only an absent key takes it", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7405,7 +7405,7 @@ "why": "a string line has no integer form — `shape`, on the other axis from the domain rejections above", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7432,7 +7432,7 @@ "why": "…and the bool-is-int trap, which would otherwise read as line 1", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7459,7 +7459,7 @@ "why": "…and a PRESENT null, which is not the same as absent: the reference reads the slot with a `0` default, so only an absent key takes it", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7486,7 +7486,7 @@ "why": "a string line has no integer form — `shape`, on the other axis from the domain rejections above", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7513,7 +7513,7 @@ "why": "…and the bool-is-int trap, which would otherwise read as line 1", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7540,7 +7540,7 @@ "why": "…and a PRESENT null, which is not the same as absent: the reference reads the slot with a `0` default, so only an absent key takes it", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7567,7 +7567,7 @@ "why": "a string line has no integer form — `shape`, on the other axis from the domain rejections above", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7594,7 +7594,7 @@ "why": "…and the bool-is-int trap, which would otherwise read as line 1", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7621,7 +7621,7 @@ "why": "…and a PRESENT null, which is not the same as absent: the reference reads the slot with a `0` default, so only an absent key takes it", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7648,7 +7648,7 @@ "why": "the top of the column domain, accepted exactly", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -7669,7 +7669,7 @@ "why": "…and one past it: representable, positive, and outside the domain — `location`, the same axis the 1-based rule is on", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -7690,7 +7690,7 @@ "why": "the top of the column domain, accepted exactly", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -7712,7 +7712,7 @@ "why": "…and one past it: representable, positive, and outside the domain — `location`, the same axis the 1-based rule is on", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "params": [ @@ -7734,7 +7734,7 @@ "why": "the top of the column domain, accepted exactly", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7756,7 +7756,7 @@ "why": "…and one past it: representable, positive, and outside the domain — `location`, the same axis the 1-based rule is on", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7778,7 +7778,7 @@ "why": "a column BELOW the representable form. It is `shape` by mechanism — there is no signed-64 integer here for a 1-based rule to be about — even though the reference's message names the 1-based rule, because it tests `v < 1` before the form. The category is read off the mechanism, which is this ledger's rule and the reason the taxonomy has two axes at all", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -7799,7 +7799,7 @@ "why": "an unknown resource kind and an out-of-domain line in one record: the kind is checked first, so this is `vocabulary`", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -7821,7 +7821,7 @@ "why": "…and the line precedes the column of the same node (§4.1), so a record breaking both reports the line's domain, not the column's type", "section": "components", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [ { "subscriptions": [ @@ -7843,7 +7843,7 @@ "why": "…and the same order inside a flow op", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7866,7 +7866,7 @@ "why": "the BODY's coordinates still precede `params` — the least obvious edge in the door, and now observable through a line as well as a column", "section": "functions", "document": { - "ownir_version": 1, + "ownir_version": 2, "functions": [ { "body": [ @@ -7893,7 +7893,7 @@ "why": "the list present and empty: nothing to check", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [] }, "raw": false, @@ -7906,7 +7906,7 @@ "why": "the four required fields alone (local, callee, file, line) — the optionals are optional", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -7926,7 +7926,7 @@ "why": "a complete family-A entry as the extractor writes it: column, method, family and the unwrapped result type", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -7950,7 +7950,7 @@ "why": "a family-B entry: a non-generic awaitable has no result type, so `result_type` is an explicit null, and `method` / `column` may be null too", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "c", @@ -7974,7 +7974,7 @@ "why": "entries are independent records; two valid ones are two sites", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8000,7 +8000,7 @@ "why": "the section must be an array of objects", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": { "local": "tx" } @@ -8015,7 +8015,7 @@ "why": "…and a PRESENT null is not absent", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": null }, "raw": false, @@ -8028,7 +8028,7 @@ "why": "an entry that is a scalar", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ 7 ] @@ -8043,7 +8043,7 @@ "why": "…and null is not a record", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ null ] @@ -8058,7 +8058,7 @@ "why": "…nor is a bare string, however much it looks like a local", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ "tx" ] @@ -8073,7 +8073,7 @@ "why": "`local` is the finding's event slot — a name slot, so empty is `identity`", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "", @@ -8093,7 +8093,7 @@ "why": "…and it is required", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "callee": "Npgsql.NpgsqlConnection.BeginTransactionAsync/1", @@ -8112,7 +8112,7 @@ "why": "…and a list is not a name — the exact shape the unbound list rendered as a finding", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": [ @@ -8136,7 +8136,7 @@ "why": "…and null is not a name either", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": null, @@ -8156,7 +8156,7 @@ "why": "`callee` is the finding's handler slot (Type.Member/arity) — a name slot", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8176,7 +8176,7 @@ "why": "…and it is required", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8195,7 +8195,7 @@ "why": "…and an object is not a name", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8217,7 +8217,7 @@ "why": "`file` is required (the anchor's file)", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8236,7 +8236,7 @@ "why": "…and it must be a string", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8256,7 +8256,7 @@ "why": "…a present null included", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8276,7 +8276,7 @@ "why": "`line` is required — unlike the defaulted lines elsewhere, an entry with no line is not a site", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8295,7 +8295,7 @@ "why": "a string line has no integer form", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8315,7 +8315,7 @@ "why": "…and the bool-is-int trap", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8335,7 +8335,7 @@ "why": "…and a present null", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8355,7 +8355,7 @@ "why": "…and a float, which is not a coordinate", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8375,7 +8375,7 @@ "why": "a line with no signed-64 form: `shape` by mechanism, on the other axis from the domain controls below", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8395,7 +8395,7 @@ "why": "the 1-based boundary on the site column", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8416,7 +8416,7 @@ "why": "the same column contract as every other column: 0 is a producer bug, not 'unknown'", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8437,7 +8437,7 @@ "why": "…negative likewise", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8458,7 +8458,7 @@ "why": "…and the bool-is-int trap on the column", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8479,7 +8479,7 @@ "why": "…and a string, which has no integer form to be 1-based about", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8500,7 +8500,7 @@ "why": "`method` is a string or null", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8521,7 +8521,7 @@ "why": "`family` is a closed set: a third family does not exist until a witness earns it", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8542,7 +8542,7 @@ "why": "…and a non-string is outside the set the same way a non-string parameter effect is", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8563,7 +8563,7 @@ "why": "…and so is the empty string", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8584,7 +8584,7 @@ "why": "`result_type` is a string or null — the number the unbound list would have rendered as a type name", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8605,7 +8605,7 @@ "why": "both name slots broken: `local` is checked first — observable only through the message, so the control pins the identity category and the pair is kept for a reader", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "", @@ -8625,7 +8625,7 @@ "why": "identity precedes the anchor: a broken callee outranks a missing file", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8644,7 +8644,7 @@ "why": "…and the file precedes the line", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8664,7 +8664,7 @@ "why": "…the line's domain precedes the column's type (§4.1 order)", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8685,7 +8685,7 @@ "why": "…and the column precedes the family vocabulary", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8707,7 +8707,7 @@ "why": "…and the family precedes the result type", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8729,7 +8729,7 @@ "why": "across sections: `protocol_functions` is validated before `orphaned_awaitables`, so a protocol function without a name (identity) outranks a non-array site list (shape)", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "protocol_functions": [ { "file": "a.cs" @@ -8749,7 +8749,7 @@ "why": "…and nothing is validated after it: a document whose only defect is in the site list reports that defect", "section": "order", "document": { - "ownir_version": 1, + "ownir_version": 2, "components": [], "services": [], "effects": [], @@ -8775,7 +8775,7 @@ "why": "`0` is the bottom of the domain and means 'unknown / file-level'", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8795,7 +8795,7 @@ "why": "…and 2147483647 is the top, accepted exactly", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8815,7 +8815,7 @@ "why": "one below the bottom: a representable coordinate outside its domain, so `location` rather than `shape`", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8835,7 +8835,7 @@ "why": "…and one above the top — the value the unbound list degraded to 0 and the strict door now refuses", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8855,7 +8855,7 @@ "why": "the top of the column domain, accepted exactly", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", @@ -8876,7 +8876,7 @@ "why": "…and one past it: representable, positive, and outside the domain — `location`, the same axis the 1-based rule is on", "section": "orphaned_awaitables", "document": { - "ownir_version": 1, + "ownir_version": 2, "orphaned_awaitables": [ { "local": "tx", diff --git a/tests/fixtures/repro/canonical_key_order.facts.json b/tests/fixtures/repro/canonical_key_order.facts.json index 24a0a3ef..621e859a 100644 --- a/tests/fixtures/repro/canonical_key_order.facts.json +++ b/tests/fixtures/repro/canonical_key_order.facts.json @@ -10,5 +10,5 @@ "name": "Zed" } ], - "ownir_version": 1 + "ownir_version": 2 } diff --git a/tests/fixtures/repro/canonical_key_order.repro.json b/tests/fixtures/repro/canonical_key_order.repro.json index 353447a5..d560cf49 100644 --- a/tests/fixtures/repro/canonical_key_order.repro.json +++ b/tests/fixtures/repro/canonical_key_order.repro.json @@ -1,16 +1,16 @@ { "repro_version": 3, "input": { - "ownir_version": 1, + "ownir_version": 2, "raw": { "algorithm": "sha256", - "digest": "fbb8fcbd328fd7ccc555d9f41d3878991ce628f92e3642091b4218eacb6ad3dc", + "digest": "576a0b7b733b157fe13aedd58b8417a8413cb5caa5af89c838755d2f8bf9730e", "bytes": 377, - "base64": "ewogICJtb2R1bGUiOiAiS2V5T3JkZXIiLAogICJjb21wb25lbnRzIjogWwogICAgewogICAgICAic3Vic2NyaXB0aW9ucyI6IFsKICAgICAgICB7InJlbGVhc2VkIjogZmFsc2UsICJyZXNvdXJjZSI6ICJzdWJzY3JpYmUiLCAibGluZSI6IDMsICJldmVudCI6ICJiLlpldGEiLCAiaGFuZGxlciI6ICJPblpldGEifSwKICAgICAgICB7ImV2ZW50IjogImEuQWxwaGEiLCAibGluZSI6IDQsICJyZXNvdXJjZSI6ICJzdWJzY3JpYmUiLCAicmVsZWFzZWQiOiB0cnVlLCAiaGFuZGxlciI6ICJPbkFscGhhIn0KICAgICAgXSwKICAgICAgImZpbGUiOiAiS2V5T3JkZXIuY3MiLAogICAgICAibmFtZSI6ICJaZWQiCiAgICB9CiAgXSwKICAib3duaXJfdmVyc2lvbiI6IDEKfQo=" + "base64": "ewogICJtb2R1bGUiOiAiS2V5T3JkZXIiLAogICJjb21wb25lbnRzIjogWwogICAgewogICAgICAic3Vic2NyaXB0aW9ucyI6IFsKICAgICAgICB7InJlbGVhc2VkIjogZmFsc2UsICJyZXNvdXJjZSI6ICJzdWJzY3JpYmUiLCAibGluZSI6IDMsICJldmVudCI6ICJiLlpldGEiLCAiaGFuZGxlciI6ICJPblpldGEifSwKICAgICAgICB7ImV2ZW50IjogImEuQWxwaGEiLCAibGluZSI6IDQsICJyZXNvdXJjZSI6ICJzdWJzY3JpYmUiLCAicmVsZWFzZWQiOiB0cnVlLCAiaGFuZGxlciI6ICJPbkFscGhhIn0KICAgICAgXSwKICAgICAgImZpbGUiOiAiS2V5T3JkZXIuY3MiLAogICAgICAibmFtZSI6ICJaZWQiCiAgICB9CiAgXSwKICAib3duaXJfdmVyc2lvbiI6IDIKfQo=" }, "canonical": { "algorithm": "sha256", - "digest": "84301b7dadc06e52b558b3da71322a8f1d863d45694e9ebe7647c9dce5ebb049", + "digest": "8b620e3fb1ad221a7468dee4968fd32303378983b292c9bcfe17eec55126ebbb", "bytes": 283 }, "document": { @@ -37,7 +37,7 @@ "name": "Zed" } ], - "ownir_version": 1 + "ownir_version": 2 } }, "engines": [ @@ -45,7 +45,7 @@ "id": "python-ownlang", "consumed": { "algorithm": "sha256", - "digest": "fbb8fcbd328fd7ccc555d9f41d3878991ce628f92e3642091b4218eacb6ad3dc", + "digest": "576a0b7b733b157fe13aedd58b8417a8413cb5caa5af89c838755d2f8bf9730e", "bytes": 377 }, "layers": [ @@ -208,7 +208,7 @@ "document": { "degraded": null, "module": "KeyOrder", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -249,7 +249,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "d41ab0ff6d94e1967ac19effc4eaf992fc23821d1f2d52f5fba79ccb934f5fe4", + "digest": "d9515ded12e0f0737b51347f7fba046ab64ea368af56dfb205afc97425977163", "bytes": 793 } } @@ -259,7 +259,7 @@ "id": "rust-own-bridge", "consumed": { "algorithm": "sha256", - "digest": "fbb8fcbd328fd7ccc555d9f41d3878991ce628f92e3642091b4218eacb6ad3dc", + "digest": "576a0b7b733b157fe13aedd58b8417a8413cb5caa5af89c838755d2f8bf9730e", "bytes": 377 }, "layers": [ @@ -422,7 +422,7 @@ "document": { "degraded": null, "module": "KeyOrder", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -463,7 +463,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "d41ab0ff6d94e1967ac19effc4eaf992fc23821d1f2d52f5fba79ccb934f5fe4", + "digest": "d9515ded12e0f0737b51347f7fba046ab64ea368af56dfb205afc97425977163", "bytes": 793 } } diff --git a/tests/fixtures/repro/canonical_key_order.trace.json b/tests/fixtures/repro/canonical_key_order.trace.json index 61b16fee..4b797710 100644 --- a/tests/fixtures/repro/canonical_key_order.trace.json +++ b/tests/fixtures/repro/canonical_key_order.trace.json @@ -7,7 +7,7 @@ "engine": "python-ownlang", "input": { "algorithm": "sha256", - "digest": "84301b7dadc06e52b558b3da71322a8f1d863d45694e9ebe7647c9dce5ebb049", + "digest": "8b620e3fb1ad221a7468dee4968fd32303378983b292c9bcfe17eec55126ebbb", "bytes": 283 }, "layers": [ @@ -210,7 +210,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", @@ -258,7 +258,7 @@ "engine": "rust-own-bridge", "input": { "algorithm": "sha256", - "digest": "84301b7dadc06e52b558b3da71322a8f1d863d45694e9ebe7647c9dce5ebb049", + "digest": "8b620e3fb1ad221a7468dee4968fd32303378983b292c9bcfe17eec55126ebbb", "bytes": 283 }, "layers": [ @@ -461,7 +461,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", diff --git a/tests/fixtures/repro/canonical_minimal.facts.json b/tests/fixtures/repro/canonical_minimal.facts.json index 47940bbf..87830c6d 100644 --- a/tests/fixtures/repro/canonical_minimal.facts.json +++ b/tests/fixtures/repro/canonical_minimal.facts.json @@ -1,4 +1,4 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Minimal" } diff --git a/tests/fixtures/repro/canonical_minimal.repro.json b/tests/fixtures/repro/canonical_minimal.repro.json index ea712740..7743962d 100644 --- a/tests/fixtures/repro/canonical_minimal.repro.json +++ b/tests/fixtures/repro/canonical_minimal.repro.json @@ -1,20 +1,20 @@ { "repro_version": 3, "input": { - "ownir_version": 1, + "ownir_version": 2, "raw": { "algorithm": "sha256", - "digest": "4573241a7888cac6145dd1005623c1edd6573a221d6779515781eb247041ebc7", + "digest": "58a2d13e4d8993a710f8d4d62a2cc417ccce569145678648ef92c53e8839f9bd", "bytes": 48, - "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMSwKICAibW9kdWxlIjogIk1pbmltYWwiCn0K" + "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMiwKICAibW9kdWxlIjogIk1pbmltYWwiCn0K" }, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 }, "document": { - "ownir_version": 1, + "ownir_version": 2, "module": "Minimal" } }, @@ -23,7 +23,7 @@ "id": "python-ownlang", "consumed": { "algorithm": "sha256", - "digest": "4573241a7888cac6145dd1005623c1edd6573a221d6779515781eb247041ebc7", + "digest": "58a2d13e4d8993a710f8d4d62a2cc417ccce569145678648ef92c53e8839f9bd", "bytes": 48 }, "layers": [ @@ -139,7 +139,7 @@ "document": { "degraded": null, "module": "Minimal", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -163,7 +163,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "aa7b2312f4da58d124b29b75b86b5f05c767ef43cac802cffa19e566740b3096", + "digest": "a7bf0bd6d242a0d56eeebed72e2dcc5fc80cd2c44e89792c7fc5a2311334ea4d", "bytes": 289 } } @@ -173,7 +173,7 @@ "id": "rust-own-bridge", "consumed": { "algorithm": "sha256", - "digest": "4573241a7888cac6145dd1005623c1edd6573a221d6779515781eb247041ebc7", + "digest": "58a2d13e4d8993a710f8d4d62a2cc417ccce569145678648ef92c53e8839f9bd", "bytes": 48 }, "layers": [ @@ -289,7 +289,7 @@ "document": { "degraded": null, "module": "Minimal", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -313,7 +313,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "aa7b2312f4da58d124b29b75b86b5f05c767ef43cac802cffa19e566740b3096", + "digest": "a7bf0bd6d242a0d56eeebed72e2dcc5fc80cd2c44e89792c7fc5a2311334ea4d", "bytes": 289 } } diff --git a/tests/fixtures/repro/canonical_minimal.trace.json b/tests/fixtures/repro/canonical_minimal.trace.json index 420af5cd..bf3a8b1a 100644 --- a/tests/fixtures/repro/canonical_minimal.trace.json +++ b/tests/fixtures/repro/canonical_minimal.trace.json @@ -7,7 +7,7 @@ "engine": "python-ownlang", "input": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 }, "layers": [ @@ -147,7 +147,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", @@ -176,7 +176,7 @@ "engine": "rust-own-bridge", "input": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 }, "layers": [ @@ -316,7 +316,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", diff --git a/tests/fixtures/repro/canonical_torture.facts.json b/tests/fixtures/repro/canonical_torture.facts.json index c9361052..e3dc76d9 100644 --- a/tests/fixtures/repro/canonical_torture.facts.json +++ b/tests/fixtures/repro/canonical_torture.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Tortureé漢字😀", "canonical_probe": { "i64_max": 9223372036854775807, diff --git a/tests/fixtures/repro/canonical_torture.repro.json b/tests/fixtures/repro/canonical_torture.repro.json index b4e8bb5e..19ae231f 100644 --- a/tests/fixtures/repro/canonical_torture.repro.json +++ b/tests/fixtures/repro/canonical_torture.repro.json @@ -1,20 +1,20 @@ { "repro_version": 3, "input": { - "ownir_version": 1, + "ownir_version": 2, "raw": { "algorithm": "sha256", - "digest": "a1c896ce83130584dcbb113c751547e4b488fae6798b00fcc919c8a1cdd8a170", + "digest": "9e9aa2dd965ef4c28aa0b09130ad9b93db2dea9c86d9da8196130aaef25a7933", "bytes": 1049, - "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMSwKICAibW9kdWxlIjogIlRvcnR1cmXDqea8ouWtl/CfmIAiLAogICJjYW5vbmljYWxfcHJvYmUiOiB7CiAgICAiaTY0X21heCI6IDkyMjMzNzIwMzY4NTQ3NzU4MDcsCiAgICAiaTY0X21pbiI6IC05MjIzMzcyMDM2ODU0Nzc1ODA4LAogICAgInplcm8iOiAwLAogICAgImJvb2xlYW5zIjogW3RydWUsIGZhbHNlXSwKICAgICJudWxsIjogbnVsbCwKICAgICJlbXB0eV9vYmplY3QiOiB7fSwKICAgICJlbXB0eV9hcnJheSI6IFtdLAogICAgImVtcHR5X3N0cmluZyI6ICIiLAogICAgInR3b19jaGFyX2VzY2FwZXMiOiAiXGJcdFxuXGZcciIsCiAgICAib3RoZXJfYzBfY29udHJvbHMiOiAiXHUwMDAwXHUwMDAxXHUwMDFmIiwKICAgICJkZWxldGVfaXNfbm90X2VzY2FwZWQiOiAiXHUwMDdmIiwKICAgICJxdW90ZV9hbmRfYmFja3NsYXNoIjogImhlIHNhaWQgXCJoaVwiIFxcIGJhY2siLAogICAgIm5ic3AiOiAiwqAiLAogICAgImxpbmVfYW5kX3BhcmFncmFwaF9zZXBhcmF0b3JzIjogIuKAqOKAqSIsCiAgICAiYnl0ZV9vcmRlcl9tYXJrIjogIu+7vyIsCiAgICAiYXN0cmFsIjogIvCfmIAiLAogICAgIvCfmIAiOiAiYW4gYXN0cmFsIGtleSBzb3J0cyBhZnRlciBldmVyeSBBU0NJSSBrZXkiLAogICAgIsOpIjogImFuIGFjY2VudGVkIGtleSBzb3J0cyBhZnRlciBldmVyeSBBU0NJSSBrZXkiLAogICAgIiI6ICJ0aGUgZW1wdHkga2V5IHNvcnRzIGZpcnN0IiwKICAgICJaIjogInVwcGVyY2FzZSBaIHNvcnRzIGJlZm9yZSBsb3dlcmNhc2UgYSIsCiAgICAiYSI6ICJsb3dlcmNhc2UgYSIKICB9LAogICJjb21wb25lbnRzIjogWwogICAgewogICAgICAibmFtZSI6ICJUb3J0dXJlVmlldyIsCiAgICAgICJmaWxlIjogIlTDtnJ0dXJlLmNzIiwKICAgICAgInN1YnNjcmlwdGlvbnMiOiBbCiAgICAgICAgeyJldmVudCI6ICJidXMuU3Vic2NyaWJlIiwgImhhbmRsZXIiOiAiT27mvKIiLCAibGluZSI6IDcsICJyZWxlYXNlZCI6IGZhbHNlLCAicmVzb3VyY2UiOiAic3Vic2NyaWJlIn0KICAgICAgXQogICAgfQogIF0KfQo=" + "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMiwKICAibW9kdWxlIjogIlRvcnR1cmXDqea8ouWtl/CfmIAiLAogICJjYW5vbmljYWxfcHJvYmUiOiB7CiAgICAiaTY0X21heCI6IDkyMjMzNzIwMzY4NTQ3NzU4MDcsCiAgICAiaTY0X21pbiI6IC05MjIzMzcyMDM2ODU0Nzc1ODA4LAogICAgInplcm8iOiAwLAogICAgImJvb2xlYW5zIjogW3RydWUsIGZhbHNlXSwKICAgICJudWxsIjogbnVsbCwKICAgICJlbXB0eV9vYmplY3QiOiB7fSwKICAgICJlbXB0eV9hcnJheSI6IFtdLAogICAgImVtcHR5X3N0cmluZyI6ICIiLAogICAgInR3b19jaGFyX2VzY2FwZXMiOiAiXGJcdFxuXGZcciIsCiAgICAib3RoZXJfYzBfY29udHJvbHMiOiAiXHUwMDAwXHUwMDAxXHUwMDFmIiwKICAgICJkZWxldGVfaXNfbm90X2VzY2FwZWQiOiAiXHUwMDdmIiwKICAgICJxdW90ZV9hbmRfYmFja3NsYXNoIjogImhlIHNhaWQgXCJoaVwiIFxcIGJhY2siLAogICAgIm5ic3AiOiAiwqAiLAogICAgImxpbmVfYW5kX3BhcmFncmFwaF9zZXBhcmF0b3JzIjogIuKAqOKAqSIsCiAgICAiYnl0ZV9vcmRlcl9tYXJrIjogIu+7vyIsCiAgICAiYXN0cmFsIjogIvCfmIAiLAogICAgIvCfmIAiOiAiYW4gYXN0cmFsIGtleSBzb3J0cyBhZnRlciBldmVyeSBBU0NJSSBrZXkiLAogICAgIsOpIjogImFuIGFjY2VudGVkIGtleSBzb3J0cyBhZnRlciBldmVyeSBBU0NJSSBrZXkiLAogICAgIiI6ICJ0aGUgZW1wdHkga2V5IHNvcnRzIGZpcnN0IiwKICAgICJaIjogInVwcGVyY2FzZSBaIHNvcnRzIGJlZm9yZSBsb3dlcmNhc2UgYSIsCiAgICAiYSI6ICJsb3dlcmNhc2UgYSIKICB9LAogICJjb21wb25lbnRzIjogWwogICAgewogICAgICAibmFtZSI6ICJUb3J0dXJlVmlldyIsCiAgICAgICJmaWxlIjogIlTDtnJ0dXJlLmNzIiwKICAgICAgInN1YnNjcmlwdGlvbnMiOiBbCiAgICAgICAgeyJldmVudCI6ICJidXMuU3Vic2NyaWJlIiwgImhhbmRsZXIiOiAiT27mvKIiLCAibGluZSI6IDcsICJyZWxlYXNlZCI6IGZhbHNlLCAicmVzb3VyY2UiOiAic3Vic2NyaWJlIn0KICAgICAgXQogICAgfQogIF0KfQo=" }, "canonical": { "algorithm": "sha256", - "digest": "abe4b1afa5a4f287401f9b50c1dec00c57588ab6baabc77968f3f1af232b49f2", + "digest": "b4b25311816e496d885f8b3639e4f20d0a13cc02fd50c589f24b51b3f32511e7", "bytes": 834 }, "document": { - "ownir_version": 1, + "ownir_version": 2, "module": "Tortureé漢字😀", "canonical_probe": { "i64_max": 9223372036854775807, @@ -64,7 +64,7 @@ "id": "python-ownlang", "consumed": { "algorithm": "sha256", - "digest": "a1c896ce83130584dcbb113c751547e4b488fae6798b00fcc919c8a1cdd8a170", + "digest": "9e9aa2dd965ef4c28aa0b09130ad9b93db2dea9c86d9da8196130aaef25a7933", "bytes": 1049 }, "layers": [ @@ -206,7 +206,7 @@ "document": { "degraded": null, "module": "Tortureé漢字😀", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -247,7 +247,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "78ece332c38aa64e10136c8a809552dc47aafaa5bede557d020be4090fe689da", + "digest": "a942641984e3c85658edc26b8c4512a915fd927dab6b834bb259c3564d0bc711", "bytes": 822 } } @@ -257,7 +257,7 @@ "id": "rust-own-bridge", "consumed": { "algorithm": "sha256", - "digest": "a1c896ce83130584dcbb113c751547e4b488fae6798b00fcc919c8a1cdd8a170", + "digest": "9e9aa2dd965ef4c28aa0b09130ad9b93db2dea9c86d9da8196130aaef25a7933", "bytes": 1049 }, "layers": [ @@ -399,7 +399,7 @@ "document": { "degraded": null, "module": "Tortureé漢字😀", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -440,7 +440,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "78ece332c38aa64e10136c8a809552dc47aafaa5bede557d020be4090fe689da", + "digest": "a942641984e3c85658edc26b8c4512a915fd927dab6b834bb259c3564d0bc711", "bytes": 822 } } diff --git a/tests/fixtures/repro/canonical_torture.trace.json b/tests/fixtures/repro/canonical_torture.trace.json index f12e3106..5fbd59ed 100644 --- a/tests/fixtures/repro/canonical_torture.trace.json +++ b/tests/fixtures/repro/canonical_torture.trace.json @@ -7,7 +7,7 @@ "engine": "python-ownlang", "input": { "algorithm": "sha256", - "digest": "abe4b1afa5a4f287401f9b50c1dec00c57588ab6baabc77968f3f1af232b49f2", + "digest": "b4b25311816e496d885f8b3639e4f20d0a13cc02fd50c589f24b51b3f32511e7", "bytes": 834 }, "layers": [ @@ -179,7 +179,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", @@ -227,7 +227,7 @@ "engine": "rust-own-bridge", "input": { "algorithm": "sha256", - "digest": "abe4b1afa5a4f287401f9b50c1dec00c57588ab6baabc77968f3f1af232b49f2", + "digest": "b4b25311816e496d885f8b3639e4f20d0a13cc02fd50c589f24b51b3f32511e7", "bytes": 834 }, "layers": [ @@ -399,7 +399,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", diff --git a/tests/fixtures/repro/di.repro.json b/tests/fixtures/repro/di.repro.json index 518aa99d..bb99fd00 100644 --- a/tests/fixtures/repro/di.repro.json +++ b/tests/fixtures/repro/di.repro.json @@ -1,20 +1,20 @@ { "repro_version": 3, "input": { - "ownir_version": 1, + "ownir_version": 2, "raw": { "algorithm": "sha256", - "digest": "0d87c5f755986f17d7e7a4e7f5193030113ecd8549049c98b3108696fcf036da", + "digest": "6283c93c414316a2aed82484f1818c3049e1acd92fcb451dfc8c7e3b9be170cd", "bytes": 884, - "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMSwKICAibW9kdWxlIjogIkRpRGVtbyIsCiAgImNvbXBvbmVudHMiOiBbXSwKICAic2VydmljZXMiOiBbCiAgICB7Im5hbWUiOiAiRW1haWxTZW5kZXIiLCAibGlmZXRpbWUiOiAic2luZ2xldG9uIiwgImZpbGUiOiAiU3RhcnR1cC5jcyIsICJsaW5lIjogMTIsICJkZXBzIjogWyJBcHBEYkNvbnRleHQiXSwgImN0b3JfZmlsZSI6ICJFbWFpbFNlbmRlci5jcyIsICJjdG9yX2xpbmUiOiA1LCAiY3Rvcl90eXBlIjogIkVtYWlsU2VuZGVyIn0sCiAgICB7Im5hbWUiOiAiQXBwRGJDb250ZXh0IiwgImxpZmV0aW1lIjogInNjb3BlZCIsICJmaWxlIjogIlN0YXJ0dXAuY3MiLCAibGluZSI6IDEzLCAiZGVwcyI6IFtdfSwKICAgIHsibmFtZSI6ICJDbG9jayIsICJsaWZldGltZSI6ICJzaW5nbGV0b24iLCAiZmlsZSI6ICJTdGFydHVwLmNzIiwgImxpbmUiOiAxNCwgImRlcHMiOiBbXX0sCiAgICB7Im5hbWUiOiAiUmVwb3J0U2VydmljZSIsICJsaWZldGltZSI6ICJzaW5nbGV0b24iLCAiZmlsZSI6ICJTdGFydHVwLmNzIiwgImxpbmUiOiAxNSwgImRlcHMiOiBbIlVuaXRPZldvcmsiXSwgImN0b3JfZmlsZSI6ICJSZXBvcnRTZXJ2aWNlLmNzIiwgImN0b3JfbGluZSI6IDcsICJjdG9yX3R5cGUiOiAiUmVwb3J0U2VydmljZSJ9LAogICAgeyJuYW1lIjogIlVuaXRPZldvcmsiLCAibGlmZXRpbWUiOiAidHJhbnNpZW50IiwgImZpbGUiOiAiU3RhcnR1cC5jcyIsICJsaW5lIjogMTYsICJkZXBzIjogWyJBcHBEYkNvbnRleHQiXX0sCiAgICB7Im5hbWUiOiAiUmVxdWVzdExvZyIsICJsaWZldGltZSI6ICJzY29wZWQiLCAiZmlsZSI6ICJTdGFydHVwLmNzIiwgImxpbmUiOiAxNywgImRlcHMiOiBbIkFwcERiQ29udGV4dCJdfQogIF0KfQo=" + "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMiwKICAibW9kdWxlIjogIkRpRGVtbyIsCiAgImNvbXBvbmVudHMiOiBbXSwKICAic2VydmljZXMiOiBbCiAgICB7Im5hbWUiOiAiRW1haWxTZW5kZXIiLCAibGlmZXRpbWUiOiAic2luZ2xldG9uIiwgImZpbGUiOiAiU3RhcnR1cC5jcyIsICJsaW5lIjogMTIsICJkZXBzIjogWyJBcHBEYkNvbnRleHQiXSwgImN0b3JfZmlsZSI6ICJFbWFpbFNlbmRlci5jcyIsICJjdG9yX2xpbmUiOiA1LCAiY3Rvcl90eXBlIjogIkVtYWlsU2VuZGVyIn0sCiAgICB7Im5hbWUiOiAiQXBwRGJDb250ZXh0IiwgImxpZmV0aW1lIjogInNjb3BlZCIsICJmaWxlIjogIlN0YXJ0dXAuY3MiLCAibGluZSI6IDEzLCAiZGVwcyI6IFtdfSwKICAgIHsibmFtZSI6ICJDbG9jayIsICJsaWZldGltZSI6ICJzaW5nbGV0b24iLCAiZmlsZSI6ICJTdGFydHVwLmNzIiwgImxpbmUiOiAxNCwgImRlcHMiOiBbXX0sCiAgICB7Im5hbWUiOiAiUmVwb3J0U2VydmljZSIsICJsaWZldGltZSI6ICJzaW5nbGV0b24iLCAiZmlsZSI6ICJTdGFydHVwLmNzIiwgImxpbmUiOiAxNSwgImRlcHMiOiBbIlVuaXRPZldvcmsiXSwgImN0b3JfZmlsZSI6ICJSZXBvcnRTZXJ2aWNlLmNzIiwgImN0b3JfbGluZSI6IDcsICJjdG9yX3R5cGUiOiAiUmVwb3J0U2VydmljZSJ9LAogICAgeyJuYW1lIjogIlVuaXRPZldvcmsiLCAibGlmZXRpbWUiOiAidHJhbnNpZW50IiwgImZpbGUiOiAiU3RhcnR1cC5jcyIsICJsaW5lIjogMTYsICJkZXBzIjogWyJBcHBEYkNvbnRleHQiXX0sCiAgICB7Im5hbWUiOiAiUmVxdWVzdExvZyIsICJsaWZldGltZSI6ICJzY29wZWQiLCAiZmlsZSI6ICJTdGFydHVwLmNzIiwgImxpbmUiOiAxNywgImRlcHMiOiBbIkFwcERiQ29udGV4dCJdfQogIF0KfQo=" }, "canonical": { "algorithm": "sha256", - "digest": "f032d100186d884fc1778e501715e23675460cef64271ddd00525e42f2a88d85", + "digest": "fe713a6d2482c003b5ea8897b893587205a9b763a351d1616f3e71e4c6c1deb9", "bytes": 767 }, "document": { - "ownir_version": 1, + "ownir_version": 2, "module": "DiDemo", "components": [], "services": [ @@ -82,7 +82,7 @@ "id": "python-ownlang", "consumed": { "algorithm": "sha256", - "digest": "0d87c5f755986f17d7e7a4e7f5193030113ecd8549049c98b3108696fcf036da", + "digest": "6283c93c414316a2aed82484f1818c3049e1acd92fcb451dfc8c7e3b9be170cd", "bytes": 884 }, "layers": [ @@ -198,7 +198,7 @@ "document": { "degraded": null, "module": "DiDemo", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -294,7 +294,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "1dc9b97ea182ba82d79f49123f5e491306bc99e1e5fd33349c1fd369986655d8", + "digest": "dfa029cd93a66e1e149d70180aa209ea74dc6e51d4186ec898022ef23d7aaa47", "bytes": 2564 } } @@ -304,7 +304,7 @@ "id": "rust-own-bridge", "consumed": { "algorithm": "sha256", - "digest": "0d87c5f755986f17d7e7a4e7f5193030113ecd8549049c98b3108696fcf036da", + "digest": "6283c93c414316a2aed82484f1818c3049e1acd92fcb451dfc8c7e3b9be170cd", "bytes": 884 }, "layers": [ @@ -420,7 +420,7 @@ "document": { "degraded": null, "module": "DiDemo", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -516,7 +516,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "1dc9b97ea182ba82d79f49123f5e491306bc99e1e5fd33349c1fd369986655d8", + "digest": "dfa029cd93a66e1e149d70180aa209ea74dc6e51d4186ec898022ef23d7aaa47", "bytes": 2564 } } diff --git a/tests/fixtures/repro/di.trace.json b/tests/fixtures/repro/di.trace.json index ea677c81..179f2bbd 100644 --- a/tests/fixtures/repro/di.trace.json +++ b/tests/fixtures/repro/di.trace.json @@ -7,7 +7,7 @@ "engine": "python-ownlang", "input": { "algorithm": "sha256", - "digest": "f032d100186d884fc1778e501715e23675460cef64271ddd00525e42f2a88d85", + "digest": "fe713a6d2482c003b5ea8897b893587205a9b763a351d1616f3e71e4c6c1deb9", "bytes": 767 }, "layers": [ @@ -147,7 +147,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", @@ -253,7 +253,7 @@ "engine": "rust-own-bridge", "input": { "algorithm": "sha256", - "digest": "f032d100186d884fc1778e501715e23675460cef64271ddd00525e42f2a88d85", + "digest": "fe713a6d2482c003b5ea8897b893587205a9b763a351d1616f3e71e4c6c1deb9", "bytes": 767 }, "layers": [ @@ -393,7 +393,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", diff --git a/tests/fixtures/repro/digests.json b/tests/fixtures/repro/digests.json index e673f0d6..13c75451 100644 --- a/tests/fixtures/repro/digests.json +++ b/tests/fixtures/repro/digests.json @@ -6,817 +6,943 @@ { "case": "alias_join_cases", "corpus": "lowered", - "digest": "05a2e24920ee8d36006b4dba4b6a10ba398ef3f37a224b9770bb8f9d13e37f54", + "digest": "de666edd821a0f7d7a31ec99cb193f8c0feeecb82b8d57f36ab9d9d01402c750", "bytes": 377 }, { "case": "canonical_key_order", "corpus": "repro", - "digest": "84301b7dadc06e52b558b3da71322a8f1d863d45694e9ebe7647c9dce5ebb049", + "digest": "8b620e3fb1ad221a7468dee4968fd32303378983b292c9bcfe17eec55126ebbb", "bytes": 283 }, { "case": "canonical_minimal", "corpus": "repro", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 }, { "case": "canonical_torture", "corpus": "repro", - "digest": "abe4b1afa5a4f287401f9b50c1dec00c57588ab6baabc77968f3f1af232b49f2", + "digest": "b4b25311816e496d885f8b3639e4f20d0a13cc02fd50c589f24b51b3f32511e7", "bytes": 834 }, { "case": "capture", "corpus": "ownir", - "digest": "a34f862ff561b0649c879d2bca226bf21cc107f4601c3720c45f3b419ed494b6", + "digest": "e8356bd686ab2fa17442e63d80cf81b76930d3cf1af093bed2fa3904819d9b51", "bytes": 696 }, { "case": "contract_inference", "corpus": "ownir", - "digest": "96f4fc97febff178709e22be42e6ba4f54c00fa018117605499deeb1e4765fdc", + "digest": "949296daf0f6cd497cabfbecc3607d212b0291e90834f52c73a32a66672508fe", "bytes": 785 }, { "case": "di", "corpus": "ownir", - "digest": "f032d100186d884fc1778e501715e23675460cef64271ddd00525e42f2a88d85", + "digest": "fe713a6d2482c003b5ea8897b893587205a9b763a351d1616f3e71e4c6c1deb9", "bytes": 767 }, { "case": "di_capture", "corpus": "ownir", - "digest": "718ba4d6bfd8a4a450a3f22fe6e2fc3774819681605be87009af54752ea7f03b", + "digest": "c5d9cf323607bb8218bbef2f85af7c9115a94ecbda7e2d265415780a71c6fdb1", "bytes": 684 }, { "case": "disposable", "corpus": "ownir", - "digest": "c6a27c0be85a5f41f8f0d7527d6ddb3eb14138bb6993f6759061d97285636fed", + "digest": "a8884c0899f9a7ef137150ea42154e3d5f382333343c72ea5d53a2e80e352886", "bytes": 430 }, { "case": "flow_column_anchors", "corpus": "ownir", - "digest": "fd7aa188032f84027570465837631a31ebffbe33e98f9672640f4978dddf75c8", + "digest": "48e5ba5719b53db604c48742b1af0da37bf38b3adfe46d3f6caca3244bec5377", "bytes": 2288 }, { "case": "flow_finally_switch", "corpus": "ownir", - "digest": "5091a185081323ef890cab84c7779443e317c7960b1b6cd38c2ac636a7445ea8", + "digest": "5f5e4ca42037ce2a182302e7adc149920c113dafbc9f0806ee6daf3c96b824ea", "bytes": 1675 }, { "case": "flow_kill_on_rebind", "corpus": "lowered", - "digest": "78534e41a0e95815c779cf7b6ddf8ce292580dc16688d0274ca2f9de2ad916f1", + "digest": "470b424f9e16f4c129ea69403716677ccfaff7cc7ca26777f3dda8224bee2ac6", "bytes": 229 }, { "case": "flow_leak_on_else", "corpus": "ownir", - "digest": "e5f0bf314e3e335b7444565303b11ebacee6def8e4a1a13d9bb75548e5642645", + "digest": "f1ce29e975c248d7e1ff1bdeadb368a489ba3c20db6c030e1dff72b78e28f4f1", "bytes": 268 }, { "case": "flow_leak_two_exits", "corpus": "ownir", - "digest": "3e1bfac01192596271a025941ff40216743b1be6d010681bc20bd66ebb64f834", + "digest": "718084d5658f7106bd84bcda3c5fc340027e85dcac415fa6923a0696e268a608", "bytes": 315 }, { "case": "flow_nested_throw", "corpus": "ownir", - "digest": "98eb6b1074373135d1816a92864c8f6aff0c58679af25e3b2bd2d849129bfd3b", + "digest": "99bcaaa93bb259fe115d11643a85fb6af380b00e074db274a25ac80a68a4e855", "bytes": 1667 }, { "case": "flow_pool_partial", "corpus": "ownir", - "digest": "bf9e24dbce660556fb5028ec2927eccb288267beecab4c1f47065bc02bd27715", + "digest": "ae28b232cce3e2ecfcd8d944cf20ecd90f8e5864561731983a6be979a41299ab", "bytes": 1426 }, { "case": "flow_unmapped_refs", "corpus": "lowered", - "digest": "8cab4874d2309bbf2719a3a9bf14bcf9ef0ae91ca254811e3ab90c5986609f12", + "digest": "3ea7fdcdf96c70e08dbdc5fcb16548fd779490d06ce328d54037f0a4c6ef0071", "bytes": 245 }, { "case": "flow_while", "corpus": "ownir", - "digest": "eea40449080bab8241995977bd6bfcb16e12976b576f2b7f7101aab68b3f29a3", + "digest": "1ebbd1005ccab7c5e108355325310f49c9436060cd36c61c729744bd0f3e642e", "bytes": 255 }, { "case": "fn_params_ordering", "corpus": "lowered", - "digest": "bb0f0fa3ff63fec2871244f4ff21c42b3d9bb3a7999ebd37e331e3340cd9c015", + "digest": "78a60a440e4435ae4fa7f0b06298f62b952ae18f065a023a9e468b7c1d082269", "bytes": 479 }, { "case": "handles_global_counters", "corpus": "lowered", - "digest": "6822d42983b9130a9bb75265e31fc579ac3786a9f4a9afb11a0d6c0508a8558b", + "digest": "b2f933e7da5e9a0309af8e61ebb03b57cf9738625fb2ed9b8e31414d1a72df2d", "bytes": 500 }, { "case": "handles_null_metadata", "corpus": "lowered", - "digest": "924d57ab06917000b7ba05b04fedaddbdcc82ea586b0ae4c1836c59bf391f5e1", + "digest": "3f6dd0a9a38044099238cc387651d654b8918ef84baa43af5929cc53dc2dcd44", "bytes": 304 }, { "case": "handoff_contract", "corpus": "ownir", - "digest": "aea2a6cb9b81cd4efd70f577e2e163187bf461e883b29bb781e5ab1b17617319", + "digest": "51c0cac844a4bab7273d3cb74f2dc026a098096aa22d06ff797589ea26626085", "bytes": 658 }, { "case": "hoist_neg_early_return", "corpus": "lowered", - "digest": "00b86b9298b97dbc78b6152fb1865f36800a8ff2e672da7fd4b7a8e8a1fc4588", + "digest": "4389d525f749b0fa4d6e40f538c4b8e30187fc90c5ac32cb3897328b3242185d", "bytes": 226 }, { "case": "hoist_neg_nested_depth", "corpus": "lowered", - "digest": "f0baa68324567f1543eccdf08ba4ec91a20059311625d9bef6b8cf2bb1c7a055", + "digest": "d6c63963318b752c5a77ec0fe834cd57c7cd785f1479b0c5f586b4553b16c0a0", "bytes": 242 }, { "case": "hoist_neg_while_body", "corpus": "lowered", - "digest": "8f4807d8dd0a671659335446601ca8ec5db2c7e21bfd0c50164393f5e0478b0a", + "digest": "276f96bb65d9815d5c3aecea48fb0a618631911313f89cd72387604538843ced", "bytes": 195 }, { "case": "hoist_pool_kind", "corpus": "lowered", - "digest": "ff611d1b198ad3febbfab220c8c2b64fa5542cdb599c20c40aeb17701b38bb1b", + "digest": "5d32b311318922e6c42129c1debb86d18eb9bfebbdce90c42839cc2709ac4e40", "bytes": 271 }, { "case": "hoist_positive_release", "corpus": "lowered", - "digest": "1d04e37ca5ab97b1bd0baa47a4d41fd4176d142204ebc046958fed9e9a9d07bb", + "digest": "4bd10e1c7f8cd4cc58684b5b9aebb6d94b314f7d24d4528ec59453695d2ce678", "bytes": 233 }, { "case": "hoist_positive_use_only", "corpus": "lowered", - "digest": "155e1c1323bc0dfd414b41ef3cb1e4df01a92b72ec52e8d3af3f020aa409f206", + "digest": "0a93485945b436fd36598b60c953514f445cd74e6c79a84a47ff18d22acab59f", "bytes": 197 }, { "case": "lines_preserved", "corpus": "lowered", - "digest": "6c49de6c378938a2d3967a37ec3a8a5a584042f3d1c4700666157e1c69264bc6", + "digest": "6d32268601f0578dd29b3df2251274a9b72cd78f9237a27553dc7d6efda0ddc9", "bytes": 383 }, { "case": "local_disposable", "corpus": "ownir", - "digest": "128e51ecd78928f091c18bdf8730146cbaa4c020178b3d543df58874131e831f", + "digest": "c7eb316618cb2545ccab7347080347dbbc110a0403326f85d2243aa2815a1fa7", "bytes": 319 }, { "case": "mos_call_channel_overload_sig", "corpus": "lowered", - "digest": "88f8295d4e8c8627686e12a7a854233da12104755eca10e78932cf7249eb7b83", + "digest": "a9d36548d5ebb8a0801315f3b8a137cc3a5c0062fd643e4e5e00727ac402b2c0", "bytes": 601 }, { "case": "mos_call_direct_consume", "corpus": "lowered", - "digest": "e262529ab03eaee2d9720e2dfcfbac2291785bbfd9c5e937870fe87d78b87f63", + "digest": "ce38fff2a88e5ef28543ec4a256b55fd5eeed4e9cbe5803fa0192ab7d7fc9304", "bytes": 269 }, { "case": "mos_call_unknown_drop", "corpus": "lowered", - "digest": "03a7cf5bf7a61004779897db9107147602d36dd6a8c0ccc92dc7f6eb00ed72ad", + "digest": "59861777169097ce7b5e98f7bf1c02020bd94b0c7337efad8e07b37aa26291a9", "bytes": 245 }, { "case": "mos_fresh_mint", "corpus": "lowered", - "digest": "76651f7fb27bf41fdf0711e5fa41caa6a7245f4410774d6254c50833cb13bb4d", + "digest": "2fc84b6318f4b42d8c5b40b6281223ec76ad76cc933da0b03b087017a1481796", "bytes": 409 }, { "case": "mos_killsite_toplevel", "corpus": "lowered", - "digest": "7b082c4968589063a94944caaec515e9935098510c239673d85297040392f8b2", + "digest": "3acf0a6a262a22edc3492b5c1be4d23b7c5585ef133fb46edd3a4e3216e727c4", "bytes": 403 }, { "case": "mos_untrack_inbranch", "corpus": "lowered", - "digest": "065f5b2d64412dbf5d7a4aa88cc3e56d3bcdec63444ae349d316299a88ec3023", + "digest": "b8325e209d1046c3075859663f425d391f7fcea38794edffe9e65b9e1ac680de", "bytes": 410 }, { "case": "mosdump_degraded_duplicate_key", "corpus": "summaries", - "digest": "5d67d6918c18d93df76a29b2d58f50202444d3b95e2a7de6cca64541bb71e06d", + "digest": "07fc35882106a66285295b99374c3ed00e030cda1836bedbed07eae187733788", "bytes": 376 }, { "case": "mosdump_explicit_effects", "corpus": "summaries", - "digest": "6f1e70cf978838a74c41b26683af4baa0f780a6147888d2ef33ccc9725f10def", + "digest": "88cf374c5ff7f46bbcfe6d860dd68150fb8509e0db307c658114fd670b10c835", "bytes": 461 }, { "case": "mosdump_nonascii_escaping", "corpus": "summaries", - "digest": "2514d4aef9c1b78656d03bd79afec9aa197f12e6ccea178d1e959e94e4ed5e61", + "digest": "c1bab2458e76f3b1f207f40e0790d7da1174c1a74e2ca37a725064811a27c858", "bytes": 219 }, { "case": "mosdump_overload_merge_tiebreaks", "corpus": "summaries", - "digest": "ea7627b5b854c959f48cbe7606c728c3a55b199869e0cc33941279067c8f4042", + "digest": "635cb26ab31cc6bec196ffd6180253001e81802e0975ad3a6e929cd4232282e9", "bytes": 403 }, { "case": "mosdump_partial_and_guarded", "corpus": "summaries", - "digest": "83b3f724c3dfa41e0de104d9d5b68bf2cec8886ec8b5cef4b5e0103e5c825ff2", + "digest": "e02d2b93811eb584bd509a00e1025c517e8ed4a5dc71a3677588e8658a7a3fd3", "bytes": 525 }, { "case": "mosdump_return_chains", "corpus": "summaries", - "digest": "1ca46385a7b194fa197ae668a9d093036a338db13dde3fc9649c232db188e200", + "digest": "05fd00ae61ffa3e6b3c0021336aca06daf245573c2bf7599c94c7b7762ad735e", "bytes": 894 }, { "case": "mosdump_scc_cycles", "corpus": "summaries", - "digest": "fbdc666a60dcc512f968caa772efc366b53eae7b88f2f34eb7f8503880ba5c7b", + "digest": "db32b69c451f1bece0f4b28fd2a036047bdc779aa5e293827cd9c7cae69b20c0", "bytes": 655 }, { "case": "mosdump_sig_vocabulary", "corpus": "summaries", - "digest": "5803620f7c3c4099d4fa460faccee4f2632bf551be95909dfbf2a54014e6be13", + "digest": "12ecc73f7a769f843e6ce848b29fe58a5b90f92d5e9fb918892057edec256480", "bytes": 514 }, { "case": "mosdump_sink_channels", "corpus": "summaries", - "digest": "b42ffde2dd251354d30c072db40e471c0783c13b7e11a5809d52424052eefb88", + "digest": "88244ff3480e52fa2e53b6c4be3e04772472720a7a8ba7b6c1110a631631749c", "bytes": 440 }, { "case": "pool", "corpus": "ownir", - "digest": "8e18fd84acdaa4383c9c72d57ec184d448881cd2ae447284d4d1bafdb01e1399", + "digest": "b3c50414f4eecade77d0c7ba469680c3829270249dbfaaf0283171992d0c5390", "bytes": 241 }, { "case": "protocol_isloaded_clean", "corpus": "ownir", - "digest": "31025ef88e97214db901824cca982f64f98cc91c63b2029671347f4ee65eaa87", + "digest": "8215e298429a88bdb00981faf5fe1878a379c920bcb97229bef891d9176c549f", "bytes": 1193 }, { "case": "protocol_isloaded_violation", "corpus": "ownir", - "digest": "1025d2dadba8f7f00604e5d40a264d286a0d5cf62a243b16578fd00b3430d813", + "digest": "946c1e8200398dd311e1bca65ce69f9ec9b3c5ee82ebf6d0779f24f6774ffa75", "bytes": 1217 }, + { + "case": "proven_call_bad_section", + "corpus": "lowered", + "digest": "5b1e14263ee2cdebf2b873809280aadd7b59549d0bb637693004fcfbd2e6bd1d", + "bytes": 1836 + }, + { + "case": "proven_call_empty_callee", + "corpus": "lowered", + "digest": "5acb8bfaf4b592d5210d67be754c5f1bd5d5b982541dfb26bb59375214cac9c7", + "bytes": 1790 + }, + { + "case": "proven_call_missing_callee_record", + "corpus": "lowered", + "digest": "211d0f1bad62962530b164105fae70ffca539516a55e278c19612856f541c9f2", + "bytes": 1531 + }, + { + "case": "proven_call_no_section", + "corpus": "lowered", + "digest": "826fe707dfbf94329d65a624c3f5e474358660fc0388d4eaec3f89e587f5eb0a", + "bytes": 1059 + }, + { + "case": "proven_call_no_site_record", + "corpus": "lowered", + "digest": "4057c5b0cf4697dd0a5bd0f99caccfc0c2aaaae2087f374c8ff5e2b2485b826d", + "bytes": 1418 + }, + { + "case": "proven_call_outside_region", + "corpus": "lowered", + "digest": "52f70d1243d6a335355d5c4355fb3375e7f2374da0c6c62199f6394dc906aa53", + "bytes": 1836 + }, + { + "case": "proven_call_site_not_a_string", + "corpus": "lowered", + "digest": "f3d2224eca39e10294ae8e5d85c95ec9b967d0f9c4655b26a464413b8745dc6c", + "bytes": 1765 + }, + { + "case": "proven_call_unknown_callee", + "corpus": "lowered", + "digest": "bb3f9c8f85ae76fc20005e54de75b2ef0bc46f678b948b501922fe69c39335f7", + "bytes": 1845 + }, + { + "case": "proven_call_unknown_site", + "corpus": "lowered", + "digest": "009a69d4f22b81c3c170fd42294e5c8e838260806e39752d744f61d072b9c9be", + "bytes": 1854 + }, + { + "case": "proven_call_virtual_in_site", + "corpus": "lowered", + "digest": "3dd2983bf5d8da3adc069d34fd39702b887b237a3eba3a205b567632d0af752d", + "bytes": 1952 + }, + { + "case": "proven_call_wrong_callee", + "corpus": "lowered", + "digest": "215ddb433b3e4ef5de02ad38c2f00eeb818316fbe5ec26aad7d9ef31836e3651", + "bytes": 1837 + }, { "case": "routing_r1_unresolved", "corpus": "lowered", - "digest": "d1d165c2e00d1d312a8afa683917ac7805c48ada9e3a8680660a267012e4b5c5", + "digest": "e0c7059d5796f06e0914c6ccbc57e0adf18c5791b9177a623de8c40b7c941bec", "bytes": 171 }, { "case": "routing_r2_subscribe_self", "corpus": "lowered", - "digest": "4c675495f03c095a7ab785d90e625d6aa1781a52cfbd0fd68ad11fcd60e749f1", + "digest": "40f500498bb5be7c8793e02c5a417fccb5466e499c9e0d4e7cbd108012702693", "bytes": 208 }, { "case": "routing_r3_capture_static", "corpus": "lowered", - "digest": "7ef0b85183514bbf77a9df2694bb48320edc1f78da5bd3788e3336696685eee0", + "digest": "96634bdadb48b58447f82c4f1bc86da15519a6e63be72a4b8dcc146b405bf9c8", "bytes": 421 }, { "case": "routing_r4_returned_fresh", "corpus": "lowered", - "digest": "b60e041a1c4d5a9ba7c614e75d37ef10998c09ae3ad48fb8d63ce7b01a1e6c38", + "digest": "d726feea6d1aff1a2eace7d5a1a57f4e1a6fae8bf4f60eab7feeec1f60fff49a", "bytes": 358 }, { "case": "routing_r5_di_capture", "corpus": "lowered", - "digest": "ad071a1320ce2d33dc2b24e3fa3b87ad97a42bac3293a407e249b5a999c60258", + "digest": "07a0d98d65771b61a886d5032ab0256e5e466c2ca6e2a8a1c37c96c2a09e68be", "bytes": 511 }, { "case": "routing_r6_token_kinds", "corpus": "lowered", - "digest": "b9f462df47c6a5940281e06d5baa5de874587d737b1f818fc0fb6e727f7104e1", + "digest": "d27daf8b55c8c77e9b8c8f27b4c82f5ee5155a81c749b62098dd2f724eac00d1", "bytes": 675 }, { "case": "sample", "corpus": "ownir", - "digest": "74547157cb2ff329176205cd8e9227b9564d8f57c2f7ff0de99e07250e5db955", + "digest": "edfaf1c27d78731a739ffce2ea82dd9dab9ba66f11ce0e1417c0dc0afd0156d8", "bytes": 375 }, { "case": "subscribe", "corpus": "ownir", - "digest": "1fd329e0c89dc4934b2729c3abf8bad890ff989606820e1cf69c2aae0cd10982", + "digest": "9de577be6dd88fdf0623f68d045b6456796804ce1bc7d29dda6a0284ee28a37e", "bytes": 216 }, { "case": "timer", "corpus": "ownir", - "digest": "1689f54850d2f09a8ed66d1d24ca52e1bb8cef6bf62e648854b9837e58a3e029", + "digest": "95a4b4eaf487b1a2805726b9247e95d56a88af7482edba0feeefde5e57468355", "bytes": 379 }, { "case": "tolerant_unknown_kind", "corpus": "lowered", - "digest": "22a44716bf2ed49acdb8e373c516b4c86429f0db1bf5f4d8f503c02af384cbe4", + "digest": "de7137f0872e1d962eb7cf0e3f4ca582ed1d80617ab122102271bcb7cc64b5ae", "bytes": 150 }, { "case": "typestate_cs_a1_alias_of_entity", "corpus": "lowered", - "digest": "82f4a95de310c4646b7517d3b57bd6edfe3bc9c1c58bf885e501e097fac1e58f", + "digest": "dbf5bf7bb0cbcc1ba412661eec45e77f069524589442cc04e15c73b20d9ccaba", "bytes": 928 }, { "case": "typestate_cs_a2_entity_through_indexer", "corpus": "lowered", - "digest": "e7b606b6462ae08b09142b0089c0b7120f14ff0a83d0f7ff288d59a9ac28e79f", + "digest": "d6a68788e9cfef5018e6fc12c95616e53b748fe970354092f79f4c39cc9a211a", "bytes": 942 }, { "case": "typestate_cs_g6_capability_not_spent", "corpus": "lowered", - "digest": "ef4c3465e8a2b525c362e46a18a072f1cb64310a8ea13b357bbe5cfbd496e700", + "digest": "e6983a065e194034916c002427b68ca146bc776c8d41de709ad2b5efa5f4d7f0", "bytes": 521 }, + { + "case": "typestate_cs_h1a_harmless_call", + "corpus": "lowered", + "digest": "b5bb81e369dfa94f83a786527331aaac561c462668cd7aa6e8002876e8dde01c", + "bytes": 1836 + }, + { + "case": "typestate_cs_h1b_transitive_pure", + "corpus": "lowered", + "digest": "de3873ea79deba559ef4d72c9fcfc9f76443042a5bf7c1feed5e3b1a07a6bdbd", + "bytes": 2269 + }, + { + "case": "typestate_cs_h1c_pure_scc", + "corpus": "lowered", + "digest": "206a38c65566d574b670524497e1e0bce30e7d78eb5097e7d0b2cc232c46eb08", + "bytes": 2316 + }, + { + "case": "typestate_cs_h1d_global_state", + "corpus": "lowered", + "digest": "9ceac1fee3ad74c939829b56f893b6a52036d43d74acf50e0776da5204945321", + "bytes": 1849 + }, + { + "case": "typestate_cs_h1e_transitive_global", + "corpus": "lowered", + "digest": "c5a2a3541da31da742da60bd84bbd9a1ceca242be405c45fd77d72014abc6b2e", + "bytes": 2279 + }, + { + "case": "typestate_cs_h1f_polluted_scc", + "corpus": "lowered", + "digest": "c24ced4d509cc454265594d0445428b669cc20e035317fb7d77628b67496e019", + "bytes": 2399 + }, + { + "case": "typestate_cs_h1g_transitive_unknown", + "corpus": "lowered", + "digest": "16f5efdcd712704b5082b9eb05050f6b8bf99c313302543988f49533d14e9ee3", + "bytes": 2016 + }, + { + "case": "typestate_cs_h1h_mutates_entity", + "corpus": "lowered", + "digest": "c48760e33b69de88af2e4e99894a459c8b22e0c2fece07c6fbdcb84f64d78fdc", + "bytes": 929 + }, + { + "case": "typestate_cs_h1i_escapes_entity", + "corpus": "lowered", + "digest": "abfa299623dde99ab5123f1e66c43ea07f5ac0511844cc4637f2e0fcacb860f1", + "bytes": 929 + }, + { + "case": "typestate_cs_h1j_mutates_outer_value", + "corpus": "lowered", + "digest": "29fea6ad55077a45b84215b6c0715e3061240881fb7b1ba46ac4e95fbbf1c0b1", + "bytes": 1941 + }, { "case": "typestate_cs_l10_region_inside_try", "corpus": "lowered", - "digest": "8e5cbb0fec8d12d14589d77f7432bc73f2f114357d7bee82fcc61bafc69d0ab8", + "digest": "b508cdefaf72f5785cec3812f35608ad57d9b28395eb98102fd952146bc98557", "bytes": 897 }, { "case": "typestate_cs_l11_region_beside_disposable", "corpus": "lowered", - "digest": "24a25a98be12223eb1c46244fab02489fa0279f1b852bb55cec8c0bd4babe639", + "digest": "76d266876c73ecd5a8d435410d30861014acda7a94bbe9e84f6ec5fc2dad9c73", "bytes": 1250 }, { "case": "typestate_cs_l12_region_beside_leaked_disposable", "corpus": "lowered", - "digest": "1f854d323f991c27c697c58f96768bf6d13d8d59d01f92f4d716745da794c467", + "digest": "3f3d811d6164784c33f58e67507f62c3822f9eb7e84773a51f497f42332d27ce", "bytes": 1237 }, { "case": "typestate_cs_l13_values_captured_into_region", "corpus": "lowered", - "digest": "3c0912f100d55c783873bb54361d9a6e1a369df110462408da4bff5d1b34ec69", + "digest": "247443e929b81c553f0e3dca0d789614e7664bfd504e2111518ed7582df8c440", "bytes": 1107 }, { "case": "typestate_cs_l1_stale_capability", "corpus": "lowered", - "digest": "ab9295ee55b27c9cf3009f0714f8b27170bba776a93a3c56575c9e7b6f893888", + "digest": "c14a554deab4fd91db76ea2d413c1b005a527a73354082135c87ad606d6ee173", "bytes": 1695 }, { "case": "typestate_cs_l2_copied_capability", "corpus": "lowered", - "digest": "064172fda48442fec636584b1642d94a382aa5410b8f67de9f6fe2c5164c58cb", + "digest": "1ccc6cb551a92c284b9f4db1de5051319108e87e965dbcbbe060f7135a582d24", "bytes": 1045 }, { "case": "typestate_cs_l3_raw_mutation", "corpus": "lowered", - "digest": "15c824bb3c749f78a1c14331f5092977479e15be6ffdfce719bcc8d70ba53498", + "digest": "3879923e0c1d9ea1b18317aef2157f378800e94c90eab42215a21a3f4959428a", "bytes": 923 }, { "case": "typestate_cs_l4_raw_escape", "corpus": "lowered", - "digest": "c342366a634db5f0ef31cc3edf35860c7e36b78b59643550961b617c21c5718f", + "digest": "f9434eacb5617c3b91b6a81fe98e4ebfd086e67aeb7824288ac42ca9267ba45c", "bytes": 919 }, { "case": "typestate_cs_l5_normal_transition", "corpus": "lowered", - "digest": "fc645e613bce7fd4bc85951c2b2cd5ac86e727c9eb422810f08ca9ebaa6628c8", + "digest": "850871c4fb098677d7943bf22c3404f37ff79f60dfb3fec2151fcc308f6c5841", "bytes": 896 }, { "case": "typestate_cs_l6_two_transitions", "corpus": "lowered", - "digest": "96bfa97439d1f8ee4dc855f029c3c5a57088bd97492915df4b27f602fe300c49", + "digest": "dfd4e191f4b2aeb28a39312e28cbc2d2b36a7e8199687738954d1b3cfaee1493", "bytes": 1318 }, { "case": "typestate_cs_l6b_chained_transitions", "corpus": "lowered", - "digest": "8cc7bf2bc99e27de18416db155c5949433707b0b795f546982386a6441e7ce12", + "digest": "585c4db151657cc30421da4e1e263e36c3490876ea911fd254a2a079e469d39d", "bytes": 1316 }, { "case": "typestate_cs_l7_read_after_region", "corpus": "lowered", - "digest": "19c9148385ee6ea47086a927c97323eb646e47cd94271d7020198c56409f3daf", + "digest": "2dca77f3870b34643d2b3391cf013e6c9629f55c9dd35640a85f888ed2db04c0", "bytes": 895 }, { "case": "typestate_cs_l8_branch_inside_region", "corpus": "lowered", - "digest": "4ecb5a073972e2ded095ac1eed365c2db4f1794d4ed1eb331657e25e04feba88", + "digest": "0345b7193ce37a5764f4cc84921fdfc9fc189bba785945ec10420b73a33eb0ab", "bytes": 1093 }, { "case": "typestate_cs_l9_opaque_calls_around_region", "corpus": "lowered", - "digest": "adfc9ac66558d84d79360ea4654c8ac4ca3cc5aa6f1f21eb556e40f9d526fdcf", + "digest": "ddf0d2a2c4ac27572f2353191ddfc1c2c0c2de5cb756c2a8ba1fc5fec4517fcf", "bytes": 912 }, { "case": "typestate_cs_x1_nested_region_same_entity", "corpus": "lowered", - "digest": "28fbaa59b3087ed3261c36f5e8e17e1efceddccabc14f2956c2e31eec273d93d", + "digest": "eedeaff8cda0f50f1e5445ae409faa1c0a6ec5b00fa6a76af3f1083165e0fb75", "bytes": 1407 }, { "case": "typestate_ef_orderbackend", "corpus": "lowered", - "digest": "64fcc2e1bfb81147e463666c77fdecdb9b606527cbdc90fe5f6a0342bdb9a2a5", + "digest": "056f2ff6e422a7ab46823a3643938363c10ace9ca98b021ffc5225ac100367aa", "bytes": 3796 }, { "case": "typestate_g6_capability_not_spent", "corpus": "lowered", - "digest": "6fc85ee6d17cf09a6614f23a3c566b6c7db1e897df4ad1fa7738557197710c1b", + "digest": "191a771e45f5369972445647f28f5ce661fb75b3f1c5069a18759d68b000f8e3", "bytes": 1413 }, { "case": "typestate_l1_stale_capability", "corpus": "lowered", - "digest": "930619b44065043eb7a91379f7f2cb84f21f467ee7deae7f1683b392ec74c12b", + "digest": "ab82dff82480c4904b63a14a140dd0086d9942374eec8af7e3de047198104ed1", "bytes": 1536 }, { "case": "typestate_l2_copied_capability", "corpus": "lowered", - "digest": "5e0436c98d213fddad7c135a2ba0a9fbcd0e71eef830a13f325223f57d565153", + "digest": "8ead3bbae679bcd20d098895a31d955f7b1f12465be75e5787d5d67dc300418b", "bytes": 1585 }, { "case": "typestate_l3_raw_entity_mutation", "corpus": "lowered", - "digest": "5f2a4467308b602eab4545156f12dc725072fc23c4b79414b8cb8107a492f86d", + "digest": "e6725b7fa5dd5db18201d8a9e175fa0a9dd51d4eac7624571c9c2dd5ce9a0f09", "bytes": 1534 }, { "case": "typestate_l3b_second_region", "corpus": "lowered", - "digest": "3195d8ce58c7a6eb206a6ee1244bab49e5118e68fff0261f3902df3f19787038", + "digest": "97f0e88837724189f958a9a833844875b882e6eaee3c90b4472a9706d7dc9c7c", "bytes": 1601 }, { "case": "typestate_l4_raw_entity_unknown_call", "corpus": "lowered", - "digest": "9e3a7a14fe8deefe265e929d7c51f0d9cd4da2c71e1c065444c0c3ff665e42d6", + "digest": "9343f182014716a93328e7777eded446a8b9861112bc8fa5b4c7985e8dba4aaa", "bytes": 1530 }, { "case": "typestate_l4b_raw_entity_shared_call", "corpus": "lowered", - "digest": "08d2b6968d802c685faeca531f2af0d4d6ad213662f91073144c0e17aed543e8", + "digest": "b7e4cfee6847f0c4f73d06f7c1cac865e75b3e27bc90b3718a053527622a69d8", "bytes": 1527 }, { "case": "typestate_l4c_raw_entity_consumed", "corpus": "lowered", - "digest": "4e6a05dbdfb7a2450d3ebc93eb448b6acae0372ade2d31d21c35a88b8eac2d1f", + "digest": "a07111fd5a4c088f095141f761809ab458dc1ac540d431af5c5e07a91464cdaf", "bytes": 1487 }, { "case": "typestate_l4d_token_unknown_call", "corpus": "lowered", - "digest": "c48148d384e05b06c5070e3c0bc89186740bf27588b069894ed4cc865af519ae", + "digest": "2aac4e678401a718b4cf50a68376ae6da4e28115b831c766d5bbce505166105c", "bytes": 1526 }, { "case": "typestate_l5_normal_transition", "corpus": "lowered", - "digest": "28b2a5e8152aa574a07f449056d60f06cd48da5e1ff49f50940bd01199fdf383", + "digest": "e579aa715ba1f7f29c90b4b1cd2903f32759e5ddbfffc692cbdc3d3dc62d2c78", "bytes": 1470 }, { "case": "typestate_l5b_two_transitions", "corpus": "lowered", - "digest": "cc0bb549463056b5eef0aa9a4fd04ffa8d72adb4f4bb32305c09110e061ffe12", + "digest": "bbc6a7cdf0fda9e32c326196bdbb3b5ed3efd3edeadc781520986a50fe079d03", "bytes": 1569 }, { "case": "typestate_l5c_read_after_region", "corpus": "lowered", - "digest": "52783299f4959c94d4ed5f549f9cd3fbdfe163fa4698807d46d7d9201fdf6652", + "digest": "8c9ff6ea7eff66505456c696dfea6198bbb60d73eac628ded2ab3d7125de26d4", "bytes": 1527 }, { "case": "typestate_n1_token_spent_on_other_entity", "corpus": "lowered", - "digest": "008d1e473674853be2eb7f4ce27047c3a0db3ec4d1344138d38dddfa86cccaa3", + "digest": "9682d5d9b59cbd28d4f6946bfb65916896be587fae9124e7559ec3a9bebfa35e", "bytes": 1606 }, { "case": "typestate_n2_two_tokens_one_region", "corpus": "lowered", - "digest": "7e478c42d5750c276800fa1e5a3599903f01aa492db6633597dbae5a2b587a99", + "digest": "1d170b7d61ac66311107704cb29553225d1b31c3d0c9102e7bd4328a3da45753", "bytes": 1581 }, { "case": "typestate_n3_raw_mutation_inferred_effect", "corpus": "lowered", - "digest": "8195d3b979b6baa824402f891ff95428a4a0f28d2508f14b887b58e7df0dd2e9", + "digest": "799fe7d3aea58951cbeff3d262f19294657a51fb66939ec339ae8746815369cc", "bytes": 1613 }, { "case": "typestate_n4_token_outlives_region", "corpus": "lowered", - "digest": "34cd617242d25cbd6649a0351f4934a5bad835b025a62aeb4efe53cb8218c36d", + "digest": "56fbfdddeb503f55a65f85a45bff61dea75d6a880f2c0b4603d799945e237c67", "bytes": 1538 }, { "case": "typestate_w1_loan_wordings", "corpus": "lowered", - "digest": "fa2099dab08f4d510f0d3175d62ccad9b704d99bba5da31ac4b1de64847e7eb6", + "digest": "3139a996e36f5a95a696d617441823a7ced98e5bbb89fd270639aa574430d124", "bytes": 1712 }, { "case": "typestate_w2_loan_wordings_pooled", "corpus": "lowered", - "digest": "c112f0ac827146734d2d89ee70a77e9629893ad100122beacb3063a4d2051f34", + "digest": "fbc58ddf1bdcde03fe9868dd905959ac254308011b7b604a3e6d78851ae2b5d7", "bytes": 1796 }, { "case": "unitofwork_flow", "corpus": "ownir", - "digest": "f40ec31aeb8c76fdf377cd8f8e9ac7f8b8e345fcf7a2722c30f2732b583de0a4", + "digest": "c95ae72590657b6d1794c2ae05678f0beeece27e7ef876f31c4a7d76c3361b49", "bytes": 324 }, { "case": "unresolved", "corpus": "ownir", - "digest": "ada74fec0dfc74dbaba397622f4b8aa86766d1398b4ae3ea95fd9a5903f67c30", + "digest": "6f73c63b610f89cef8e31ddf508dc8e89e5e607a8a199c16f9f3732d40058e30", "bytes": 309 }, { "case": "verdict_boundary_effect_line_negative", "corpus": "verdicts", - "digest": "b3385658d5e763c4a3c14ad3f1e338826df85554f072e8f571966a31ce854c00", + "digest": "e5f971271e5a93d5016ffa84af2cc03b624770a3303758a37bf68353f2b0bbfd", "bytes": 336 }, { "case": "verdict_boundary_line_above_u32", "corpus": "verdicts", - "digest": "592b6343827472c8b8a1e9356441f730f940841abec3515ae3361c5be32f71eb", + "digest": "13a2dae251f4d273cfd0a6891f31e1f0e922b3f71413a046fceac0df379abfa2", "bytes": 434 }, { "case": "verdict_boundary_line_negative", "corpus": "verdicts", - "digest": "051678520a5b3c8a926ea635db29560b4eb14424d1e3f15691a28aa9c22a4315", + "digest": "5c72d27baa3f50444b8484d5e5595781b9905fbd9fc10de988c82f7a30e32107", "bytes": 541 }, { "case": "verdict_boundary_service_line_negative", "corpus": "verdicts", - "digest": "5fb548d3e58c11a19d8894a6d6406ea1c8469ce7644977d3c0297fb5b43b88c2", + "digest": "284ef720a904ee1754bad4a0697002ec4e1fd1491dbbbd263c7400865048cb8b", "bytes": 480 }, { "case": "verdict_column_sort_order", "corpus": "verdicts", - "digest": "2c3f97e4065a1f0ff00732ef10dd2238523d14d4e6105ce863b8537123380aba", + "digest": "0956d98e8604b73bbabc80208bfa9a0558763969f806bbdff9abae1ffaffc1a6", "bytes": 960 }, { "case": "verdict_dedup_key_members", "corpus": "verdicts", - "digest": "80e51b34954837db6d2e62c6c700732b7f24e09dc01dbadf078d2a1b8afcd075", + "digest": "de0e91fe28f879dd96ea270b622e8da8930f9de2ff3cb32c8fe840ba830841ac", "bytes": 973 }, { "case": "verdict_dedup_needs_the_message", "corpus": "verdicts", - "digest": "6062283edcf11bf49a3464872121f0d73daa269b49f979e1fe1b5ab35c0cec52", + "digest": "6d86aeea1dcb9b7ac7c0d8db02fe197eb805124679e586d3d9327c087a1cdc3d", "bytes": 663 }, { "case": "verdict_degenerate_metadata", "corpus": "verdicts", - "digest": "31895c280f2ec7cc7072c60b238c0b3346f63b5a3d6acdf066b2a3e0aabcb461", + "digest": "4dd524e6c2119a32f6ff4a68242589537956fdb3e8a848a920670498205413cd", "bytes": 856 }, { "case": "verdict_di004_call_site_anchor", "corpus": "verdicts", - "digest": "2bab34529d15196ab3aa1a260e84f2f851a74b7b585430da49e19ef616ebd1f7", + "digest": "5d580776359f2d389d496049df7fbc454e6412213ef532961616a37a89281c22", "bytes": 1410 }, { "case": "verdict_di005_cache_site_anchor", "corpus": "verdicts", - "digest": "9c36e23eecc9f737ce4df8e4437e52c6c5ec856a1914269d67675982eefe4236", + "digest": "6d8d1db8912c4a7a3088bc43d8e3cead161ad3e0737dd480167d46df625d388f", "bytes": 1137 }, { "case": "verdict_di_duplicate_sites_last_wins", "corpus": "verdicts", - "digest": "10904137f0d7efdcf79ef99052ae57f10a9cab99d3c9a09e7bcdd9a0566c25e0", + "digest": "b3e92b4d7232bdefdd03551cb4fa63c0e2e7a314319121fbcff76d3ccff47d91", "bytes": 1888 }, { "case": "verdict_di_evidence_degradations", "corpus": "verdicts", - "digest": "37a0e719e16d2c256ca3b9f27e0af509156d9a8b0046aa9e1a064842f340498b", + "digest": "e126967d5c2f94998ff0d156bc759aba45094470daf0bbb353d9cf7ed9bb9da8", "bytes": 851 }, { "case": "verdict_di_graph_families", "corpus": "verdicts", - "digest": "dd691c530acb0667019af74adea6e1fe6076afe5249a30678063b78e249229ce", + "digest": "084d9a3c5ca2deb6420691fb6b9ff9e408ffab67e8703f5150001c163eb9f455", "bytes": 1077 }, { "case": "verdict_di_tolerant_typed_coercions", "corpus": "verdicts", - "digest": "398d4f6271fd938ec4f11682d5cf1e881c7d52bc7475cd0529ced60847c910d1", + "digest": "0f4d2ef05fbef4766bb2cbe821fb6bd4ccf67aa03259be2622cb18ad0c54d5f1", "bytes": 901 }, { "case": "verdict_domain_tolerant_readers", "corpus": "verdicts", - "digest": "6da7a9a361830a55d2ab2d32eb05290be3fc93f3323efe72a3650ca4b71a4019", + "digest": "cd26d08305ed9189cf94924be7b5b1160ce08d2c86368b27daeaa419bb0927e6", "bytes": 1307 }, { "case": "verdict_door_effect_deps_not_strings", "corpus": "verdicts", - "digest": "b85df11e6d8bd400d38b209009a3517bce2bce543e65fd2faac863dcfd057cf1", + "digest": "3e2c8ccf546f0722262d8783368939732046902c669d6ad2db6ab9ca71880d8c", "bytes": 622 }, { "case": "verdict_door_service_unknown_lifetime", "corpus": "verdicts", - "digest": "e7820a76b22a9c562e7533d3f429ee16535c85bef592209d4466dcfa9d83f613", + "digest": "d55ad1e0ee0126a05601c0f719c178d26f9fcb0f67d2b1cf902738c1b1646526", "bytes": 541 }, { "case": "verdict_eff001_slice_dropped", "corpus": "verdicts", - "digest": "08def69c7e11a67c510b08cc58e6541bdbd9667a548a253c3f39145991ae6cd5", + "digest": "fc6d077595597706645ae421079c53119b19e350c2da7170dbd01b8ed07c400c", "bytes": 417 }, { "case": "verdict_eff001_storm_and_memo", "corpus": "verdicts", - "digest": "94ed663fe27fa19b913bd7cb1696040b5043d908c71995c53ae944d40634a8d3", + "digest": "0c7866d3c980ea9fb0ff679bf98810eafadfc5b03604bfdb90747099658f6b45", "bytes": 1054 }, { "case": "verdict_flow_local_wordings", "corpus": "verdicts", - "digest": "9f4f197a3efb607880a2e75a7425c45f8672f06f8f2c43eeba117a4bfb16b60a", + "digest": "a83142a5990617a9a7d54f8c1360904dcb73578399439d4ec4a8ad9ee1c4e3ee", "bytes": 1273 }, { "case": "verdict_multi_file_ordering", "corpus": "verdicts", - "digest": "e111eabe5fbd8fcb152fc4b28b2ab5b4fdb8b92725ea240349c27389837bf8e0", + "digest": "555666cfc3f7ea7f9e00131f6283c5ca5d7efcd699a74e2ffc8667f148d539a5", "bytes": 1036 }, { "case": "verdict_own014_escape_slice_dropped", "corpus": "verdicts", - "digest": "666dc9182ccbb4adc9b6122a90a59b6b38534d22e7f27061289f343c4cfe9b46", + "digest": "65813f387aa5ffae1ba5380f37b9781c91d5f24be29b135a0cec35d35c4d0cab", "bytes": 598 }, { "case": "verdict_own014_wordings", "corpus": "verdicts", - "digest": "fefa681ee9eda9ed9161d8bf66cfddd865fcc5114b83a200a8fd83e66d048e56", + "digest": "66d789ca0336eb1e8ae064dd10045efa9bc8f138237278eaff9fbe536b2e1f96", "bytes": 1035 }, { "case": "verdict_own051_gates", "corpus": "verdicts", - "digest": "4590bdda62b257e16b225991ca1203e050e2627905346ea55d793cdced15b5a2", + "digest": "590e913b140b90d2f199ec4c11b74dabcf04e989df05049cd9595caf6b860c5f", "bytes": 1262 }, { "case": "verdict_own053_orphaned_awaitable", "corpus": "verdicts", - "digest": "8c3a714def4bd36329fc4d88ae157c98c90ea354a67859815fb3408686441304", + "digest": "bd5813506b6b101a6dbe69a692ae669f69f628a6e441c48671f65aedf369c65c", "bytes": 1980 }, { "case": "verdict_pool_view_anchor", "corpus": "verdicts", - "digest": "0c425103a62f8d845d620663d8fbe067e80c2967d9505d7f72466c8840fe549a", + "digest": "ac93bfa8e9d9c3ac513e06757d3a6792ec8a6b83d9bda0c8b3d985243f1a3b0e", "bytes": 493 }, { "case": "verdict_protocol_absent_rules_are_silent", "corpus": "verdicts", - "digest": "cdea8afef32c64801071e43fd6d2cc1bff323372640b3b7801818795b2559bc0", + "digest": "da55005a56b580ae96ad9f2c9cde62f9a17c939686206bab84b9a4f29a38d449", "bytes": 1158 }, { "case": "verdict_protocol_barrier_maybe_two_step_slice", "corpus": "verdicts", - "digest": "40328aaf2b11a6c715eb9a873f39562788fef78b22c0d62363d78cb072ba955b", + "digest": "90563dfdaa1b175f8119bb6b4b12380e03abf8412f3ea6b7147f107b305aedba", "bytes": 1309 }, { "case": "verdict_protocol_beside_other_families", "corpus": "verdicts", - "digest": "30dea8e128ba72742004db04be010e7424b79ae82d3c76b58cd9abc704c7ab7c", + "digest": "d30f4eaa457228997da832bca77cc5a7a0ccf8f68f6d69f5977516b5a3d6f0b3", "bytes": 1709 }, { "case": "verdict_protocol_exit_codes_and_wordings", "corpus": "verdicts", - "digest": "8533d5e4452f7c353cc81ce0ee4bb1ba7df3267edf5830737aeee90f9d786629", + "digest": "d952759e4019d68bd8c85d4cc5f32f09043d9c3e1a32204f25af3da63ed5fdfb", "bytes": 1679 }, { "case": "verdict_protocol_identity_and_line_guards", "corpus": "verdicts", - "digest": "326c47e5ee40b908ae49481c2afdd4647fb29b5f10d8a4770af58d52869fc0f1", + "digest": "09f8f6b9c43a979bf611a460dc5fb4e97665498d83596e3512797fdedccdd9d7", "bytes": 1771 }, { "case": "verdict_protocol_obl005_dead_rule", "corpus": "verdicts", - "digest": "b33de9a202cde29dce6c253c33860af9aebe6e639b03817699712bf4373c715f", + "digest": "c39adc066b2e83b570144b9ad1280196f9108f3811f348c39ba102ce30509fb8", "bytes": 2220 }, { "case": "verdict_protocol_tolerant_door_rules", "corpus": "verdicts", - "digest": "1816d2f2c5e90d64fda2b8edb55d946ac6091fcd6840d74c3c8e03432c444fb0", + "digest": "4ef3b7bce7a59dab8cafe3edf64e414151f72408881287961ac00b13459700b4", "bytes": 2018 }, { "case": "verdict_same_site_distinct_events", "corpus": "verdicts", - "digest": "2e4358f94b476b9abb5e655d263cfe3e385b0b66fbb626910df6933a1f11967e", + "digest": "385fb22fb9ad4c00195a13439b44c3c52af7785c554c7a6a7c4eac47779a4e5d", "bytes": 1543 }, { "case": "verdict_severity_tiers_and_suppression", "corpus": "verdicts", - "digest": "b769397a6dd2afbfdf5ccbfe7300fee31b5c5b2824288389db0e19f4630bdd29", + "digest": "ec712158d2d89b9ab1e8022f9e4952c5b7a8a777d093ccd2752ba4a9a63618d7", "bytes": 1916 }, { "case": "verdict_skip_list_artifacts", "corpus": "verdicts", - "digest": "a7db24c76096b3d1214ede7180abcc542f0c460bb0e1e3156cfcc7a41ef79b76", + "digest": "ba0bda34d5cab71ed7195bafc3ee17065272aba472af06f21c59627af67ef8e9", "bytes": 1460 }, { "case": "verdict_subscription_lambda_note", "corpus": "verdicts", - "digest": "1b3566896123392c76e5b5694b12a68db5c2ca613821e81b0bc44dfdf522199a", + "digest": "def4f3cdfe1551effdae696b3c314f1408bf49f7fe01d75e25fa65d74b0d96a7", "bytes": 589 }, { "case": "verdict_unknown_line_guards", "corpus": "verdicts", - "digest": "188ca5752faf2f440513511c65ac823ce48c69bf8effa7af403516f7c0bde9aa", + "digest": "9d2bdc039055baf269cccc5f562195e09e4af211617ab3e15e135f606eefc7d4", "bytes": 1216 }, { "case": "vocab_unknown_op", "corpus": "lowered", - "digest": "866a9d0b4bf4898bbcb2a52b9522201efea52c0a0ff7a75ee2963ad4c88851a9", + "digest": "4d49f08eed0965cb7176da0b9ceb5273d9383cfa6da0bc685a3e7f530a6a23e2", "bytes": 108 } ] diff --git a/tests/fixtures/repro/domain_exponent.facts.json b/tests/fixtures/repro/domain_exponent.facts.json index 641ad6a3..08fe2956 100644 --- a/tests/fixtures/repro/domain_exponent.facts.json +++ b/tests/fixtures/repro/domain_exponent.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DomainExponent", "canonical_probe": 1e3 } diff --git a/tests/fixtures/repro/domain_float.facts.json b/tests/fixtures/repro/domain_float.facts.json index 10ece038..9cbc382f 100644 --- a/tests/fixtures/repro/domain_float.facts.json +++ b/tests/fixtures/repro/domain_float.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DomainFloat", "canonical_probe": 1.5 } diff --git a/tests/fixtures/repro/domain_int_above_i64.facts.json b/tests/fixtures/repro/domain_int_above_i64.facts.json index 9ee63f5d..9e3b5460 100644 --- a/tests/fixtures/repro/domain_int_above_i64.facts.json +++ b/tests/fixtures/repro/domain_int_above_i64.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DomainIntAboveI64", "canonical_probe": 9223372036854775808 } diff --git a/tests/fixtures/repro/domain_int_below_i64.facts.json b/tests/fixtures/repro/domain_int_below_i64.facts.json index b1fb1c19..798bba6e 100644 --- a/tests/fixtures/repro/domain_int_below_i64.facts.json +++ b/tests/fixtures/repro/domain_int_below_i64.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DomainIntBelowI64", "canonical_probe": -9223372036854775809 } diff --git a/tests/fixtures/repro/domain_negative_zero.facts.json b/tests/fixtures/repro/domain_negative_zero.facts.json index 6d336d98..2b26095e 100644 --- a/tests/fixtures/repro/domain_negative_zero.facts.json +++ b/tests/fixtures/repro/domain_negative_zero.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DomainNegativeZero", "canonical_probe": -0 } diff --git a/tests/fixtures/repro/domain_non_finite.facts.json b/tests/fixtures/repro/domain_non_finite.facts.json index 3e33dbf1..4a61257a 100644 --- a/tests/fixtures/repro/domain_non_finite.facts.json +++ b/tests/fixtures/repro/domain_non_finite.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DomainNonFinite", "canonical_probe": NaN } diff --git a/tests/fixtures/repro/hoist_neg_while_body.repro.json b/tests/fixtures/repro/hoist_neg_while_body.repro.json index 7d0ee0c2..89444c04 100644 --- a/tests/fixtures/repro/hoist_neg_while_body.repro.json +++ b/tests/fixtures/repro/hoist_neg_while_body.repro.json @@ -1,20 +1,20 @@ { "repro_version": 3, "input": { - "ownir_version": 1, + "ownir_version": 2, "raw": { "algorithm": "sha256", - "digest": "a7f863be7b028758543a21c7981207f446de936b37927a3cb1d0bac5289fb977", + "digest": "7436b450cd1341c81ca6572e7dabefaff5c4ab8baddbff95c17310255c52ff7c", "bytes": 446, - "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMSwKICAibW9kdWxlIjogIkhvaXN0TmVnMiIsCiAgImZ1bmN0aW9ucyI6IFsKICAgIHsKICAgICAgIm5hbWUiOiAiTSIsCiAgICAgICJmaWxlIjogIkYuY3MiLAogICAgICAiYm9keSI6IFsKICAgICAgICB7CiAgICAgICAgICAib3AiOiAid2hpbGUiLAogICAgICAgICAgImxpbmUiOiAyLAogICAgICAgICAgImJvZHkiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAib3AiOiAiYWNxdWlyZSIsCiAgICAgICAgICAgICAgInZhciI6ICJyIiwKICAgICAgICAgICAgICAibGluZSI6IDMKICAgICAgICAgICAgfQogICAgICAgICAgXQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgIm9wIjogInJlbGVhc2UiLAogICAgICAgICAgInZhciI6ICJyIiwKICAgICAgICAgICJsaW5lIjogNQogICAgICAgIH0KICAgICAgXQogICAgfQogIF0KfQo=" + "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMiwKICAibW9kdWxlIjogIkhvaXN0TmVnMiIsCiAgImZ1bmN0aW9ucyI6IFsKICAgIHsKICAgICAgIm5hbWUiOiAiTSIsCiAgICAgICJmaWxlIjogIkYuY3MiLAogICAgICAiYm9keSI6IFsKICAgICAgICB7CiAgICAgICAgICAib3AiOiAid2hpbGUiLAogICAgICAgICAgImxpbmUiOiAyLAogICAgICAgICAgImJvZHkiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAib3AiOiAiYWNxdWlyZSIsCiAgICAgICAgICAgICAgInZhciI6ICJyIiwKICAgICAgICAgICAgICAibGluZSI6IDMKICAgICAgICAgICAgfQogICAgICAgICAgXQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgIm9wIjogInJlbGVhc2UiLAogICAgICAgICAgInZhciI6ICJyIiwKICAgICAgICAgICJsaW5lIjogNQogICAgICAgIH0KICAgICAgXQogICAgfQogIF0KfQo=" }, "canonical": { "algorithm": "sha256", - "digest": "8f4807d8dd0a671659335446601ca8ec5db2c7e21bfd0c50164393f5e0478b0a", + "digest": "276f96bb65d9815d5c3aecea48fb0a618631911313f89cd72387604538843ced", "bytes": 195 }, "document": { - "ownir_version": 1, + "ownir_version": 2, "module": "HoistNeg2", "functions": [ { @@ -47,7 +47,7 @@ "id": "python-ownlang", "consumed": { "algorithm": "sha256", - "digest": "a7f863be7b028758543a21c7981207f446de936b37927a3cb1d0bac5289fb977", + "digest": "7436b450cd1341c81ca6572e7dabefaff5c4ab8baddbff95c17310255c52ff7c", "bytes": 446 }, "layers": [ @@ -201,7 +201,7 @@ "document": { "degraded": null, "module": "HoistNeg2", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", @@ -239,7 +239,7 @@ "id": "rust-own-bridge", "consumed": { "algorithm": "sha256", - "digest": "a7f863be7b028758543a21c7981207f446de936b37927a3cb1d0bac5289fb977", + "digest": "7436b450cd1341c81ca6572e7dabefaff5c4ab8baddbff95c17310255c52ff7c", "bytes": 446 }, "layers": [ @@ -393,7 +393,7 @@ "document": { "degraded": null, "module": "HoistNeg2", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/repro/hoist_neg_while_body.trace.json b/tests/fixtures/repro/hoist_neg_while_body.trace.json index e65040a3..55e37c45 100644 --- a/tests/fixtures/repro/hoist_neg_while_body.trace.json +++ b/tests/fixtures/repro/hoist_neg_while_body.trace.json @@ -7,7 +7,7 @@ "engine": "python-ownlang", "input": { "algorithm": "sha256", - "digest": "8f4807d8dd0a671659335446601ca8ec5db2c7e21bfd0c50164393f5e0478b0a", + "digest": "276f96bb65d9815d5c3aecea48fb0a618631911313f89cd72387604538843ced", "bytes": 195 }, "layers": [ @@ -194,7 +194,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", @@ -233,7 +233,7 @@ "engine": "rust-own-bridge", "input": { "algorithm": "sha256", - "digest": "8f4807d8dd0a671659335446601ca8ec5db2c7e21bfd0c50164393f5e0478b0a", + "digest": "276f96bb65d9815d5c3aecea48fb0a618631911313f89cd72387604538843ced", "bytes": 195 }, "layers": [ @@ -420,7 +420,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", diff --git a/tests/fixtures/repro/mosdump_degraded_duplicate_key.repro.json b/tests/fixtures/repro/mosdump_degraded_duplicate_key.repro.json index 27f0e7f1..827f0182 100644 --- a/tests/fixtures/repro/mosdump_degraded_duplicate_key.repro.json +++ b/tests/fixtures/repro/mosdump_degraded_duplicate_key.repro.json @@ -1,20 +1,20 @@ { "repro_version": 3, "input": { - "ownir_version": 1, + "ownir_version": 2, "raw": { "algorithm": "sha256", - "digest": "60debca1e8aede04c2048c023af7f29a7af41131d9b081abaace6d40761bfae5", + "digest": "2debe3d9444ec820586745713e75f484dd00909b6276045d7ad73ed8e683df70", "bytes": 747, - "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMSwKICAibW9kdWxlIjogIkRlZ3JhZGVkIiwKICAiZnVuY3Rpb25zIjogWwogICAgewogICAgICAibmFtZSI6ICJUYWtlIiwKICAgICAgInNpZyI6ICJTeXN0ZW0uSU8uU3RyZWFtIiwKICAgICAgImZpbGUiOiAidDEuY3MiLAogICAgICAicGFyYW1zIjogWwogICAgICAgIHsKICAgICAgICAgICJuYW1lIjogInAiLAogICAgICAgICAgImxpbmUiOiAxCiAgICAgICAgfQogICAgICBdLAogICAgICAiYm9keSI6IFsKICAgICAgICB7CiAgICAgICAgICAib3AiOiAicmVsZWFzZSIsCiAgICAgICAgICAidmFyIjogInAiLAogICAgICAgICAgImxpbmUiOiAyCiAgICAgICAgfQogICAgICBdCiAgICB9LAogICAgewogICAgICAibmFtZSI6ICJUYWtlIiwKICAgICAgInNpZyI6ICJTeXN0ZW0uU3RyaW5nIiwKICAgICAgImZpbGUiOiAidDIuY3MiLAogICAgICAicGFyYW1zIjogWwogICAgICAgIHsKICAgICAgICAgICJuYW1lIjogInAiLAogICAgICAgICAgImxpbmUiOiA1CiAgICAgICAgfQogICAgICBdLAogICAgICAiYm9keSI6IFsKICAgICAgICB7CiAgICAgICAgICAib3AiOiAidXNlIiwKICAgICAgICAgICJ2YXIiOiAicCIsCiAgICAgICAgICAibGluZSI6IDYKICAgICAgICB9CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJuYW1lIjogIlRha2UoU3lzdGVtLklPLlN0cmVhbSkiLAogICAgICAiZmlsZSI6ICJjbGFzaC5jcyIsCiAgICAgICJib2R5IjogW10KICAgIH0KICBdCn0K" + "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMiwKICAibW9kdWxlIjogIkRlZ3JhZGVkIiwKICAiZnVuY3Rpb25zIjogWwogICAgewogICAgICAibmFtZSI6ICJUYWtlIiwKICAgICAgInNpZyI6ICJTeXN0ZW0uSU8uU3RyZWFtIiwKICAgICAgImZpbGUiOiAidDEuY3MiLAogICAgICAicGFyYW1zIjogWwogICAgICAgIHsKICAgICAgICAgICJuYW1lIjogInAiLAogICAgICAgICAgImxpbmUiOiAxCiAgICAgICAgfQogICAgICBdLAogICAgICAiYm9keSI6IFsKICAgICAgICB7CiAgICAgICAgICAib3AiOiAicmVsZWFzZSIsCiAgICAgICAgICAidmFyIjogInAiLAogICAgICAgICAgImxpbmUiOiAyCiAgICAgICAgfQogICAgICBdCiAgICB9LAogICAgewogICAgICAibmFtZSI6ICJUYWtlIiwKICAgICAgInNpZyI6ICJTeXN0ZW0uU3RyaW5nIiwKICAgICAgImZpbGUiOiAidDIuY3MiLAogICAgICAicGFyYW1zIjogWwogICAgICAgIHsKICAgICAgICAgICJuYW1lIjogInAiLAogICAgICAgICAgImxpbmUiOiA1CiAgICAgICAgfQogICAgICBdLAogICAgICAiYm9keSI6IFsKICAgICAgICB7CiAgICAgICAgICAib3AiOiAidXNlIiwKICAgICAgICAgICJ2YXIiOiAicCIsCiAgICAgICAgICAibGluZSI6IDYKICAgICAgICB9CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJuYW1lIjogIlRha2UoU3lzdGVtLklPLlN0cmVhbSkiLAogICAgICAiZmlsZSI6ICJjbGFzaC5jcyIsCiAgICAgICJib2R5IjogW10KICAgIH0KICBdCn0K" }, "canonical": { "algorithm": "sha256", - "digest": "5d67d6918c18d93df76a29b2d58f50202444d3b95e2a7de6cca64541bb71e06d", + "digest": "07fc35882106a66285295b99374c3ed00e030cda1836bedbed07eae187733788", "bytes": 376 }, "document": { - "ownir_version": 1, + "ownir_version": 2, "module": "Degraded", "functions": [ { @@ -66,7 +66,7 @@ "id": "python-ownlang", "consumed": { "algorithm": "sha256", - "digest": "60debca1e8aede04c2048c023af7f29a7af41131d9b081abaace6d40761bfae5", + "digest": "2debe3d9444ec820586745713e75f484dd00909b6276045d7ad73ed8e683df70", "bytes": 747 }, "layers": [ @@ -257,7 +257,7 @@ "document": { "degraded": "ValueError: duplicate MethodSkeleton key: Take(System.IO.Stream)", "module": "Degraded", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -298,7 +298,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "11420b28e02f7d9cf9e1ba3791c8420f1565f9f25f0c8e57fb43eac932a2f152", + "digest": "359637133a1883cdee74d3dcf3a3d81f7ffbf891563d7df7cd733ea46fa8edb5", "bytes": 822 } } @@ -308,7 +308,7 @@ "id": "rust-own-bridge", "consumed": { "algorithm": "sha256", - "digest": "60debca1e8aede04c2048c023af7f29a7af41131d9b081abaace6d40761bfae5", + "digest": "2debe3d9444ec820586745713e75f484dd00909b6276045d7ad73ed8e683df70", "bytes": 747 }, "layers": [ @@ -499,7 +499,7 @@ "document": { "degraded": "ValueError: duplicate MethodSkeleton key: Take(System.IO.Stream)", "module": "Degraded", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -540,7 +540,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "11420b28e02f7d9cf9e1ba3791c8420f1565f9f25f0c8e57fb43eac932a2f152", + "digest": "359637133a1883cdee74d3dcf3a3d81f7ffbf891563d7df7cd733ea46fa8edb5", "bytes": 822 } } diff --git a/tests/fixtures/repro/mosdump_degraded_duplicate_key.trace.json b/tests/fixtures/repro/mosdump_degraded_duplicate_key.trace.json index afd5a7f4..14c61a22 100644 --- a/tests/fixtures/repro/mosdump_degraded_duplicate_key.trace.json +++ b/tests/fixtures/repro/mosdump_degraded_duplicate_key.trace.json @@ -7,7 +7,7 @@ "engine": "python-ownlang", "input": { "algorithm": "sha256", - "digest": "5d67d6918c18d93df76a29b2d58f50202444d3b95e2a7de6cca64541bb71e06d", + "digest": "07fc35882106a66285295b99374c3ed00e030cda1836bedbed07eae187733788", "bytes": 376 }, "layers": [ @@ -238,7 +238,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", @@ -286,7 +286,7 @@ "engine": "rust-own-bridge", "input": { "algorithm": "sha256", - "digest": "5d67d6918c18d93df76a29b2d58f50202444d3b95e2a7de6cca64541bb71e06d", + "digest": "07fc35882106a66285295b99374c3ed00e030cda1836bedbed07eae187733788", "bytes": 376 }, "layers": [ @@ -517,7 +517,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", diff --git a/tests/fixtures/repro/protocol_isloaded_violation.repro.json b/tests/fixtures/repro/protocol_isloaded_violation.repro.json index a655fe9b..0e8d25a6 100644 --- a/tests/fixtures/repro/protocol_isloaded_violation.repro.json +++ b/tests/fixtures/repro/protocol_isloaded_violation.repro.json @@ -1,20 +1,20 @@ { "repro_version": 3, "input": { - "ownir_version": 1, + "ownir_version": 2, "raw": { "algorithm": "sha256", - "digest": "b5fd4f02066e01f09661c2a68b00faa58ec2b5dd6b43a640ff15514cd1f74033", + "digest": "b6899a982dd2d81f87da8bb9b2e2a9105b6a0344aaf32bf99414e8146169e8dd", "bytes": 1559, - "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMSwKICAibW9kdWxlIjogIkV4dHJhY3RlZCIsCiAgImNvbXBvbmVudHMiOiBbXSwKICAicHJvdG9jb2xzIjogWwogICAgewogICAgICAibmFtZSI6ICJEb2N1bWVudExvYWRpbmciLAogICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGRvY3VtZW50IHRyZWUgaXMgaW5jb25zaXN0ZW50IHdoaWxlIElzTG9hZGVkID09IGZhbHNlOyBwdWJsaXNoaW5nIERvY3VtZW50L1Jvd3MvVG90YWxzIGluIHRoYXQgd2luZG93IGhhbmRzIGJpbmRpbmdzIGEgYnJva2VuIG9iamVjdC4iLAogICAgICAib3BlbnMiOiAgeyJraW5kIjogImFzc2lnbiIsICJ0YXJnZXQiOiAiSXNMb2FkZWQiLCAidmFsdWUiOiBmYWxzZX0sCiAgICAgICJjbG9zZXMiOiB7ImtpbmQiOiAiYXNzaWduIiwgInRhcmdldCI6ICJJc0xvYWRlZCIsICJ2YWx1ZSI6IHRydWV9LAogICAgICAiYmFycmllcnMiOiBbCiAgICAgICAgeyJraW5kIjogImNhbGwiLCAiY2FsbGVlIjogIk9uUHJvcGVydHlDaGFuZ2VkIiwKICAgICAgICAgImFyZ3MiOiBbIkRvY3VtZW50IiwgIlJvd3MiLCAiVG90YWxzIiwgIlNlbGVjdGVkSXRlbSJdfQogICAgICBdLAogICAgICAiYWxsb3ciOiBbCiAgICAgICAgeyJraW5kIjogImNhbGwiLCAiY2FsbGVlIjogIk9uUHJvcGVydHlDaGFuZ2VkIiwKICAgICAgICAgImFyZ3MiOiBbIklzTG9hZGVkIiwgIklzQnVzeSIsICJQcm9ncmVzcyIsICJTdGF0dXNUZXh0Il19CiAgICAgIF0sCiAgICAgICJleGl0X2JhcnJpZXJzIjogdHJ1ZSwKICAgICAgInNjb3BlIjogeyJtZXRob2RzIjogWyJCaWdEb2N1bWVudFZpZXdNb2RlbC5Mb2FkQmlnRG9jdW1lbnQiXX0KICAgIH0KICBdLAogICJwcm90b2NvbF9mdW5jdGlvbnMiOiBbCiAgICB7CiAgICAgICJuYW1lIjogIkJyb2tlci5CaWdEb2N1bWVudFZpZXdNb2RlbC5Mb2FkQmlnRG9jdW1lbnQiLAogICAgICAiZmlsZSI6ICJCaWdEb2N1bWVudFZpZXdNb2RlbC5jcyIsCiAgICAgICJldmVudHMiOiBbCiAgICAgICAgeyJldiI6ICJhc3NpZ24iLCAidGFyZ2V0IjogIklzTG9hZGVkIiwgInZhbHVlIjogZmFsc2UsICJsaW5lIjogMTg0fSwKICAgICAgICB7ImV2IjogImNhbGwiLCAiY2FsbGVlIjogIk9uUHJvcGVydHlDaGFuZ2VkIiwgImFyZyI6ICJJc0J1c3kiLCAibGluZSI6IDE4NX0sCiAgICAgICAgeyJldiI6ICJjYWxsIiwgImNhbGxlZSI6ICJSZWJ1aWxkSW5kZXhlcyIsICJsaW5lIjogMTkwfSwKICAgICAgICB7ImV2IjogImlmIiwgImxpbmUiOiAyMjAsICJ0aGVuIjogWwogICAgICAgICAgeyJldiI6ICJjYWxsIiwgImNhbGxlZSI6ICJPblByb3BlcnR5Q2hhbmdlZCIsICJhcmciOiAiRG9jdW1lbnQiLCAibGluZSI6IDI0MX0KICAgICAgICBdLCAiZWxzZSI6IFtdfSwKICAgICAgICB7ImV2IjogImFzc2lnbiIsICJ0YXJnZXQiOiAiSXNMb2FkZWQiLCAidmFsdWUiOiB0cnVlLCAibGluZSI6IDI2MH0sCiAgICAgICAgeyJldiI6ICJjYWxsIiwgImNhbGxlZSI6ICJPblByb3BlcnR5Q2hhbmdlZCIsICJhcmciOiAiRG9jdW1lbnQiLCAibGluZSI6IDI2MX0KICAgICAgXQogICAgfQogIF0KfQo=" + "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMiwKICAibW9kdWxlIjogIkV4dHJhY3RlZCIsCiAgImNvbXBvbmVudHMiOiBbXSwKICAicHJvdG9jb2xzIjogWwogICAgewogICAgICAibmFtZSI6ICJEb2N1bWVudExvYWRpbmciLAogICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGRvY3VtZW50IHRyZWUgaXMgaW5jb25zaXN0ZW50IHdoaWxlIElzTG9hZGVkID09IGZhbHNlOyBwdWJsaXNoaW5nIERvY3VtZW50L1Jvd3MvVG90YWxzIGluIHRoYXQgd2luZG93IGhhbmRzIGJpbmRpbmdzIGEgYnJva2VuIG9iamVjdC4iLAogICAgICAib3BlbnMiOiAgeyJraW5kIjogImFzc2lnbiIsICJ0YXJnZXQiOiAiSXNMb2FkZWQiLCAidmFsdWUiOiBmYWxzZX0sCiAgICAgICJjbG9zZXMiOiB7ImtpbmQiOiAiYXNzaWduIiwgInRhcmdldCI6ICJJc0xvYWRlZCIsICJ2YWx1ZSI6IHRydWV9LAogICAgICAiYmFycmllcnMiOiBbCiAgICAgICAgeyJraW5kIjogImNhbGwiLCAiY2FsbGVlIjogIk9uUHJvcGVydHlDaGFuZ2VkIiwKICAgICAgICAgImFyZ3MiOiBbIkRvY3VtZW50IiwgIlJvd3MiLCAiVG90YWxzIiwgIlNlbGVjdGVkSXRlbSJdfQogICAgICBdLAogICAgICAiYWxsb3ciOiBbCiAgICAgICAgeyJraW5kIjogImNhbGwiLCAiY2FsbGVlIjogIk9uUHJvcGVydHlDaGFuZ2VkIiwKICAgICAgICAgImFyZ3MiOiBbIklzTG9hZGVkIiwgIklzQnVzeSIsICJQcm9ncmVzcyIsICJTdGF0dXNUZXh0Il19CiAgICAgIF0sCiAgICAgICJleGl0X2JhcnJpZXJzIjogdHJ1ZSwKICAgICAgInNjb3BlIjogeyJtZXRob2RzIjogWyJCaWdEb2N1bWVudFZpZXdNb2RlbC5Mb2FkQmlnRG9jdW1lbnQiXX0KICAgIH0KICBdLAogICJwcm90b2NvbF9mdW5jdGlvbnMiOiBbCiAgICB7CiAgICAgICJuYW1lIjogIkJyb2tlci5CaWdEb2N1bWVudFZpZXdNb2RlbC5Mb2FkQmlnRG9jdW1lbnQiLAogICAgICAiZmlsZSI6ICJCaWdEb2N1bWVudFZpZXdNb2RlbC5jcyIsCiAgICAgICJldmVudHMiOiBbCiAgICAgICAgeyJldiI6ICJhc3NpZ24iLCAidGFyZ2V0IjogIklzTG9hZGVkIiwgInZhbHVlIjogZmFsc2UsICJsaW5lIjogMTg0fSwKICAgICAgICB7ImV2IjogImNhbGwiLCAiY2FsbGVlIjogIk9uUHJvcGVydHlDaGFuZ2VkIiwgImFyZyI6ICJJc0J1c3kiLCAibGluZSI6IDE4NX0sCiAgICAgICAgeyJldiI6ICJjYWxsIiwgImNhbGxlZSI6ICJSZWJ1aWxkSW5kZXhlcyIsICJsaW5lIjogMTkwfSwKICAgICAgICB7ImV2IjogImlmIiwgImxpbmUiOiAyMjAsICJ0aGVuIjogWwogICAgICAgICAgeyJldiI6ICJjYWxsIiwgImNhbGxlZSI6ICJPblByb3BlcnR5Q2hhbmdlZCIsICJhcmciOiAiRG9jdW1lbnQiLCAibGluZSI6IDI0MX0KICAgICAgICBdLCAiZWxzZSI6IFtdfSwKICAgICAgICB7ImV2IjogImFzc2lnbiIsICJ0YXJnZXQiOiAiSXNMb2FkZWQiLCAidmFsdWUiOiB0cnVlLCAibGluZSI6IDI2MH0sCiAgICAgICAgeyJldiI6ICJjYWxsIiwgImNhbGxlZSI6ICJPblByb3BlcnR5Q2hhbmdlZCIsICJhcmciOiAiRG9jdW1lbnQiLCAibGluZSI6IDI2MX0KICAgICAgXQogICAgfQogIF0KfQo=" }, "canonical": { "algorithm": "sha256", - "digest": "1025d2dadba8f7f00604e5d40a264d286a0d5cf62a243b16578fd00b3430d813", + "digest": "946c1e8200398dd311e1bca65ce69f9ec9b3c5ee82ebf6d0779f24f6774ffa75", "bytes": 1217 }, "document": { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [], "protocols": [ @@ -120,7 +120,7 @@ "id": "python-ownlang", "consumed": { "algorithm": "sha256", - "digest": "b5fd4f02066e01f09661c2a68b00faa58ec2b5dd6b43a640ff15514cd1f74033", + "digest": "b6899a982dd2d81f87da8bb9b2e2a9105b6a0344aaf32bf99414e8146169e8dd", "bytes": 1559 }, "layers": [ @@ -236,7 +236,7 @@ "document": { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -293,7 +293,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "8cc50bd50c0c89ba50889e19589622969af9607dc7e43e843156391070340f39", + "digest": "1fab9d1ef18aaf629baca5fabbf90319e0563e8f157647ff0545595106fd8dc0", "bytes": 1556 } } @@ -303,7 +303,7 @@ "id": "rust-own-bridge", "consumed": { "algorithm": "sha256", - "digest": "b5fd4f02066e01f09661c2a68b00faa58ec2b5dd6b43a640ff15514cd1f74033", + "digest": "b6899a982dd2d81f87da8bb9b2e2a9105b6a0344aaf32bf99414e8146169e8dd", "bytes": 1559 }, "layers": [ @@ -419,7 +419,7 @@ "document": { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -476,7 +476,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "8cc50bd50c0c89ba50889e19589622969af9607dc7e43e843156391070340f39", + "digest": "1fab9d1ef18aaf629baca5fabbf90319e0563e8f157647ff0545595106fd8dc0", "bytes": 1556 } } diff --git a/tests/fixtures/repro/protocol_isloaded_violation.trace.json b/tests/fixtures/repro/protocol_isloaded_violation.trace.json index a5f231f2..f6b9c2ea 100644 --- a/tests/fixtures/repro/protocol_isloaded_violation.trace.json +++ b/tests/fixtures/repro/protocol_isloaded_violation.trace.json @@ -7,7 +7,7 @@ "engine": "python-ownlang", "input": { "algorithm": "sha256", - "digest": "1025d2dadba8f7f00604e5d40a264d286a0d5cf62a243b16578fd00b3430d813", + "digest": "946c1e8200398dd311e1bca65ce69f9ec9b3c5ee82ebf6d0779f24f6774ffa75", "bytes": 1217 }, "layers": [ @@ -147,7 +147,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", @@ -211,7 +211,7 @@ "engine": "rust-own-bridge", "input": { "algorithm": "sha256", - "digest": "1025d2dadba8f7f00604e5d40a264d286a0d5cf62a243b16578fd00b3430d813", + "digest": "946c1e8200398dd311e1bca65ce69f9ec9b3c5ee82ebf6d0779f24f6774ffa75", "bytes": 1217 }, "layers": [ @@ -351,7 +351,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", diff --git a/tests/fixtures/repro/variants/bom.bin b/tests/fixtures/repro/variants/bom.bin index f74ea8de..162d06a9 100644 --- a/tests/fixtures/repro/variants/bom.bin +++ b/tests/fixtures/repro/variants/bom.bin @@ -1,4 +1,4 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Minimal" } diff --git a/tests/fixtures/repro/variants/byte_variants.json b/tests/fixtures/repro/variants/byte_variants.json index 1571f8a5..bcb5be4f 100644 --- a/tests/fixtures/repro/variants/byte_variants.json +++ b/tests/fixtures/repro/variants/byte_variants.json @@ -10,7 +10,7 @@ ], "raw": { "algorithm": "sha256", - "digest": "dcb356dc38153f87557fca387626f9141f3b7e7c0e56a60de05ee3382fb93386", + "digest": "ef5853d55d3e0d5a0f9b5c855645c69f7cb07facb1acf7390643756348ff6b16", "bytes": 51 }, "python": { @@ -35,7 +35,7 @@ ], "raw": { "algorithm": "sha256", - "digest": "b5517c9a81f5beeb40ed922a8513b07be328ee9657c96c8437da7054e39a19bf", + "digest": "e2547a32de298f7b7ca129b980952284365732885ab7e1bd0e2292ada176380e", "bytes": 52 }, "python": { @@ -50,13 +50,13 @@ "typed_door_accepted": true, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, @@ -68,7 +68,7 @@ ], "raw": { "algorithm": "sha256", - "digest": "2b6f6f3963575300fd43ca5e771be0bbc9f9c2cbf9d628832df6e5c1d3879ca5", + "digest": "b1e56493dced32ade2f24222e6dfafd567c9a0e746fabc92b8b6006999dd0121", "bytes": 49 }, "python": { @@ -83,13 +83,13 @@ "typed_door_accepted": true, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, @@ -101,7 +101,7 @@ ], "raw": { "algorithm": "sha256", - "digest": "6394abbd914117b7da2699abbc12e791a5a78b9699aad8bfd1e6232c8d5236b6", + "digest": "4f6caba464e812bdae6bfd4f4f545300ba7de95022d7b344840a1b2a992ab45f", "bytes": 48 }, "python": { @@ -126,7 +126,7 @@ ], "raw": { "algorithm": "sha256", - "digest": "5a7a1a044ea315d567f9a0777031b7b5ba7d16f32606a3e331acdab7cf47d7df", + "digest": "2202d4e3a3da62aaeac1ff10ecd3fdf35ae011e02723c813371261167d3b2e3d", "bytes": 48 }, "python": { @@ -141,13 +141,13 @@ "typed_door_accepted": true, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, @@ -159,7 +159,7 @@ ], "raw": { "algorithm": "sha256", - "digest": "ed5c01c1831c9a090b346c96334da79b70b85951d851f92621a5d896e03935b8", + "digest": "bb1efc5f64660be9702c61d8fbb4d83f099e05843ff8b09222086f7fc42fbdb7", "bytes": 46 }, "python": { @@ -184,7 +184,7 @@ ], "raw": { "algorithm": "sha256", - "digest": "b3d45f877b03fc8129e6343f1b2344f8d493ae8590a5ca8c9dad12edfbc58b21", + "digest": "afe869fba4bae7587faf47dfb3645f2f38ccbcbbfcb22d631e9b9c1667a3012f", "bytes": 47 }, "python": { @@ -199,13 +199,13 @@ "typed_door_accepted": true, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, @@ -217,7 +217,7 @@ ], "raw": { "algorithm": "sha256", - "digest": "4573241a7888cac6145dd1005623c1edd6573a221d6779515781eb247041ebc7", + "digest": "58a2d13e4d8993a710f8d4d62a2cc417ccce569145678648ef92c53e8839f9bd", "bytes": 48 }, "python": { @@ -232,13 +232,13 @@ "typed_door_accepted": true, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, @@ -250,7 +250,7 @@ ], "raw": { "algorithm": "sha256", - "digest": "6fe99998f020698c05a07209e1de1c86ee9eef20fcde2ad4eab5e0ee18192dbc", + "digest": "ebe184f69f1dd03e3d4bffcd3f0bb6b9dab412aa0534e0eb710bda94873bf2f8", "bytes": 38 }, "python": { @@ -265,13 +265,13 @@ "typed_door_accepted": true, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, @@ -283,7 +283,7 @@ ], "raw": { "algorithm": "sha256", - "digest": "74c40b0a7c1b78ed452f72dc9f61894c9f601b9b5de73a1f97cd6d7ec416d963", + "digest": "e912e6478f0474089fafd7ddb3a4957e1c57fb0a05b62494b0603c05cb8e8613", "bytes": 52 }, "python": { @@ -298,13 +298,13 @@ "typed_door_accepted": true, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } }, "canonical": { "algorithm": "sha256", - "digest": "0f3af651cbd63f59131e16da784820e334fa68ed69b29fb068076abf4374d319", + "digest": "fa704f85cb2ccb45144cf585ca6ed2c91540ebe6bfffae1ef44d9e46dde14a71", "bytes": 38 } } diff --git a/tests/fixtures/repro/variants/crlf.bin b/tests/fixtures/repro/variants/crlf.bin index 14a675ad..52207b15 100644 --- a/tests/fixtures/repro/variants/crlf.bin +++ b/tests/fixtures/repro/variants/crlf.bin @@ -1,4 +1,4 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Minimal" } diff --git a/tests/fixtures/repro/variants/extra_trailing_newline.bin b/tests/fixtures/repro/variants/extra_trailing_newline.bin index 735741ec..b98de926 100644 --- a/tests/fixtures/repro/variants/extra_trailing_newline.bin +++ b/tests/fixtures/repro/variants/extra_trailing_newline.bin @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Minimal" } diff --git a/tests/fixtures/repro/variants/invalid_utf8.bin b/tests/fixtures/repro/variants/invalid_utf8.bin index 323c1c03..7520aebc 100644 --- a/tests/fixtures/repro/variants/invalid_utf8.bin +++ b/tests/fixtures/repro/variants/invalid_utf8.bin @@ -1,4 +1,4 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Minim€l" } diff --git a/tests/fixtures/repro/variants/key_order_reversed.bin b/tests/fixtures/repro/variants/key_order_reversed.bin index 893cc908..beb31960 100644 --- a/tests/fixtures/repro/variants/key_order_reversed.bin +++ b/tests/fixtures/repro/variants/key_order_reversed.bin @@ -1,4 +1,4 @@ { "module": "Minimal", - "ownir_version": 1 + "ownir_version": 2 } diff --git a/tests/fixtures/repro/variants/malformed_json.bin b/tests/fixtures/repro/variants/malformed_json.bin index 849e3c97..95c2b4a7 100644 --- a/tests/fixtures/repro/variants/malformed_json.bin +++ b/tests/fixtures/repro/variants/malformed_json.bin @@ -1,3 +1,3 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Minimal" diff --git a/tests/fixtures/repro/variants/no_trailing_newline.bin b/tests/fixtures/repro/variants/no_trailing_newline.bin index 4cbc3f44..227f7995 100644 --- a/tests/fixtures/repro/variants/no_trailing_newline.bin +++ b/tests/fixtures/repro/variants/no_trailing_newline.bin @@ -1,4 +1,4 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Minimal" } \ No newline at end of file diff --git a/tests/fixtures/repro/variants/plain.bin b/tests/fixtures/repro/variants/plain.bin index 47940bbf..87830c6d 100644 --- a/tests/fixtures/repro/variants/plain.bin +++ b/tests/fixtures/repro/variants/plain.bin @@ -1,4 +1,4 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Minimal" } diff --git a/tests/fixtures/repro/variants/whitespace_compact.bin b/tests/fixtures/repro/variants/whitespace_compact.bin index c3d1a7f4..6931e61a 100644 --- a/tests/fixtures/repro/variants/whitespace_compact.bin +++ b/tests/fixtures/repro/variants/whitespace_compact.bin @@ -1 +1 @@ -{"ownir_version":1,"module":"Minimal"} \ No newline at end of file +{"ownir_version":2,"module":"Minimal"} \ No newline at end of file diff --git a/tests/fixtures/repro/variants/whitespace_expanded.bin b/tests/fixtures/repro/variants/whitespace_expanded.bin index b425f44e..de522ba9 100644 --- a/tests/fixtures/repro/variants/whitespace_expanded.bin +++ b/tests/fixtures/repro/variants/whitespace_expanded.bin @@ -1,4 +1,4 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Minimal" } diff --git a/tests/fixtures/repro/verdict_door_effect_deps_not_strings.repro.json b/tests/fixtures/repro/verdict_door_effect_deps_not_strings.repro.json index cb344746..2959aba9 100644 --- a/tests/fixtures/repro/verdict_door_effect_deps_not_strings.repro.json +++ b/tests/fixtures/repro/verdict_door_effect_deps_not_strings.repro.json @@ -1,20 +1,20 @@ { "repro_version": 3, "input": { - "ownir_version": 1, + "ownir_version": 2, "raw": { "algorithm": "sha256", - "digest": "c28447881206b741a6c80335c945308cbbf16b8eb7a44e6490a44e1c17a9ab05", + "digest": "0cf753e1fd3d1ad9630128fc387a96d00b15bc8e97105c732b0348e17cb58b9a", "bytes": 948, - "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMSwKICAibW9kdWxlIjogIkRvb3IiLAogICJjb21wb25lbnRzIjogW10sCiAgIl9kb2MiOiBbCiAgICAiIzI5NCBPRC0xOiBCUi1EMidzIHNraXAtbm90LWNvZXJjZSBvbiB0aGUgdG9sZXJhbnQgZG9vci4gVGhlIHJlZmVyZW5jZSBTS0lQUyIsCiAgICAidGhlIGVmZmVjdCB3aG9zZSBkZXBzIGlzIGEgYmFyZSBzdHJpbmcgKG5vIHNwdXJpb3VzIEVGRjAwMSkgYW5kIHJlcG9ydHMgdGhlIiwKICAgICJ3ZWxsLWZvcm1lZCBzaWJsaW5nOyB0aGUgUnVzdCB0b2xlcmFudCBlbnRyeSBpcyB0aGUgdHlwZWQgY29uc3RydWN0b3IsIHdoaWNoIiwKICAgICJyZWZ1c2VzIHRoZSBkb2N1bWVudCBiZWZvcmUgdGhlIGJyaWRnZSdzIHNraXAgcnVsZSBjYW4gcnVuLiIKICBdLAogICJlZmZlY3RzIjogWwogICAgewogICAgICAiY29tcG9uZW50IjogIlgiLAogICAgICAiZmlsZSI6ICJYLnRzeCIsCiAgICAgICJsaW5lIjogMSwKICAgICAgImlvIjogdHJ1ZSwKICAgICAgImRlcHMiOiAiYSIsCiAgICAgICJiaW5kaW5ncyI6IFsKICAgICAgICB7CiAgICAgICAgICAibmFtZSI6ICJhIiwKICAgICAgICAgICJpbml0IjogIm9iamVjdCIsCiAgICAgICAgICAicmVmcyI6IFtdLAogICAgICAgICAgImxpbmUiOiAxCiAgICAgICAgfQogICAgICBdCiAgICB9LAogICAgewogICAgICAiY29tcG9uZW50IjogIk9rIiwKICAgICAgImZpbGUiOiAiT2sudHN4IiwKICAgICAgImxpbmUiOiA5LAogICAgICAiaW8iOiB0cnVlLAogICAgICAiZGVwcyI6IFsKICAgICAgICAibyIKICAgICAgXSwKICAgICAgImJpbmRpbmdzIjogWwogICAgICAgIHsKICAgICAgICAgICJuYW1lIjogIm8iLAogICAgICAgICAgImluaXQiOiAib2JqZWN0IiwKICAgICAgICAgICJyZWZzIjogW10sCiAgICAgICAgICAibGluZSI6IDgKICAgICAgICB9CiAgICAgIF0KICAgIH0KICBdCn0K" + "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMiwKICAibW9kdWxlIjogIkRvb3IiLAogICJjb21wb25lbnRzIjogW10sCiAgIl9kb2MiOiBbCiAgICAiIzI5NCBPRC0xOiBCUi1EMidzIHNraXAtbm90LWNvZXJjZSBvbiB0aGUgdG9sZXJhbnQgZG9vci4gVGhlIHJlZmVyZW5jZSBTS0lQUyIsCiAgICAidGhlIGVmZmVjdCB3aG9zZSBkZXBzIGlzIGEgYmFyZSBzdHJpbmcgKG5vIHNwdXJpb3VzIEVGRjAwMSkgYW5kIHJlcG9ydHMgdGhlIiwKICAgICJ3ZWxsLWZvcm1lZCBzaWJsaW5nOyB0aGUgUnVzdCB0b2xlcmFudCBlbnRyeSBpcyB0aGUgdHlwZWQgY29uc3RydWN0b3IsIHdoaWNoIiwKICAgICJyZWZ1c2VzIHRoZSBkb2N1bWVudCBiZWZvcmUgdGhlIGJyaWRnZSdzIHNraXAgcnVsZSBjYW4gcnVuLiIKICBdLAogICJlZmZlY3RzIjogWwogICAgewogICAgICAiY29tcG9uZW50IjogIlgiLAogICAgICAiZmlsZSI6ICJYLnRzeCIsCiAgICAgICJsaW5lIjogMSwKICAgICAgImlvIjogdHJ1ZSwKICAgICAgImRlcHMiOiAiYSIsCiAgICAgICJiaW5kaW5ncyI6IFsKICAgICAgICB7CiAgICAgICAgICAibmFtZSI6ICJhIiwKICAgICAgICAgICJpbml0IjogIm9iamVjdCIsCiAgICAgICAgICAicmVmcyI6IFtdLAogICAgICAgICAgImxpbmUiOiAxCiAgICAgICAgfQogICAgICBdCiAgICB9LAogICAgewogICAgICAiY29tcG9uZW50IjogIk9rIiwKICAgICAgImZpbGUiOiAiT2sudHN4IiwKICAgICAgImxpbmUiOiA5LAogICAgICAiaW8iOiB0cnVlLAogICAgICAiZGVwcyI6IFsKICAgICAgICAibyIKICAgICAgXSwKICAgICAgImJpbmRpbmdzIjogWwogICAgICAgIHsKICAgICAgICAgICJuYW1lIjogIm8iLAogICAgICAgICAgImluaXQiOiAib2JqZWN0IiwKICAgICAgICAgICJyZWZzIjogW10sCiAgICAgICAgICAibGluZSI6IDgKICAgICAgICB9CiAgICAgIF0KICAgIH0KICBdCn0K" }, "canonical": { "algorithm": "sha256", - "digest": "b85df11e6d8bd400d38b209009a3517bce2bce543e65fd2faac863dcfd057cf1", + "digest": "3e2c8ccf546f0722262d8783368939732046902c669d6ad2db6ab9ca71880d8c", "bytes": 622 }, "document": { - "ownir_version": 1, + "ownir_version": 2, "module": "Door", "components": [], "_doc": [ @@ -64,7 +64,7 @@ "id": "python-ownlang", "consumed": { "algorithm": "sha256", - "digest": "c28447881206b741a6c80335c945308cbbf16b8eb7a44e6490a44e1c17a9ab05", + "digest": "0cf753e1fd3d1ad9630128fc387a96d00b15bc8e97105c732b0348e17cb58b9a", "bytes": 948 }, "layers": [ @@ -180,7 +180,7 @@ "document": { "degraded": null, "module": "Door", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -232,7 +232,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "77b36d9af18fb0d999b5c37a36ea82da135413dddb3f4a1ae9cda738736e46fc", + "digest": "af6e42e52310d88da1c4d586919ce3282ed3dc312a751c5fc85e6118ff93d67d", "bytes": 1299 } } @@ -242,7 +242,7 @@ "id": "rust-own-bridge", "consumed": { "algorithm": "sha256", - "digest": "c28447881206b741a6c80335c945308cbbf16b8eb7a44e6490a44e1c17a9ab05", + "digest": "0cf753e1fd3d1ad9630128fc387a96d00b15bc8e97105c732b0348e17cb58b9a", "bytes": 948 }, "layers": [ diff --git a/tests/fixtures/repro/verdict_door_effect_deps_not_strings.trace.json b/tests/fixtures/repro/verdict_door_effect_deps_not_strings.trace.json index 060b9146..a138dd9e 100644 --- a/tests/fixtures/repro/verdict_door_effect_deps_not_strings.trace.json +++ b/tests/fixtures/repro/verdict_door_effect_deps_not_strings.trace.json @@ -7,7 +7,7 @@ "engine": "python-ownlang", "input": { "algorithm": "sha256", - "digest": "b85df11e6d8bd400d38b209009a3517bce2bce543e65fd2faac863dcfd057cf1", + "digest": "3e2c8ccf546f0722262d8783368939732046902c669d6ad2db6ab9ca71880d8c", "bytes": 622 }, "layers": [ @@ -147,7 +147,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", @@ -206,7 +206,7 @@ "engine": "rust-own-bridge", "input": { "algorithm": "sha256", - "digest": "b85df11e6d8bd400d38b209009a3517bce2bce543e65fd2faac863dcfd057cf1", + "digest": "3e2c8ccf546f0722262d8783368939732046902c669d6ad2db6ab9ca71880d8c", "bytes": 622 }, "layers": [ diff --git a/tests/fixtures/repro/verdict_door_service_unknown_lifetime.repro.json b/tests/fixtures/repro/verdict_door_service_unknown_lifetime.repro.json index 0d4f951f..a358621b 100644 --- a/tests/fixtures/repro/verdict_door_service_unknown_lifetime.repro.json +++ b/tests/fixtures/repro/verdict_door_service_unknown_lifetime.repro.json @@ -1,20 +1,20 @@ { "repro_version": 3, "input": { - "ownir_version": 1, + "ownir_version": 2, "raw": { "algorithm": "sha256", - "digest": "a354246b1cf569608b3741390343cca8b9fab03471af9a176ca026a6b8359b0e", + "digest": "f9a3ccd3ed32d1f3e958456d8f96eeca82af62359f1f77ce2b13fc31ba7b76a5", "bytes": 759, - "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMSwKICAibW9kdWxlIjogIkRvb3IiLAogICJjb21wb25lbnRzIjogW10sCiAgIl9kb2MiOiBbCiAgICAiIzI5NCBPRC0xOiBhbiB1bmtub3duIERJIGxpZmV0aW1lIGlzIElHTk9SRUQgYnkgdGhlIHJlZmVyZW5jZSBmaW5kZXJzIG9uIHRoZSIsCiAgICAidG9sZXJhbnQgZG9vciAoTXlzdGVyeSBpcyBuZWl0aGVyIHNjb3BlZCBub3IgdHJhbnNpZW50LCBzbyBBcHAgLT4gRGIgaXMgdGhlIiwKICAgICJvbmx5IERJMDAxKTsgdGhlIHR5cGVkIFJ1c3QgZG9vciByZWZ1c2VzIHRoZSBkb2N1bWVudCBhdCB0aGUgbGlmZXRpbWUgZW51bS4iCiAgXSwKICAic2VydmljZXMiOiBbCiAgICB7CiAgICAgICJuYW1lIjogIkFwcCIsCiAgICAgICJsaWZldGltZSI6ICJzaW5nbGV0b24iLAogICAgICAiZmlsZSI6ICJyZWcuY3MiLAogICAgICAibGluZSI6IDUsCiAgICAgICJkZXBzIjogWwogICAgICAgICJNeXN0ZXJ5IiwKICAgICAgICAiRGIiCiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJuYW1lIjogIk15c3RlcnkiLAogICAgICAibGlmZXRpbWUiOiAicHJvdG90eXBlIiwKICAgICAgImZpbGUiOiAicmVnLmNzIiwKICAgICAgImxpbmUiOiA2LAogICAgICAiZGVwcyI6IFtdCiAgICB9LAogICAgewogICAgICAibmFtZSI6ICJEYiIsCiAgICAgICJsaWZldGltZSI6ICJzY29wZWQiLAogICAgICAiZmlsZSI6ICJyZWcuY3MiLAogICAgICAibGluZSI6IDcsCiAgICAgICJkZXBzIjogW10KICAgIH0KICBdCn0K" + "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMiwKICAibW9kdWxlIjogIkRvb3IiLAogICJjb21wb25lbnRzIjogW10sCiAgIl9kb2MiOiBbCiAgICAiIzI5NCBPRC0xOiBhbiB1bmtub3duIERJIGxpZmV0aW1lIGlzIElHTk9SRUQgYnkgdGhlIHJlZmVyZW5jZSBmaW5kZXJzIG9uIHRoZSIsCiAgICAidG9sZXJhbnQgZG9vciAoTXlzdGVyeSBpcyBuZWl0aGVyIHNjb3BlZCBub3IgdHJhbnNpZW50LCBzbyBBcHAgLT4gRGIgaXMgdGhlIiwKICAgICJvbmx5IERJMDAxKTsgdGhlIHR5cGVkIFJ1c3QgZG9vciByZWZ1c2VzIHRoZSBkb2N1bWVudCBhdCB0aGUgbGlmZXRpbWUgZW51bS4iCiAgXSwKICAic2VydmljZXMiOiBbCiAgICB7CiAgICAgICJuYW1lIjogIkFwcCIsCiAgICAgICJsaWZldGltZSI6ICJzaW5nbGV0b24iLAogICAgICAiZmlsZSI6ICJyZWcuY3MiLAogICAgICAibGluZSI6IDUsCiAgICAgICJkZXBzIjogWwogICAgICAgICJNeXN0ZXJ5IiwKICAgICAgICAiRGIiCiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJuYW1lIjogIk15c3RlcnkiLAogICAgICAibGlmZXRpbWUiOiAicHJvdG90eXBlIiwKICAgICAgImZpbGUiOiAicmVnLmNzIiwKICAgICAgImxpbmUiOiA2LAogICAgICAiZGVwcyI6IFtdCiAgICB9LAogICAgewogICAgICAibmFtZSI6ICJEYiIsCiAgICAgICJsaWZldGltZSI6ICJzY29wZWQiLAogICAgICAiZmlsZSI6ICJyZWcuY3MiLAogICAgICAibGluZSI6IDcsCiAgICAgICJkZXBzIjogW10KICAgIH0KICBdCn0K" }, "canonical": { "algorithm": "sha256", - "digest": "e7820a76b22a9c562e7533d3f429ee16535c85bef592209d4466dcfa9d83f613", + "digest": "d55ad1e0ee0126a05601c0f719c178d26f9fcb0f67d2b1cf902738c1b1646526", "bytes": 541 }, "document": { - "ownir_version": 1, + "ownir_version": 2, "module": "Door", "components": [], "_doc": [ @@ -55,7 +55,7 @@ "id": "python-ownlang", "consumed": { "algorithm": "sha256", - "digest": "a354246b1cf569608b3741390343cca8b9fab03471af9a176ca026a6b8359b0e", + "digest": "f9a3ccd3ed32d1f3e958456d8f96eeca82af62359f1f77ce2b13fc31ba7b76a5", "bytes": 759 }, "layers": [ @@ -171,7 +171,7 @@ "document": { "degraded": null, "module": "Door", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } @@ -223,7 +223,7 @@ "status": "produced", "canonical": { "algorithm": "sha256", - "digest": "6a55b516f689e0269a5e32b5c418e91e9c365aaefd913769af9fc636fb92d600", + "digest": "973c1f15166cdafa8c965ee321dce1d1a14f3fd4f8d56da091a8d624aae6b8a8", "bytes": 1078 } } @@ -233,7 +233,7 @@ "id": "rust-own-bridge", "consumed": { "algorithm": "sha256", - "digest": "a354246b1cf569608b3741390343cca8b9fab03471af9a176ca026a6b8359b0e", + "digest": "f9a3ccd3ed32d1f3e958456d8f96eeca82af62359f1f77ce2b13fc31ba7b76a5", "bytes": 759 }, "layers": [ diff --git a/tests/fixtures/repro/verdict_door_service_unknown_lifetime.trace.json b/tests/fixtures/repro/verdict_door_service_unknown_lifetime.trace.json index 444043f3..6d124677 100644 --- a/tests/fixtures/repro/verdict_door_service_unknown_lifetime.trace.json +++ b/tests/fixtures/repro/verdict_door_service_unknown_lifetime.trace.json @@ -7,7 +7,7 @@ "engine": "python-ownlang", "input": { "algorithm": "sha256", - "digest": "e7820a76b22a9c562e7533d3f429ee16535c85bef592209d4466dcfa9d83f613", + "digest": "d55ad1e0ee0126a05601c0f719c178d26f9fcb0f67d2b1cf902738c1b1646526", "bytes": 541 }, "layers": [ @@ -147,7 +147,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", @@ -206,7 +206,7 @@ "engine": "rust-own-bridge", "input": { "algorithm": "sha256", - "digest": "e7820a76b22a9c562e7533d3f429ee16535c85bef592209d4466dcfa9d83f613", + "digest": "d55ad1e0ee0126a05601c0f719c178d26f9fcb0f67d2b1cf902738c1b1646526", "bytes": 541 }, "layers": [ diff --git a/tests/fixtures/repro/vocab_unknown_op.repro.json b/tests/fixtures/repro/vocab_unknown_op.repro.json index 8cd2c045..21f9ab40 100644 --- a/tests/fixtures/repro/vocab_unknown_op.repro.json +++ b/tests/fixtures/repro/vocab_unknown_op.repro.json @@ -1,20 +1,20 @@ { "repro_version": 3, "input": { - "ownir_version": 1, + "ownir_version": 2, "raw": { "algorithm": "sha256", - "digest": "91e2d42aad1ded1dc0ae052a2dd3b66ab098761709514dd7f7711408015f759d", + "digest": "f82b725252700044c739adfd9a1c11bf2a1758f276851e56dc70cfd84713cbeb", "bytes": 208, - "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMSwKICAibW9kdWxlIjogIlZvY2FiIiwKICAiZnVuY3Rpb25zIjogWwogICAgewogICAgICAibmFtZSI6ICJNIiwKICAgICAgImZpbGUiOiAiRi5jcyIsCiAgICAgICJib2R5IjogWwogICAgICAgIHsKICAgICAgICAgICJvcCI6ICJ0cnkiLAogICAgICAgICAgImxpbmUiOiAyCiAgICAgICAgfQogICAgICBdCiAgICB9CiAgXQp9Cg==" + "base64": "ewogICJvd25pcl92ZXJzaW9uIjogMiwKICAibW9kdWxlIjogIlZvY2FiIiwKICAiZnVuY3Rpb25zIjogWwogICAgewogICAgICAibmFtZSI6ICJNIiwKICAgICAgImZpbGUiOiAiRi5jcyIsCiAgICAgICJib2R5IjogWwogICAgICAgIHsKICAgICAgICAgICJvcCI6ICJ0cnkiLAogICAgICAgICAgImxpbmUiOiAyCiAgICAgICAgfQogICAgICBdCiAgICB9CiAgXQp9Cg==" }, "canonical": { "algorithm": "sha256", - "digest": "866a9d0b4bf4898bbcb2a52b9522201efea52c0a0ff7a75ee2963ad4c88851a9", + "digest": "4d49f08eed0965cb7176da0b9ceb5273d9383cfa6da0bc685a3e7f530a6a23e2", "bytes": 108 }, "document": { - "ownir_version": 1, + "ownir_version": 2, "module": "Vocab", "functions": [ { @@ -35,7 +35,7 @@ "id": "python-ownlang", "consumed": { "algorithm": "sha256", - "digest": "91e2d42aad1ded1dc0ae052a2dd3b66ab098761709514dd7f7711408015f759d", + "digest": "f82b725252700044c739adfd9a1c11bf2a1758f276851e56dc70cfd84713cbeb", "bytes": 208 }, "layers": [ @@ -58,7 +58,7 @@ "document": { "degraded": null, "module": "Vocab", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", @@ -96,7 +96,7 @@ "id": "rust-own-bridge", "consumed": { "algorithm": "sha256", - "digest": "91e2d42aad1ded1dc0ae052a2dd3b66ab098761709514dd7f7711408015f759d", + "digest": "f82b725252700044c739adfd9a1c11bf2a1758f276851e56dc70cfd84713cbeb", "bytes": 208 }, "layers": [ @@ -119,7 +119,7 @@ "document": { "degraded": null, "module": "Vocab", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/repro/vocab_unknown_op.trace.json b/tests/fixtures/repro/vocab_unknown_op.trace.json index 105344a1..930faf94 100644 --- a/tests/fixtures/repro/vocab_unknown_op.trace.json +++ b/tests/fixtures/repro/vocab_unknown_op.trace.json @@ -7,7 +7,7 @@ "engine": "python-ownlang", "input": { "algorithm": "sha256", - "digest": "866a9d0b4bf4898bbcb2a52b9522201efea52c0a0ff7a75ee2963ad4c88851a9", + "digest": "4d49f08eed0965cb7176da0b9ceb5273d9383cfa6da0bc685a3e7f530a6a23e2", "bytes": 108 }, "layers": [ @@ -36,7 +36,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", @@ -75,7 +75,7 @@ "engine": "rust-own-bridge", "input": { "algorithm": "sha256", - "digest": "866a9d0b4bf4898bbcb2a52b9522201efea52c0a0ff7a75ee2963ad4c88851a9", + "digest": "4d49f08eed0965cb7176da0b9ceb5273d9383cfa6da0bc685a3e7f530a6a23e2", "bytes": 108 }, "layers": [ @@ -104,7 +104,7 @@ }, { "id": "ownir_version", - "value": 1 + "value": 2 }, { "id": "degraded", diff --git a/tests/fixtures/summaries/alias_join_cases.summaries.json b/tests/fixtures/summaries/alias_join_cases.summaries.json index b7bd6861..f657ee80 100644 --- a/tests/fixtures/summaries/alias_join_cases.summaries.json +++ b/tests/fixtures/summaries/alias_join_cases.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Alias", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/flow_kill_on_rebind.summaries.json b/tests/fixtures/summaries/flow_kill_on_rebind.summaries.json index bd6304b4..d1e2018a 100644 --- a/tests/fixtures/summaries/flow_kill_on_rebind.summaries.json +++ b/tests/fixtures/summaries/flow_kill_on_rebind.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Rebind", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/flow_unmapped_refs.summaries.json b/tests/fixtures/summaries/flow_unmapped_refs.summaries.json index 6372f1c7..373d6fcd 100644 --- a/tests/fixtures/summaries/flow_unmapped_refs.summaries.json +++ b/tests/fixtures/summaries/flow_unmapped_refs.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Unmapped", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/fn_params_ordering.summaries.json b/tests/fixtures/summaries/fn_params_ordering.summaries.json index faea3751..72969683 100644 --- a/tests/fixtures/summaries/fn_params_ordering.summaries.json +++ b/tests/fixtures/summaries/fn_params_ordering.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Params", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/handles_global_counters.summaries.json b/tests/fixtures/summaries/handles_global_counters.summaries.json index ddf15b9e..6d3fc22f 100644 --- a/tests/fixtures/summaries/handles_global_counters.summaries.json +++ b/tests/fixtures/summaries/handles_global_counters.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Counters", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } diff --git a/tests/fixtures/summaries/handles_null_metadata.summaries.json b/tests/fixtures/summaries/handles_null_metadata.summaries.json index d5f8e43d..8f284cb1 100644 --- a/tests/fixtures/summaries/handles_null_metadata.summaries.json +++ b/tests/fixtures/summaries/handles_null_metadata.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "NullMeta", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } diff --git a/tests/fixtures/summaries/hoist_neg_early_return.summaries.json b/tests/fixtures/summaries/hoist_neg_early_return.summaries.json index 7f6d31ca..bfbff199 100644 --- a/tests/fixtures/summaries/hoist_neg_early_return.summaries.json +++ b/tests/fixtures/summaries/hoist_neg_early_return.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "HoistNeg3", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/hoist_neg_nested_depth.summaries.json b/tests/fixtures/summaries/hoist_neg_nested_depth.summaries.json index 2516c762..f3ecc2c6 100644 --- a/tests/fixtures/summaries/hoist_neg_nested_depth.summaries.json +++ b/tests/fixtures/summaries/hoist_neg_nested_depth.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "HoistNeg1", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/hoist_neg_while_body.summaries.json b/tests/fixtures/summaries/hoist_neg_while_body.summaries.json index e797ab77..e4aca5bd 100644 --- a/tests/fixtures/summaries/hoist_neg_while_body.summaries.json +++ b/tests/fixtures/summaries/hoist_neg_while_body.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "HoistNeg2", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/hoist_pool_kind.summaries.json b/tests/fixtures/summaries/hoist_pool_kind.summaries.json index 5416327d..9c32a6e5 100644 --- a/tests/fixtures/summaries/hoist_pool_kind.summaries.json +++ b/tests/fixtures/summaries/hoist_pool_kind.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "HoistPool", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/hoist_positive_release.summaries.json b/tests/fixtures/summaries/hoist_positive_release.summaries.json index b7dff134..489176c3 100644 --- a/tests/fixtures/summaries/hoist_positive_release.summaries.json +++ b/tests/fixtures/summaries/hoist_positive_release.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Hoist", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/hoist_positive_use_only.summaries.json b/tests/fixtures/summaries/hoist_positive_use_only.summaries.json index 901d7d88..d1c0c507 100644 --- a/tests/fixtures/summaries/hoist_positive_use_only.summaries.json +++ b/tests/fixtures/summaries/hoist_positive_use_only.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "HoistUse", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/lines_preserved.summaries.json b/tests/fixtures/summaries/lines_preserved.summaries.json index 010bf551..9decdee8 100644 --- a/tests/fixtures/summaries/lines_preserved.summaries.json +++ b/tests/fixtures/summaries/lines_preserved.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Lines", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/manifest.json b/tests/fixtures/summaries/manifest.json index bcf13a4e..5ca6ee0d 100644 --- a/tests/fixtures/summaries/manifest.json +++ b/tests/fixtures/summaries/manifest.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "excluded_lowered": [ { "name": "tolerant_unknown_kind", diff --git a/tests/fixtures/summaries/mos_call_channel_overload_sig.summaries.json b/tests/fixtures/summaries/mos_call_channel_overload_sig.summaries.json index 244d88e2..0e1a80b2 100644 --- a/tests/fixtures/summaries/mos_call_channel_overload_sig.summaries.json +++ b/tests/fixtures/summaries/mos_call_channel_overload_sig.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Overloads", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/mos_call_direct_consume.summaries.json b/tests/fixtures/summaries/mos_call_direct_consume.summaries.json index 5c8e83f6..02b28f26 100644 --- a/tests/fixtures/summaries/mos_call_direct_consume.summaries.json +++ b/tests/fixtures/summaries/mos_call_direct_consume.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Direct", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/mos_call_unknown_drop.summaries.json b/tests/fixtures/summaries/mos_call_unknown_drop.summaries.json index ad06c667..aa0e7150 100644 --- a/tests/fixtures/summaries/mos_call_unknown_drop.summaries.json +++ b/tests/fixtures/summaries/mos_call_unknown_drop.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Drop", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/mos_fresh_mint.summaries.json b/tests/fixtures/summaries/mos_fresh_mint.summaries.json index 4c4022b5..5625fdd3 100644 --- a/tests/fixtures/summaries/mos_fresh_mint.summaries.json +++ b/tests/fixtures/summaries/mos_fresh_mint.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Fresh", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/mos_killsite_toplevel.summaries.json b/tests/fixtures/summaries/mos_killsite_toplevel.summaries.json index 95e48b59..91d3841c 100644 --- a/tests/fixtures/summaries/mos_killsite_toplevel.summaries.json +++ b/tests/fixtures/summaries/mos_killsite_toplevel.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "KillSite", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/mos_untrack_inbranch.summaries.json b/tests/fixtures/summaries/mos_untrack_inbranch.summaries.json index 5a470b55..750d3783 100644 --- a/tests/fixtures/summaries/mos_untrack_inbranch.summaries.json +++ b/tests/fixtures/summaries/mos_untrack_inbranch.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Untrack", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/summaries/mosdump_degraded_duplicate_key.facts.json b/tests/fixtures/summaries/mosdump_degraded_duplicate_key.facts.json index ec928b44..d1b78fd2 100644 --- a/tests/fixtures/summaries/mosdump_degraded_duplicate_key.facts.json +++ b/tests/fixtures/summaries/mosdump_degraded_duplicate_key.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Degraded", "functions": [ { diff --git a/tests/fixtures/summaries/mosdump_degraded_duplicate_key.summaries.json b/tests/fixtures/summaries/mosdump_degraded_duplicate_key.summaries.json index 338c50fa..8254eb2c 100644 --- a/tests/fixtures/summaries/mosdump_degraded_duplicate_key.summaries.json +++ b/tests/fixtures/summaries/mosdump_degraded_duplicate_key.summaries.json @@ -1,7 +1,7 @@ { "degraded": "ValueError: duplicate MethodSkeleton key: Take(System.IO.Stream)", "module": "Degraded", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } diff --git a/tests/fixtures/summaries/mosdump_explicit_effects.facts.json b/tests/fixtures/summaries/mosdump_explicit_effects.facts.json index 19f8d8e0..fcea81ab 100644 --- a/tests/fixtures/summaries/mosdump_explicit_effects.facts.json +++ b/tests/fixtures/summaries/mosdump_explicit_effects.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Effects", "functions": [ { diff --git a/tests/fixtures/summaries/mosdump_explicit_effects.summaries.json b/tests/fixtures/summaries/mosdump_explicit_effects.summaries.json index 780acf19..619e1a62 100644 --- a/tests/fixtures/summaries/mosdump_explicit_effects.summaries.json +++ b/tests/fixtures/summaries/mosdump_explicit_effects.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Effects", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "ef.cs", diff --git a/tests/fixtures/summaries/mosdump_nonascii_escaping.facts.json b/tests/fixtures/summaries/mosdump_nonascii_escaping.facts.json index d36243b5..3735dba0 100644 --- a/tests/fixtures/summaries/mosdump_nonascii_escaping.facts.json +++ b/tests/fixtures/summaries/mosdump_nonascii_escaping.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Юникод—М😀", "functions": [ { diff --git a/tests/fixtures/summaries/mosdump_nonascii_escaping.summaries.json b/tests/fixtures/summaries/mosdump_nonascii_escaping.summaries.json index 5a21503b..e9e1d344 100644 --- a/tests/fixtures/summaries/mosdump_nonascii_escaping.summaries.json +++ b/tests/fixtures/summaries/mosdump_nonascii_escaping.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "\u042e\u043d\u0438\u043a\u043e\u0434\u2014\u041c\ud83d\ude00", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "\u0444\u0430\u0439\u043b\ud83d\ude00.cs", diff --git a/tests/fixtures/summaries/mosdump_overload_merge_tiebreaks.facts.json b/tests/fixtures/summaries/mosdump_overload_merge_tiebreaks.facts.json index 06ef382a..b90fc745 100644 --- a/tests/fixtures/summaries/mosdump_overload_merge_tiebreaks.facts.json +++ b/tests/fixtures/summaries/mosdump_overload_merge_tiebreaks.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "MergeTie", "functions": [ { diff --git a/tests/fixtures/summaries/mosdump_overload_merge_tiebreaks.summaries.json b/tests/fixtures/summaries/mosdump_overload_merge_tiebreaks.summaries.json index eb8c2f13..fc282fe5 100644 --- a/tests/fixtures/summaries/mosdump_overload_merge_tiebreaks.summaries.json +++ b/tests/fixtures/summaries/mosdump_overload_merge_tiebreaks.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "MergeTie", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "a.cs", diff --git a/tests/fixtures/summaries/mosdump_partial_and_guarded.facts.json b/tests/fixtures/summaries/mosdump_partial_and_guarded.facts.json index 01f01310..efbb332c 100644 --- a/tests/fixtures/summaries/mosdump_partial_and_guarded.facts.json +++ b/tests/fixtures/summaries/mosdump_partial_and_guarded.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Guarded", "functions": [ { diff --git a/tests/fixtures/summaries/mosdump_partial_and_guarded.summaries.json b/tests/fixtures/summaries/mosdump_partial_and_guarded.summaries.json index 679a66c8..c755f4e9 100644 --- a/tests/fixtures/summaries/mosdump_partial_and_guarded.summaries.json +++ b/tests/fixtures/summaries/mosdump_partial_and_guarded.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Guarded", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "pg.cs", diff --git a/tests/fixtures/summaries/mosdump_return_chains.facts.json b/tests/fixtures/summaries/mosdump_return_chains.facts.json index 44d7b143..d3642e2d 100644 --- a/tests/fixtures/summaries/mosdump_return_chains.facts.json +++ b/tests/fixtures/summaries/mosdump_return_chains.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "ReturnChains", "functions": [ { diff --git a/tests/fixtures/summaries/mosdump_return_chains.summaries.json b/tests/fixtures/summaries/mosdump_return_chains.summaries.json index 254f649d..77aec7c6 100644 --- a/tests/fixtures/summaries/mosdump_return_chains.summaries.json +++ b/tests/fixtures/summaries/mosdump_return_chains.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "ReturnChains", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "cyc.cs", diff --git a/tests/fixtures/summaries/mosdump_scc_cycles.facts.json b/tests/fixtures/summaries/mosdump_scc_cycles.facts.json index 65d4fa79..7c13595a 100644 --- a/tests/fixtures/summaries/mosdump_scc_cycles.facts.json +++ b/tests/fixtures/summaries/mosdump_scc_cycles.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "SccCycles", "functions": [ { diff --git a/tests/fixtures/summaries/mosdump_scc_cycles.summaries.json b/tests/fixtures/summaries/mosdump_scc_cycles.summaries.json index 56341b0c..09e79cdf 100644 --- a/tests/fixtures/summaries/mosdump_scc_cycles.summaries.json +++ b/tests/fixtures/summaries/mosdump_scc_cycles.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "SccCycles", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "cy.cs", diff --git a/tests/fixtures/summaries/mosdump_sig_vocabulary.facts.json b/tests/fixtures/summaries/mosdump_sig_vocabulary.facts.json index 6290f4af..3b77bb6e 100644 --- a/tests/fixtures/summaries/mosdump_sig_vocabulary.facts.json +++ b/tests/fixtures/summaries/mosdump_sig_vocabulary.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "SigVocab", "functions": [ { diff --git a/tests/fixtures/summaries/mosdump_sig_vocabulary.summaries.json b/tests/fixtures/summaries/mosdump_sig_vocabulary.summaries.json index 9d76cb7e..5b4fd663 100644 --- a/tests/fixtures/summaries/mosdump_sig_vocabulary.summaries.json +++ b/tests/fixtures/summaries/mosdump_sig_vocabulary.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "SigVocab", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "f.cs", diff --git a/tests/fixtures/summaries/mosdump_sink_channels.facts.json b/tests/fixtures/summaries/mosdump_sink_channels.facts.json index dca63604..fb91d404 100644 --- a/tests/fixtures/summaries/mosdump_sink_channels.facts.json +++ b/tests/fixtures/summaries/mosdump_sink_channels.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Sinks", "functions": [ { diff --git a/tests/fixtures/summaries/mosdump_sink_channels.summaries.json b/tests/fixtures/summaries/mosdump_sink_channels.summaries.json index 00e2bc77..5b177b87 100644 --- a/tests/fixtures/summaries/mosdump_sink_channels.summaries.json +++ b/tests/fixtures/summaries/mosdump_sink_channels.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Sinks", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "sk.cs", diff --git a/tests/fixtures/summaries/proven_call_bad_section.summaries.json b/tests/fixtures/summaries/proven_call_bad_section.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/proven_call_bad_section.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/proven_call_empty_callee.summaries.json b/tests/fixtures/summaries/proven_call_empty_callee.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/proven_call_empty_callee.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/proven_call_missing_callee_record.summaries.json b/tests/fixtures/summaries/proven_call_missing_callee_record.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/proven_call_missing_callee_record.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/proven_call_no_section.summaries.json b/tests/fixtures/summaries/proven_call_no_section.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/proven_call_no_section.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/proven_call_no_site_record.summaries.json b/tests/fixtures/summaries/proven_call_no_site_record.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/proven_call_no_site_record.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/proven_call_outside_region.summaries.json b/tests/fixtures/summaries/proven_call_outside_region.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/proven_call_outside_region.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/proven_call_site_not_a_string.summaries.json b/tests/fixtures/summaries/proven_call_site_not_a_string.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/proven_call_site_not_a_string.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/proven_call_unknown_callee.summaries.json b/tests/fixtures/summaries/proven_call_unknown_callee.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/proven_call_unknown_callee.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/proven_call_unknown_site.summaries.json b/tests/fixtures/summaries/proven_call_unknown_site.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/proven_call_unknown_site.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/proven_call_virtual_in_site.summaries.json b/tests/fixtures/summaries/proven_call_virtual_in_site.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/proven_call_virtual_in_site.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/proven_call_wrong_callee.summaries.json b/tests/fixtures/summaries/proven_call_wrong_callee.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/proven_call_wrong_callee.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/routing_r1_unresolved.summaries.json b/tests/fixtures/summaries/routing_r1_unresolved.summaries.json index 1fd45b51..4d1f709a 100644 --- a/tests/fixtures/summaries/routing_r1_unresolved.summaries.json +++ b/tests/fixtures/summaries/routing_r1_unresolved.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "R1", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } diff --git a/tests/fixtures/summaries/routing_r2_subscribe_self.summaries.json b/tests/fixtures/summaries/routing_r2_subscribe_self.summaries.json index 3c80d2aa..1d1cec01 100644 --- a/tests/fixtures/summaries/routing_r2_subscribe_self.summaries.json +++ b/tests/fixtures/summaries/routing_r2_subscribe_self.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "R2", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } diff --git a/tests/fixtures/summaries/routing_r3_capture_static.summaries.json b/tests/fixtures/summaries/routing_r3_capture_static.summaries.json index 15436bba..6c4b0fb1 100644 --- a/tests/fixtures/summaries/routing_r3_capture_static.summaries.json +++ b/tests/fixtures/summaries/routing_r3_capture_static.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "R3", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } diff --git a/tests/fixtures/summaries/routing_r4_returned_fresh.summaries.json b/tests/fixtures/summaries/routing_r4_returned_fresh.summaries.json index a395834e..69f07d48 100644 --- a/tests/fixtures/summaries/routing_r4_returned_fresh.summaries.json +++ b/tests/fixtures/summaries/routing_r4_returned_fresh.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "R4", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } diff --git a/tests/fixtures/summaries/routing_r5_di_capture.summaries.json b/tests/fixtures/summaries/routing_r5_di_capture.summaries.json index 17194997..f96dfbe1 100644 --- a/tests/fixtures/summaries/routing_r5_di_capture.summaries.json +++ b/tests/fixtures/summaries/routing_r5_di_capture.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "R5", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } diff --git a/tests/fixtures/summaries/routing_r6_token_kinds.summaries.json b/tests/fixtures/summaries/routing_r6_token_kinds.summaries.json index 74811789..a1a4fa8f 100644 --- a/tests/fixtures/summaries/routing_r6_token_kinds.summaries.json +++ b/tests/fixtures/summaries/routing_r6_token_kinds.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "R6", - "ownir_version": 1, + "ownir_version": 2, "summaries": [], "unresolved": [] } diff --git a/tests/fixtures/summaries/typestate_cs_a1_alias_of_entity.summaries.json b/tests/fixtures/summaries/typestate_cs_a1_alias_of_entity.summaries.json index 66ecf19d..159750cd 100644 --- a/tests/fixtures/summaries/typestate_cs_a1_alias_of_entity.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_a1_alias_of_entity.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/A1_alias_of_entity.cs", diff --git a/tests/fixtures/summaries/typestate_cs_a2_entity_through_indexer.summaries.json b/tests/fixtures/summaries/typestate_cs_a2_entity_through_indexer.summaries.json index 1ad05239..e993a475 100644 --- a/tests/fixtures/summaries/typestate_cs_a2_entity_through_indexer.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_a2_entity_through_indexer.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/A2_entity_through_indexer.cs", diff --git a/tests/fixtures/summaries/typestate_cs_g6_capability_not_spent.summaries.json b/tests/fixtures/summaries/typestate_cs_g6_capability_not_spent.summaries.json index 8f95b7e2..7a15d8b5 100644 --- a/tests/fixtures/summaries/typestate_cs_g6_capability_not_spent.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_g6_capability_not_spent.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/G6_capability_not_spent.cs", diff --git a/tests/fixtures/summaries/typestate_cs_h1a_harmless_call.summaries.json b/tests/fixtures/summaries/typestate_cs_h1a_harmless_call.summaries.json new file mode 100644 index 00000000..e2806003 --- /dev/null +++ b/tests/fixtures/summaries/typestate_cs_h1a_harmless_call.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1aHarmlessCall.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/typestate_cs_h1b_transitive_pure.summaries.json b/tests/fixtures/summaries/typestate_cs_h1b_transitive_pure.summaries.json new file mode 100644 index 00000000..35fdd13a --- /dev/null +++ b/tests/fixtures/summaries/typestate_cs_h1b_transitive_pure.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1b_transitive_pure.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1bTransitivePure.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/typestate_cs_h1c_pure_scc.summaries.json b/tests/fixtures/summaries/typestate_cs_h1c_pure_scc.summaries.json new file mode 100644 index 00000000..c9df6931 --- /dev/null +++ b/tests/fixtures/summaries/typestate_cs_h1c_pure_scc.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1c_pure_scc.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1cPureScc.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/typestate_cs_h1d_global_state.summaries.json b/tests/fixtures/summaries/typestate_cs_h1d_global_state.summaries.json new file mode 100644 index 00000000..4babf4b2 --- /dev/null +++ b/tests/fixtures/summaries/typestate_cs_h1d_global_state.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1d_global_state.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1dGlobalState.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/typestate_cs_h1e_transitive_global.summaries.json b/tests/fixtures/summaries/typestate_cs_h1e_transitive_global.summaries.json new file mode 100644 index 00000000..fe9aa117 --- /dev/null +++ b/tests/fixtures/summaries/typestate_cs_h1e_transitive_global.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1eTransitiveGlobal.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/typestate_cs_h1f_polluted_scc.summaries.json b/tests/fixtures/summaries/typestate_cs_h1f_polluted_scc.summaries.json new file mode 100644 index 00000000..0931a9ca --- /dev/null +++ b/tests/fixtures/summaries/typestate_cs_h1f_polluted_scc.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1fPollutedScc.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/typestate_cs_h1g_transitive_unknown.summaries.json b/tests/fixtures/summaries/typestate_cs_h1g_transitive_unknown.summaries.json new file mode 100644 index 00000000..2a8f65d7 --- /dev/null +++ b/tests/fixtures/summaries/typestate_cs_h1g_transitive_unknown.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1gTransitiveUnknown.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/typestate_cs_h1h_mutates_entity.summaries.json b/tests/fixtures/summaries/typestate_cs_h1h_mutates_entity.summaries.json new file mode 100644 index 00000000..be6a86b8 --- /dev/null +++ b/tests/fixtures/summaries/typestate_cs_h1h_mutates_entity.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1h_mutates_entity.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1hMutatesEntity.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/typestate_cs_h1i_escapes_entity.summaries.json b/tests/fixtures/summaries/typestate_cs_h1i_escapes_entity.summaries.json new file mode 100644 index 00000000..02d44965 --- /dev/null +++ b/tests/fixtures/summaries/typestate_cs_h1i_escapes_entity.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1i_escapes_entity.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1iEscapesEntity.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/typestate_cs_h1j_mutates_outer_value.summaries.json b/tests/fixtures/summaries/typestate_cs_h1j_mutates_outer_value.summaries.json new file mode 100644 index 00000000..8c6dcc3a --- /dev/null +++ b/tests/fixtures/summaries/typestate_cs_h1j_mutates_outer_value.summaries.json @@ -0,0 +1,41 @@ +{ + "degraded": null, + "module": "Extracted", + "ownir_version": 2, + "summaries": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs", + "line": 0, + "method": "Own.Protocols.Cases.H1jMutatesOuterValue.Run", + "params": [], + "returns": { + "owned": "none" + }, + "source": "inferred" + }, + { + "file": "frontend/roslyn/protocol-samples/Api/ProtocolApi.cs", + "line": 0, + "method": "Own.Protocols.Sample.ApprovedOrder.Ship", + "params": [ + { + "disposable": true, + "index": 0, + "name": "token", + "transfer": "must" + }, + { + "disposable": true, + "index": 1, + "name": "entity", + "transfer": "no" + } + ], + "returns": { + "owned": "none" + }, + "source": "inferred" + } + ], + "unresolved": [] +} diff --git a/tests/fixtures/summaries/typestate_cs_l10_region_inside_try.summaries.json b/tests/fixtures/summaries/typestate_cs_l10_region_inside_try.summaries.json index d51857e9..4684be28 100644 --- a/tests/fixtures/summaries/typestate_cs_l10_region_inside_try.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l10_region_inside_try.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L10_region_inside_try.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l11_region_beside_disposable.summaries.json b/tests/fixtures/summaries/typestate_cs_l11_region_beside_disposable.summaries.json index 1f17c842..295ac1e0 100644 --- a/tests/fixtures/summaries/typestate_cs_l11_region_beside_disposable.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l11_region_beside_disposable.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L11_region_beside_disposable.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l12_region_beside_leaked_disposable.summaries.json b/tests/fixtures/summaries/typestate_cs_l12_region_beside_leaked_disposable.summaries.json index b609e4a5..468b3f69 100644 --- a/tests/fixtures/summaries/typestate_cs_l12_region_beside_leaked_disposable.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l12_region_beside_leaked_disposable.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L12_region_beside_leaked_disposable.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l13_values_captured_into_region.summaries.json b/tests/fixtures/summaries/typestate_cs_l13_values_captured_into_region.summaries.json index a27019a2..567a112f 100644 --- a/tests/fixtures/summaries/typestate_cs_l13_values_captured_into_region.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l13_values_captured_into_region.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L13_values_captured_into_region.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l1_stale_capability.summaries.json b/tests/fixtures/summaries/typestate_cs_l1_stale_capability.summaries.json index 0a18d7b4..1d5f5a78 100644 --- a/tests/fixtures/summaries/typestate_cs_l1_stale_capability.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l1_stale_capability.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L1_stale_capability.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l2_copied_capability.summaries.json b/tests/fixtures/summaries/typestate_cs_l2_copied_capability.summaries.json index 9a093a97..93dcdc2d 100644 --- a/tests/fixtures/summaries/typestate_cs_l2_copied_capability.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l2_copied_capability.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L2_copied_capability.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l3_raw_mutation.summaries.json b/tests/fixtures/summaries/typestate_cs_l3_raw_mutation.summaries.json index ee502f80..eff59d2f 100644 --- a/tests/fixtures/summaries/typestate_cs_l3_raw_mutation.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l3_raw_mutation.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L3_raw_mutation.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l4_raw_escape.summaries.json b/tests/fixtures/summaries/typestate_cs_l4_raw_escape.summaries.json index cf1196e0..f91f2a6f 100644 --- a/tests/fixtures/summaries/typestate_cs_l4_raw_escape.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l4_raw_escape.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L4_raw_escape.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l5_normal_transition.summaries.json b/tests/fixtures/summaries/typestate_cs_l5_normal_transition.summaries.json index 7284583f..8860f308 100644 --- a/tests/fixtures/summaries/typestate_cs_l5_normal_transition.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l5_normal_transition.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L5_normal_transition.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l6_two_transitions.summaries.json b/tests/fixtures/summaries/typestate_cs_l6_two_transitions.summaries.json index ebc9b1a0..5c077278 100644 --- a/tests/fixtures/summaries/typestate_cs_l6_two_transitions.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l6_two_transitions.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L6_two_transitions.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l6b_chained_transitions.summaries.json b/tests/fixtures/summaries/typestate_cs_l6b_chained_transitions.summaries.json index 96c78b68..c7380775 100644 --- a/tests/fixtures/summaries/typestate_cs_l6b_chained_transitions.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l6b_chained_transitions.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L6b_chained_transitions.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l7_read_after_region.summaries.json b/tests/fixtures/summaries/typestate_cs_l7_read_after_region.summaries.json index c30ede9b..4849f577 100644 --- a/tests/fixtures/summaries/typestate_cs_l7_read_after_region.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l7_read_after_region.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L7_read_after_region.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l8_branch_inside_region.summaries.json b/tests/fixtures/summaries/typestate_cs_l8_branch_inside_region.summaries.json index f96918e0..7e4c2644 100644 --- a/tests/fixtures/summaries/typestate_cs_l8_branch_inside_region.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l8_branch_inside_region.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L8_branch_inside_region.cs", diff --git a/tests/fixtures/summaries/typestate_cs_l9_opaque_calls_around_region.summaries.json b/tests/fixtures/summaries/typestate_cs_l9_opaque_calls_around_region.summaries.json index 97cebfc4..93d89cea 100644 --- a/tests/fixtures/summaries/typestate_cs_l9_opaque_calls_around_region.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_l9_opaque_calls_around_region.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/L9_opaque_calls_around_region.cs", diff --git a/tests/fixtures/summaries/typestate_cs_x1_nested_region_same_entity.summaries.json b/tests/fixtures/summaries/typestate_cs_x1_nested_region_same_entity.summaries.json index dccd8a12..1b9a9c34 100644 --- a/tests/fixtures/summaries/typestate_cs_x1_nested_region_same_entity.summaries.json +++ b/tests/fixtures/summaries/typestate_cs_x1_nested_region_same_entity.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/cases/X1_nested_region_same_entity.cs", diff --git a/tests/fixtures/summaries/typestate_ef_orderbackend.summaries.json b/tests/fixtures/summaries/typestate_ef_orderbackend.summaries.json index 62c162bf..2c10946a 100644 --- a/tests/fixtures/summaries/typestate_ef_orderbackend.summaries.json +++ b/tests/fixtures/summaries/typestate_ef_orderbackend.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Extracted", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "frontend/roslyn/protocol-samples/efcore/OrderBackend/Domain/OrderProtocol.cs", diff --git a/tests/fixtures/summaries/typestate_g6_capability_not_spent.summaries.json b/tests/fixtures/summaries/typestate_g6_capability_not_spent.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_g6_capability_not_spent.summaries.json +++ b/tests/fixtures/summaries/typestate_g6_capability_not_spent.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_l1_stale_capability.summaries.json b/tests/fixtures/summaries/typestate_l1_stale_capability.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_l1_stale_capability.summaries.json +++ b/tests/fixtures/summaries/typestate_l1_stale_capability.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_l2_copied_capability.summaries.json b/tests/fixtures/summaries/typestate_l2_copied_capability.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_l2_copied_capability.summaries.json +++ b/tests/fixtures/summaries/typestate_l2_copied_capability.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_l3_raw_entity_mutation.summaries.json b/tests/fixtures/summaries/typestate_l3_raw_entity_mutation.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_l3_raw_entity_mutation.summaries.json +++ b/tests/fixtures/summaries/typestate_l3_raw_entity_mutation.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_l3b_second_region.summaries.json b/tests/fixtures/summaries/typestate_l3b_second_region.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_l3b_second_region.summaries.json +++ b/tests/fixtures/summaries/typestate_l3b_second_region.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_l4_raw_entity_unknown_call.summaries.json b/tests/fixtures/summaries/typestate_l4_raw_entity_unknown_call.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_l4_raw_entity_unknown_call.summaries.json +++ b/tests/fixtures/summaries/typestate_l4_raw_entity_unknown_call.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_l4b_raw_entity_shared_call.summaries.json b/tests/fixtures/summaries/typestate_l4b_raw_entity_shared_call.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_l4b_raw_entity_shared_call.summaries.json +++ b/tests/fixtures/summaries/typestate_l4b_raw_entity_shared_call.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_l4c_raw_entity_consumed.summaries.json b/tests/fixtures/summaries/typestate_l4c_raw_entity_consumed.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_l4c_raw_entity_consumed.summaries.json +++ b/tests/fixtures/summaries/typestate_l4c_raw_entity_consumed.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_l4d_token_unknown_call.summaries.json b/tests/fixtures/summaries/typestate_l4d_token_unknown_call.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_l4d_token_unknown_call.summaries.json +++ b/tests/fixtures/summaries/typestate_l4d_token_unknown_call.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_l5_normal_transition.summaries.json b/tests/fixtures/summaries/typestate_l5_normal_transition.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_l5_normal_transition.summaries.json +++ b/tests/fixtures/summaries/typestate_l5_normal_transition.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_l5b_two_transitions.summaries.json b/tests/fixtures/summaries/typestate_l5b_two_transitions.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_l5b_two_transitions.summaries.json +++ b/tests/fixtures/summaries/typestate_l5b_two_transitions.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_l5c_read_after_region.summaries.json b/tests/fixtures/summaries/typestate_l5c_read_after_region.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_l5c_read_after_region.summaries.json +++ b/tests/fixtures/summaries/typestate_l5c_read_after_region.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_n1_token_spent_on_other_entity.summaries.json b/tests/fixtures/summaries/typestate_n1_token_spent_on_other_entity.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_n1_token_spent_on_other_entity.summaries.json +++ b/tests/fixtures/summaries/typestate_n1_token_spent_on_other_entity.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_n2_two_tokens_one_region.summaries.json b/tests/fixtures/summaries/typestate_n2_two_tokens_one_region.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_n2_two_tokens_one_region.summaries.json +++ b/tests/fixtures/summaries/typestate_n2_two_tokens_one_region.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_n3_raw_mutation_inferred_effect.summaries.json b/tests/fixtures/summaries/typestate_n3_raw_mutation_inferred_effect.summaries.json index 2d29cfac..b026938d 100644 --- a/tests/fixtures/summaries/typestate_n3_raw_mutation_inferred_effect.summaries.json +++ b/tests/fixtures/summaries/typestate_n3_raw_mutation_inferred_effect.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_n4_token_outlives_region.summaries.json b/tests/fixtures/summaries/typestate_n4_token_outlives_region.summaries.json index 08d2f970..2e5b52c7 100644 --- a/tests/fixtures/summaries/typestate_n4_token_outlives_region.summaries.json +++ b/tests/fixtures/summaries/typestate_n4_token_outlives_region.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Orders.cs", diff --git a/tests/fixtures/summaries/typestate_w1_loan_wordings.summaries.json b/tests/fixtures/summaries/typestate_w1_loan_wordings.summaries.json index bc5f4df3..be33f02d 100644 --- a/tests/fixtures/summaries/typestate_w1_loan_wordings.summaries.json +++ b/tests/fixtures/summaries/typestate_w1_loan_wordings.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Wordings.cs", diff --git a/tests/fixtures/summaries/typestate_w2_loan_wordings_pooled.summaries.json b/tests/fixtures/summaries/typestate_w2_loan_wordings_pooled.summaries.json index bc5f4df3..be33f02d 100644 --- a/tests/fixtures/summaries/typestate_w2_loan_wordings_pooled.summaries.json +++ b/tests/fixtures/summaries/typestate_w2_loan_wordings_pooled.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "TypestateGate", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "Wordings.cs", diff --git a/tests/fixtures/summaries/vocab_unknown_op.summaries.json b/tests/fixtures/summaries/vocab_unknown_op.summaries.json index 4394ccd5..9d883306 100644 --- a/tests/fixtures/summaries/vocab_unknown_op.summaries.json +++ b/tests/fixtures/summaries/vocab_unknown_op.summaries.json @@ -1,7 +1,7 @@ { "degraded": null, "module": "Vocab", - "ownir_version": 1, + "ownir_version": 2, "summaries": [ { "file": "F.cs", diff --git a/tests/fixtures/verdict_renders/render_anchorless.facts.json b/tests/fixtures/verdict_renders/render_anchorless.facts.json index 18d56b29..24ec7585 100644 --- a/tests/fixtures/verdict_renders/render_anchorless.facts.json +++ b/tests/fixtures/verdict_renders/render_anchorless.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Anchorless", "_doc": [ "OWN052 is anchorless by nature (file '?', line 0), so its SARIF location", diff --git a/tests/fixtures/verdict_renders/render_anchorless.renders.json b/tests/fixtures/verdict_renders/render_anchorless.renders.json index 107cd829..fca9449d 100644 --- a/tests/fixtures/verdict_renders/render_anchorless.renders.json +++ b/tests/fixtures/verdict_renders/render_anchorless.renders.json @@ -51,7 +51,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, @@ -98,7 +98,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, diff --git a/tests/fixtures/verdict_renders/render_columns.facts.json b/tests/fixtures/verdict_renders/render_columns.facts.json index f2d8d920..c173b0e1 100644 --- a/tests/fixtures/verdict_renders/render_columns.facts.json +++ b/tests/fixtures/verdict_renders/render_columns.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Columns", "_doc": [ "A reported column rides into SARIF as region.startColumn, and only ever", diff --git a/tests/fixtures/verdict_renders/render_columns.renders.json b/tests/fixtures/verdict_renders/render_columns.renders.json index 2dbd8259..3be1735e 100644 --- a/tests/fixtures/verdict_renders/render_columns.renders.json +++ b/tests/fixtures/verdict_renders/render_columns.renders.json @@ -59,7 +59,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, @@ -137,7 +137,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, diff --git a/tests/fixtures/verdict_renders/render_empty.facts.json b/tests/fixtures/verdict_renders/render_empty.facts.json index d615097a..7d9ebcb0 100644 --- a/tests/fixtures/verdict_renders/render_empty.facts.json +++ b/tests/fixtures/verdict_renders/render_empty.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Empty", "_doc": [ "A clean document: every line-per-finding surface is an empty list and the", diff --git a/tests/fixtures/verdict_renders/render_empty.renders.json b/tests/fixtures/verdict_renders/render_empty.renders.json index e188a4c9..5214e603 100644 --- a/tests/fixtures/verdict_renders/render_empty.renders.json +++ b/tests/fixtures/verdict_renders/render_empty.renders.json @@ -28,7 +28,7 @@ "informationUri": "https://github.com/PhysShell/Own.NET", "rules": [], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, @@ -47,7 +47,7 @@ "informationUri": "https://github.com/PhysShell/Own.NET", "rules": [], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, diff --git a/tests/fixtures/verdict_renders/render_escaping.facts.json b/tests/fixtures/verdict_renders/render_escaping.facts.json index eeec9268..d756b0fe 100644 --- a/tests/fixtures/verdict_renders/render_escaping.facts.json +++ b/tests/fixtures/verdict_renders/render_escaping.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Escaping", "_doc": [ "Every workflow-command escaping rule in one document. The component file", diff --git a/tests/fixtures/verdict_renders/render_escaping.renders.json b/tests/fixtures/verdict_renders/render_escaping.renders.json index db52add2..574e546d 100644 --- a/tests/fixtures/verdict_renders/render_escaping.renders.json +++ b/tests/fixtures/verdict_renders/render_escaping.renders.json @@ -51,7 +51,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, @@ -103,7 +103,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, diff --git a/tests/fixtures/verdict_renders/render_evidence_slices.facts.json b/tests/fixtures/verdict_renders/render_evidence_slices.facts.json index be179c81..fed48250 100644 --- a/tests/fixtures/verdict_renders/render_evidence_slices.facts.json +++ b/tests/fixtures/verdict_renders/render_evidence_slices.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Evidence", "_doc": [ "The two evidence projections: `related` -> relatedLocations and the ordered", diff --git a/tests/fixtures/verdict_renders/render_evidence_slices.renders.json b/tests/fixtures/verdict_renders/render_evidence_slices.renders.json index a246d37d..2bb0aee7 100644 --- a/tests/fixtures/verdict_renders/render_evidence_slices.renders.json +++ b/tests/fixtures/verdict_renders/render_evidence_slices.renders.json @@ -59,7 +59,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, @@ -244,7 +244,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, diff --git a/tests/fixtures/verdict_renders/render_protocol_family.facts.json b/tests/fixtures/verdict_renders/render_protocol_family.facts.json index a5b24fb1..674f0a4c 100644 --- a/tests/fixtures/verdict_renders/render_protocol_family.facts.json +++ b/tests/fixtures/verdict_renders/render_protocol_family.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Protocols", "_doc": [ "BR-V9 over the OBL family (#259 checkpoint 4b), two surfaces in one", diff --git a/tests/fixtures/verdict_renders/render_protocol_family.renders.json b/tests/fixtures/verdict_renders/render_protocol_family.renders.json index ced801e2..edaf645f 100644 --- a/tests/fixtures/verdict_renders/render_protocol_family.renders.json +++ b/tests/fixtures/verdict_renders/render_protocol_family.renders.json @@ -87,7 +87,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, @@ -342,7 +342,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, diff --git a/tests/fixtures/verdict_renders/render_refusal.facts.json b/tests/fixtures/verdict_renders/render_refusal.facts.json index 65d18472..5fe39eb4 100644 --- a/tests/fixtures/verdict_renders/render_refusal.facts.json +++ b/tests/fixtures/verdict_renders/render_refusal.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Refusal", "_doc": [ "A document the bridge refuses has no findings to render, so the rendered", diff --git a/tests/fixtures/verdict_renders/render_rule_catalogue.facts.json b/tests/fixtures/verdict_renders/render_rule_catalogue.facts.json index 1b509668..ba756279 100644 --- a/tests/fixtures/verdict_renders/render_rule_catalogue.facts.json +++ b/tests/fixtures/verdict_renders/render_rule_catalogue.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Catalogue", "_doc": [ "The SARIF log's TWO orderings, in a document where they disagree. The", diff --git a/tests/fixtures/verdict_renders/render_rule_catalogue.renders.json b/tests/fixtures/verdict_renders/render_rule_catalogue.renders.json index aaaa1b79..19872d92 100644 --- a/tests/fixtures/verdict_renders/render_rule_catalogue.renders.json +++ b/tests/fixtures/verdict_renders/render_rule_catalogue.renders.json @@ -73,7 +73,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, @@ -181,7 +181,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, diff --git a/tests/fixtures/verdict_renders/render_tiers_and_levels.facts.json b/tests/fixtures/verdict_renders/render_tiers_and_levels.facts.json index ea10fbf1..c34dc1be 100644 --- a/tests/fixtures/verdict_renders/render_tiers_and_levels.facts.json +++ b/tests/fixtures/verdict_renders/render_tiers_and_levels.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Tiers", "_doc": [ "One document carrying all three SARIF levels and both suppression states:", diff --git a/tests/fixtures/verdict_renders/render_tiers_and_levels.renders.json b/tests/fixtures/verdict_renders/render_tiers_and_levels.renders.json index 61e5451c..c6cfc723 100644 --- a/tests/fixtures/verdict_renders/render_tiers_and_levels.renders.json +++ b/tests/fixtures/verdict_renders/render_tiers_and_levels.renders.json @@ -81,7 +81,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, @@ -220,7 +220,7 @@ } ], "properties": { - "ownirSchemaVersion": 1 + "ownirSchemaVersion": 2 } } }, diff --git a/tests/fixtures/verdicts/proven_call_bad_section.verdicts.json b/tests/fixtures/verdicts/proven_call_bad_section.verdicts.json new file mode 100644 index 00000000..3e2a9ae2 --- /dev/null +++ b/tests/fixtures/verdicts/proven_call_bad_section.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'heap_effects' section is malformed — heap-effect facts: heap_effects_version must be 1" +} diff --git a/tests/fixtures/verdicts/proven_call_empty_callee.verdicts.json b/tests/fixtures/verdicts/proven_call_empty_callee.verdicts.json new file mode 100644 index 00000000..51609ad0 --- /dev/null +++ b/tests/fixtures/verdicts/proven_call_empty_callee.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR flow op 'proven_call' needs a non-empty string 'site' and a non-empty string 'callee' (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18)" +} diff --git a/tests/fixtures/verdicts/proven_call_missing_callee_record.verdicts.json b/tests/fixtures/verdicts/proven_call_missing_callee_record.verdicts.json new file mode 100644 index 00000000..060d695e --- /dev/null +++ b/tests/fixtures/verdicts/proven_call_missing_callee_record.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)' is not proven harmless: 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)' has no summary (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/verdicts/proven_call_no_section.verdicts.json b/tests/fixtures/verdicts/proven_call_no_section.verdicts.json new file mode 100644 index 00000000..8e02ede2 --- /dev/null +++ b/tests/fixtures/verdicts/proven_call_no_section.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) needs the 'heap_effects' section — refused: a call with no effect evidence is not harmless" +} diff --git a/tests/fixtures/verdicts/proven_call_no_site_record.verdicts.json b/tests/fixtures/verdicts/proven_call_no_site_record.verdicts.json new file mode 100644 index 00000000..21524b1a --- /dev/null +++ b/tests/fixtures/verdicts/proven_call_no_site_record.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' site 'site:frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18:21' has no record in 'heap_effects' (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: no evidence is not harmless" +} diff --git a/tests/fixtures/verdicts/proven_call_outside_region.verdicts.json b/tests/fixtures/verdicts/proven_call_outside_region.verdicts.json new file mode 100644 index 00000000..e284f6db --- /dev/null +++ b/tests/fixtures/verdicts/proven_call_outside_region.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' outside a borrow_mut region (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: the op admits a call only inside an exclusive region" +} diff --git a/tests/fixtures/verdicts/proven_call_site_not_a_string.verdicts.json b/tests/fixtures/verdicts/proven_call_site_not_a_string.verdicts.json new file mode 100644 index 00000000..51609ad0 --- /dev/null +++ b/tests/fixtures/verdicts/proven_call_site_not_a_string.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR flow op 'proven_call' needs a non-empty string 'site' and a non-empty string 'callee' (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18)" +} diff --git a/tests/fixtures/verdicts/proven_call_unknown_callee.verdicts.json b/tests/fixtures/verdicts/proven_call_unknown_callee.verdicts.json new file mode 100644 index 00000000..8e58353b --- /dev/null +++ b/tests/fixtures/verdicts/proven_call_unknown_callee.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)' is not proven harmless: 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)': writes.instance is unknown (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/verdicts/proven_call_unknown_site.verdicts.json b/tests/fixtures/verdicts/proven_call_unknown_site.verdicts.json new file mode 100644 index 00000000..c1555951 --- /dev/null +++ b/tests/fixtures/verdicts/proven_call_unknown_site.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)' is not proven harmless: the call site: writes.instance is unknown (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/verdicts/proven_call_virtual_in_site.verdicts.json b/tests/fixtures/verdicts/proven_call_virtual_in_site.verdicts.json new file mode 100644 index 00000000..5e4cf47e --- /dev/null +++ b/tests/fixtures/verdicts/proven_call_virtual_in_site.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1aHarmlessCall.Twice(int)' is not proven harmless: 'Own.Protocols.Cases.IClock.Ticks()' is virtual (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/verdicts/proven_call_wrong_callee.verdicts.json b/tests/fixtures/verdicts/proven_call_wrong_callee.verdicts.json new file mode 100644 index 00000000..6f3c6909 --- /dev/null +++ b/tests/fixtures/verdicts/proven_call_wrong_callee.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1aHarmlessCall.Thrice(int)' is not proven harmless: the site does not call 'Own.Protocols.Cases.H1aHarmlessCall.Thrice(int)' directly (frontend/roslyn/protocol-samples/cases/H1a_harmless_call.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/verdicts/typestate_cs_h1a_harmless_call.verdicts.json b/tests/fixtures/verdicts/typestate_cs_h1a_harmless_call.verdicts.json new file mode 100644 index 00000000..9454b37e --- /dev/null +++ b/tests/fixtures/verdicts/typestate_cs_h1a_harmless_call.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "findings": [] +} diff --git a/tests/fixtures/verdicts/typestate_cs_h1b_transitive_pure.verdicts.json b/tests/fixtures/verdicts/typestate_cs_h1b_transitive_pure.verdicts.json new file mode 100644 index 00000000..9454b37e --- /dev/null +++ b/tests/fixtures/verdicts/typestate_cs_h1b_transitive_pure.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "findings": [] +} diff --git a/tests/fixtures/verdicts/typestate_cs_h1c_pure_scc.verdicts.json b/tests/fixtures/verdicts/typestate_cs_h1c_pure_scc.verdicts.json new file mode 100644 index 00000000..9454b37e --- /dev/null +++ b/tests/fixtures/verdicts/typestate_cs_h1c_pure_scc.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "findings": [] +} diff --git a/tests/fixtures/verdicts/typestate_cs_h1d_global_state.verdicts.json b/tests/fixtures/verdicts/typestate_cs_h1d_global_state.verdicts.json new file mode 100644 index 00000000..2b854474 --- /dev/null +++ b/tests/fixtures/verdicts/typestate_cs_h1d_global_state.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1dGlobalState.TouchesGlobalState()' is not proven harmless: 'Own.Protocols.Cases.H1dGlobalState.TouchesGlobalState()': writes.static is may (frontend/roslyn/protocol-samples/cases/H1d_global_state.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/verdicts/typestate_cs_h1e_transitive_global.verdicts.json b/tests/fixtures/verdicts/typestate_cs_h1e_transitive_global.verdicts.json new file mode 100644 index 00000000..4a95ec9c --- /dev/null +++ b/tests/fixtures/verdicts/typestate_cs_h1e_transitive_global.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1eTransitiveGlobal.A(int)' is not proven harmless: 'Own.Protocols.Cases.H1eTransitiveGlobal.A(int)': writes.static is may (frontend/roslyn/protocol-samples/cases/H1e_transitive_global.cs:19) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/verdicts/typestate_cs_h1f_polluted_scc.verdicts.json b/tests/fixtures/verdicts/typestate_cs_h1f_polluted_scc.verdicts.json new file mode 100644 index 00000000..743f68a9 --- /dev/null +++ b/tests/fixtures/verdicts/typestate_cs_h1f_polluted_scc.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1fPollutedScc.Ping(int)' is not proven harmless: 'Own.Protocols.Cases.H1fPollutedScc.Ping(int)': writes.static is may (frontend/roslyn/protocol-samples/cases/H1f_polluted_scc.cs:19) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/verdicts/typestate_cs_h1g_transitive_unknown.verdicts.json b/tests/fixtures/verdicts/typestate_cs_h1g_transitive_unknown.verdicts.json new file mode 100644 index 00000000..e81ac843 --- /dev/null +++ b/tests/fixtures/verdicts/typestate_cs_h1g_transitive_unknown.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1gTransitiveUnknown.A(int)' is not proven harmless: 'Own.Protocols.Cases.H1gTransitiveUnknown.A(int)': writes.instance is unknown (frontend/roslyn/protocol-samples/cases/H1g_transitive_unknown.cs:18) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/verdicts/typestate_cs_h1h_mutates_entity.verdicts.json b/tests/fixtures/verdicts/typestate_cs_h1h_mutates_entity.verdicts.json new file mode 100644 index 00000000..35559649 --- /dev/null +++ b/tests/fixtures/verdicts/typestate_cs_h1h_mutates_entity.verdicts.json @@ -0,0 +1,21 @@ +{ + "verdicts_version": 1, + "findings": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1h_mutates_entity.cs", + "line": 15, + "code": "OWN013", + "component": "Own.Protocols.Cases.H1hMutatesEntity.Run", + "event": "order", + "handler": "", + "message": "IDisposable local 'order' is used directly while an exclusive borrow of it is live", + "kind": "disposable", + "advisory": false, + "severity": null, + "related": [], + "flow": [], + "ignore_reason": null, + "column": null + } + ] +} diff --git a/tests/fixtures/verdicts/typestate_cs_h1i_escapes_entity.verdicts.json b/tests/fixtures/verdicts/typestate_cs_h1i_escapes_entity.verdicts.json new file mode 100644 index 00000000..c7891172 --- /dev/null +++ b/tests/fixtures/verdicts/typestate_cs_h1i_escapes_entity.verdicts.json @@ -0,0 +1,21 @@ +{ + "verdicts_version": 1, + "findings": [ + { + "file": "frontend/roslyn/protocol-samples/cases/H1i_escapes_entity.cs", + "line": 16, + "code": "OWN013", + "component": "Own.Protocols.Cases.H1iEscapesEntity.Run", + "event": "order", + "handler": "", + "message": "IDisposable local 'order' is used directly while an exclusive borrow of it is live", + "kind": "disposable", + "advisory": false, + "severity": null, + "related": [], + "flow": [], + "ignore_reason": null, + "column": null + } + ] +} diff --git a/tests/fixtures/verdicts/typestate_cs_h1j_mutates_outer_value.verdicts.json b/tests/fixtures/verdicts/typestate_cs_h1j_mutates_outer_value.verdicts.json new file mode 100644 index 00000000..044b7d79 --- /dev/null +++ b/tests/fixtures/verdicts/typestate_cs_h1j_mutates_outer_value.verdicts.json @@ -0,0 +1,4 @@ +{ + "verdicts_version": 1, + "error": "OwnIR 'proven_call' to 'Own.Protocols.Cases.H1jMutatesOuterValue.Fill(int[])' is not proven harmless: 'Own.Protocols.Cases.H1jMutatesOuterValue.Fill(int[])': parameter 0 is borrow_mut (frontend/roslyn/protocol-samples/cases/H1j_mutates_outer_value.cs:20) — refused: an exclusive region admits only calls the effect summaries prove harmless" +} diff --git a/tests/fixtures/verdicts/verdict_boundary_effect_line_negative.facts.json b/tests/fixtures/verdicts/verdict_boundary_effect_line_negative.facts.json index 7db44663..f082a63e 100644 --- a/tests/fixtures/verdicts/verdict_boundary_effect_line_negative.facts.json +++ b/tests/fixtures/verdicts/verdict_boundary_effect_line_negative.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Bound", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_boundary_line_above_u32.facts.json b/tests/fixtures/verdicts/verdict_boundary_line_above_u32.facts.json index 000653c1..3d79f938 100644 --- a/tests/fixtures/verdicts/verdict_boundary_line_above_u32.facts.json +++ b/tests/fixtures/verdicts/verdict_boundary_line_above_u32.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Bound", "_doc": [ "The upper edge of the same promoted control: an acquire at 2^32 is outside", diff --git a/tests/fixtures/verdicts/verdict_boundary_line_negative.facts.json b/tests/fixtures/verdicts/verdict_boundary_line_negative.facts.json index fabde6a7..1419ecec 100644 --- a/tests/fixtures/verdicts/verdict_boundary_line_negative.facts.json +++ b/tests/fixtures/verdicts/verdict_boundary_line_negative.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Bound", "_doc": [ "A promoted #259 coordinate-domain control: a negative param line. Before", diff --git a/tests/fixtures/verdicts/verdict_boundary_service_line_negative.facts.json b/tests/fixtures/verdicts/verdict_boundary_service_line_negative.facts.json index 5861b2a7..a17a663c 100644 --- a/tests/fixtures/verdicts/verdict_boundary_service_line_negative.facts.json +++ b/tests/fixtures/verdicts/verdict_boundary_service_line_negative.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Bound", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_column_sort_order.facts.json b/tests/fixtures/verdicts/verdict_column_sort_order.facts.json index daf8a879..0dbe6146 100644 --- a/tests/fixtures/verdicts/verdict_column_sort_order.facts.json +++ b/tests/fixtures/verdicts/verdict_column_sort_order.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Cols", "_doc": [ "BR-V8's column member: two leaks on the SAME line are minted in the order b", diff --git a/tests/fixtures/verdicts/verdict_dedup_key_members.facts.json b/tests/fixtures/verdicts/verdict_dedup_key_members.facts.json index c836f39c..b09d3107 100644 --- a/tests/fixtures/verdicts/verdict_dedup_key_members.facts.json +++ b/tests/fixtures/verdicts/verdict_dedup_key_members.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DedupKeyMembers", "_doc": [ "BR-V7 key members that survive only because they are IN the key, now that", diff --git a/tests/fixtures/verdicts/verdict_dedup_needs_the_message.facts.json b/tests/fixtures/verdicts/verdict_dedup_needs_the_message.facts.json index 3ceb93d3..9e44faad 100644 --- a/tests/fixtures/verdicts/verdict_dedup_needs_the_message.facts.json +++ b/tests/fixtures/verdicts/verdict_dedup_needs_the_message.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DedupNeedsTheMessage", "_doc": [ "BR-V7's `message` member, which cp4 could not carry and argued was", diff --git a/tests/fixtures/verdicts/verdict_degenerate_metadata.facts.json b/tests/fixtures/verdicts/verdict_degenerate_metadata.facts.json index c9fb182f..832ac542 100644 --- a/tests/fixtures/verdicts/verdict_degenerate_metadata.facts.json +++ b/tests/fixtures/verdicts/verdict_degenerate_metadata.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DegenerateMetadata", "_doc": [ "Metadata that is PRESENT and degenerate, which is not the same as absent.", diff --git a/tests/fixtures/verdicts/verdict_di004_call_site_anchor.facts.json b/tests/fixtures/verdicts/verdict_di004_call_site_anchor.facts.json index 3d275348..7e8b033f 100644 --- a/tests/fixtures/verdicts/verdict_di004_call_site_anchor.facts.json +++ b/tests/fixtures/verdicts/verdict_di004_call_site_anchor.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Di004", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_di005_cache_site_anchor.facts.json b/tests/fixtures/verdicts/verdict_di005_cache_site_anchor.facts.json index 54e94aff..2c875bbf 100644 --- a/tests/fixtures/verdicts/verdict_di005_cache_site_anchor.facts.json +++ b/tests/fixtures/verdicts/verdict_di005_cache_site_anchor.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Di005", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_di_duplicate_sites_last_wins.facts.json b/tests/fixtures/verdicts/verdict_di_duplicate_sites_last_wins.facts.json index 5246092b..d6a27151 100644 --- a/tests/fixtures/verdicts/verdict_di_duplicate_sites_last_wins.facts.json +++ b/tests/fixtures/verdicts/verdict_di_duplicate_sites_last_wins.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DiDup", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_di_evidence_degradations.facts.json b/tests/fixtures/verdicts/verdict_di_evidence_degradations.facts.json index dd351b50..9a44119b 100644 --- a/tests/fixtures/verdicts/verdict_di_evidence_degradations.facts.json +++ b/tests/fixtures/verdicts/verdict_di_evidence_degradations.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DiEvidenceDegradations", "_doc": [ "Two BR-V5 degradations on the DI families. `App` records a consuming ctor", diff --git a/tests/fixtures/verdicts/verdict_di_graph_families.facts.json b/tests/fixtures/verdicts/verdict_di_graph_families.facts.json index 5a60b17c..b5f6f349 100644 --- a/tests/fixtures/verdicts/verdict_di_graph_families.facts.json +++ b/tests/fixtures/verdicts/verdict_di_graph_families.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DiGraph", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_di_tolerant_typed_coercions.facts.json b/tests/fixtures/verdicts/verdict_di_tolerant_typed_coercions.facts.json index a835a566..783ac6b1 100644 --- a/tests/fixtures/verdicts/verdict_di_tolerant_typed_coercions.facts.json +++ b/tests/fixtures/verdicts/verdict_di_tolerant_typed_coercions.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "DiTolerant", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_domain_tolerant_readers.facts.json b/tests/fixtures/verdicts/verdict_domain_tolerant_readers.facts.json index 3b92f3a5..2d0e004b 100644 --- a/tests/fixtures/verdicts/verdict_domain_tolerant_readers.facts.json +++ b/tests/fixtures/verdicts/verdict_domain_tolerant_readers.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Dom", "_doc": [ "The tolerant coordinate readers, where nothing else reaches them. The four", diff --git a/tests/fixtures/verdicts/verdict_door_effect_deps_not_strings.facts.json b/tests/fixtures/verdicts/verdict_door_effect_deps_not_strings.facts.json index 9a10a556..1000987d 100644 --- a/tests/fixtures/verdicts/verdict_door_effect_deps_not_strings.facts.json +++ b/tests/fixtures/verdicts/verdict_door_effect_deps_not_strings.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Door", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_door_service_unknown_lifetime.facts.json b/tests/fixtures/verdicts/verdict_door_service_unknown_lifetime.facts.json index 6e429306..7fe81a69 100644 --- a/tests/fixtures/verdicts/verdict_door_service_unknown_lifetime.facts.json +++ b/tests/fixtures/verdicts/verdict_door_service_unknown_lifetime.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Door", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_eff001_slice_dropped.facts.json b/tests/fixtures/verdicts/verdict_eff001_slice_dropped.facts.json index 42a64a6a..ffc4923a 100644 --- a/tests/fixtures/verdicts/verdict_eff001_slice_dropped.facts.json +++ b/tests/fixtures/verdicts/verdict_eff001_slice_dropped.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Eff001NoSlice", "_doc": [ "BR-V5's line-guard on the effect slice: the storm is a verdict either way,", diff --git a/tests/fixtures/verdicts/verdict_eff001_storm_and_memo.facts.json b/tests/fixtures/verdicts/verdict_eff001_storm_and_memo.facts.json index 020b0c07..b47cfd86 100644 --- a/tests/fixtures/verdicts/verdict_eff001_storm_and_memo.facts.json +++ b/tests/fixtures/verdicts/verdict_eff001_storm_and_memo.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Fx", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_flow_local_wordings.facts.json b/tests/fixtures/verdicts/verdict_flow_local_wordings.facts.json index 3ddb770b..99e2e12a 100644 --- a/tests/fixtures/verdicts/verdict_flow_local_wordings.facts.json +++ b/tests/fixtures/verdicts/verdict_flow_local_wordings.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "FlowLocalWordings", "_doc": [ "BR-V4's flow-local wordings the swept corpora never mint, one function each", diff --git a/tests/fixtures/verdicts/verdict_multi_file_ordering.facts.json b/tests/fixtures/verdicts/verdict_multi_file_ordering.facts.json index 3639865d..1b4decab 100644 --- a/tests/fixtures/verdicts/verdict_multi_file_ordering.facts.json +++ b/tests/fixtures/verdicts/verdict_multi_file_ordering.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Order", "_doc": [ "BR-V8 across families and files: five findings on line 7 in five files sort", diff --git a/tests/fixtures/verdicts/verdict_own014_escape_slice_dropped.facts.json b/tests/fixtures/verdicts/verdict_own014_escape_slice_dropped.facts.json index 94630572..9615cd97 100644 --- a/tests/fixtures/verdicts/verdict_own014_escape_slice_dropped.facts.json +++ b/tests/fixtures/verdicts/verdict_own014_escape_slice_dropped.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Own014NoSlice", "_doc": [ "BR-V5's 'a slice shorter than two steps is dropped', on the OWN014 escape", diff --git a/tests/fixtures/verdicts/verdict_own014_wordings.facts.json b/tests/fixtures/verdicts/verdict_own014_wordings.facts.json index 52f38c4b..5261d55d 100644 --- a/tests/fixtures/verdicts/verdict_own014_wordings.facts.json +++ b/tests/fixtures/verdicts/verdict_own014_wordings.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Own014Wordings", "_doc": [ "The OWN014 wordings the swept corpora never mint. `Cache` is a DI SCOPED", diff --git a/tests/fixtures/verdicts/verdict_own051_gates.facts.json b/tests/fixtures/verdicts/verdict_own051_gates.facts.json index d0c8b018..abafc8fb 100644 --- a/tests/fixtures/verdicts/verdict_own051_gates.facts.json +++ b/tests/fixtures/verdicts/verdict_own051_gates.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Gates", "_doc": [ "BR-L8 / INF-A5 advisories: an owned local dropped after a may-call is silent", diff --git a/tests/fixtures/verdicts/verdict_own053_orphaned_awaitable.facts.json b/tests/fixtures/verdicts/verdict_own053_orphaned_awaitable.facts.json index 4296069f..3e980b5e 100644 --- a/tests/fixtures/verdicts/verdict_own053_orphaned_awaitable.facts.json +++ b/tests/fixtures/verdicts/verdict_own053_orphaned_awaitable.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Orphans", "_doc": [ "BR-V1 / BR-V4 / BR-V8: the OWN053 orphaned-awaitable advisory, promoted from", diff --git a/tests/fixtures/verdicts/verdict_pool_view_anchor.facts.json b/tests/fixtures/verdicts/verdict_pool_view_anchor.facts.json index eb7874a1..1d890ff0 100644 --- a/tests/fixtures/verdicts/verdict_pool_view_anchor.facts.json +++ b/tests/fixtures/verdicts/verdict_pool_view_anchor.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "PoolView", "_doc": [ "OWN025 anchors at the VIEW site (the core's line) with column null ON", diff --git a/tests/fixtures/verdicts/verdict_protocol_absent_rules_are_silent.facts.json b/tests/fixtures/verdicts/verdict_protocol_absent_rules_are_silent.facts.json index a17e3ffd..8d81ab83 100644 --- a/tests/fixtures/verdicts/verdict_protocol_absent_rules_are_silent.facts.json +++ b/tests/fixtures/verdicts/verdict_protocol_absent_rules_are_silent.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Silent", "components": [ { diff --git a/tests/fixtures/verdicts/verdict_protocol_barrier_maybe_two_step_slice.facts.json b/tests/fixtures/verdicts/verdict_protocol_barrier_maybe_two_step_slice.facts.json index ca356c42..efa2324b 100644 --- a/tests/fixtures/verdicts/verdict_protocol_barrier_maybe_two_step_slice.facts.json +++ b/tests/fixtures/verdicts/verdict_protocol_barrier_maybe_two_step_slice.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Docs", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_protocol_beside_other_families.facts.json b/tests/fixtures/verdicts/verdict_protocol_beside_other_families.facts.json index f281b134..57fa4fa8 100644 --- a/tests/fixtures/verdicts/verdict_protocol_beside_other_families.facts.json +++ b/tests/fixtures/verdicts/verdict_protocol_beside_other_families.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Mixed", "components": [ { diff --git a/tests/fixtures/verdicts/verdict_protocol_exit_codes_and_wordings.facts.json b/tests/fixtures/verdicts/verdict_protocol_exit_codes_and_wordings.facts.json index e693c343..918fbdc4 100644 --- a/tests/fixtures/verdicts/verdict_protocol_exit_codes_and_wordings.facts.json +++ b/tests/fixtures/verdicts/verdict_protocol_exit_codes_and_wordings.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Batch", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_protocol_identity_and_line_guards.facts.json b/tests/fixtures/verdicts/verdict_protocol_identity_and_line_guards.facts.json index d43aafe8..a8de1877 100644 --- a/tests/fixtures/verdicts/verdict_protocol_identity_and_line_guards.facts.json +++ b/tests/fixtures/verdicts/verdict_protocol_identity_and_line_guards.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Names", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_protocol_obl005_dead_rule.facts.json b/tests/fixtures/verdicts/verdict_protocol_obl005_dead_rule.facts.json index 29baa75e..e0713cc2 100644 --- a/tests/fixtures/verdicts/verdict_protocol_obl005_dead_rule.facts.json +++ b/tests/fixtures/verdicts/verdict_protocol_obl005_dead_rule.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Ghosts", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_protocol_tolerant_door_rules.facts.json b/tests/fixtures/verdicts/verdict_protocol_tolerant_door_rules.facts.json index 2d53b212..30c799ad 100644 --- a/tests/fixtures/verdicts/verdict_protocol_tolerant_door_rules.facts.json +++ b/tests/fixtures/verdicts/verdict_protocol_tolerant_door_rules.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Tolerant", "components": [], "_doc": [ diff --git a/tests/fixtures/verdicts/verdict_same_site_distinct_events.facts.json b/tests/fixtures/verdicts/verdict_same_site_distinct_events.facts.json index a9045b0c..4b89209b 100644 --- a/tests/fixtures/verdicts/verdict_same_site_distinct_events.facts.json +++ b/tests/fixtures/verdicts/verdict_same_site_distinct_events.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "SameSite", "_doc": [ "BR-V7's key, one pair per member: records on the same line that differ in", diff --git a/tests/fixtures/verdicts/verdict_severity_tiers_and_suppression.facts.json b/tests/fixtures/verdicts/verdict_severity_tiers_and_suppression.facts.json index 2ba04fde..330c8c6a 100644 --- a/tests/fixtures/verdicts/verdict_severity_tiers_and_suppression.facts.json +++ b/tests/fixtures/verdicts/verdict_severity_tiers_and_suppression.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Tiers", "_doc": [ "BR-V6: an injected-source `+=` or ignored `.Subscribe()` is the warning tier;", diff --git a/tests/fixtures/verdicts/verdict_skip_list_artifacts.facts.json b/tests/fixtures/verdicts/verdict_skip_list_artifacts.facts.json index 2dc4b0cb..95969ed7 100644 --- a/tests/fixtures/verdicts/verdict_skip_list_artifacts.facts.json +++ b/tests/fixtures/verdicts/verdict_skip_list_artifacts.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Skip", "_doc": [ "BR-V2, the CLOSED skip list, one control per member the tree can reach:", diff --git a/tests/fixtures/verdicts/verdict_subscription_lambda_note.facts.json b/tests/fixtures/verdicts/verdict_subscription_lambda_note.facts.json index f6f9e6ca..44c56d11 100644 --- a/tests/fixtures/verdicts/verdict_subscription_lambda_note.facts.json +++ b/tests/fixtures/verdicts/verdict_subscription_lambda_note.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "SubscriptionLambdaNote", "_doc": [ "The inline-lambda note on the INJECTED plain-subscription wording. The", diff --git a/tests/fixtures/verdicts/verdict_unknown_line_guards.facts.json b/tests/fixtures/verdicts/verdict_unknown_line_guards.facts.json index d0412497..ad964239 100644 --- a/tests/fixtures/verdicts/verdict_unknown_line_guards.facts.json +++ b/tests/fixtures/verdicts/verdict_unknown_line_guards.facts.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "UnknownLineGuards", "_doc": [ "BR-V5's line guards, one per slice builder, each on a record that IS a", diff --git a/tests/goldens/README.md b/tests/goldens/README.md index e68c4045..d17ac0dd 100644 --- a/tests/goldens/README.md +++ b/tests/goldens/README.md @@ -44,6 +44,15 @@ the message "must stay 0", meaning "the flag does not move the version" but checking a literal. It now checks what it meant: the flag-on facts carry the core's current `OWNIR_VERSION`, and the same one as the flag-off facts. +**Amended a third time, by OwnIR v2.** The flow vocabulary gained the +must-understand `proven_call` (H1, `docs/notes/h1-proven-call.md`), and +`OWNIR_VERSION` moved 1 → 2. One line of this file changed — `"ownir_version": 1` +became `"ownir_version": 2` — and nothing else: no record, no key, no order. The +sample has no protocol region, so the extractor writes no `proven_call` and no +`heap_effects` section for it; the new section is exercised by +`tests/fixtures/fix_candidates/AdditiveSections.cs` instead, whose checker reads the +section list off the extractor's envelope. + ### Regenerating (only when an unrelated extractor change intentionally alters this sample's facts) ```bash diff --git a/tests/goldens/fix_candidates_off.golden.json b/tests/goldens/fix_candidates_off.golden.json index c60de9bc..7b2e64de 100644 --- a/tests/goldens/fix_candidates_off.golden.json +++ b/tests/goldens/fix_candidates_off.golden.json @@ -1,5 +1,5 @@ { - "ownir_version": 1, + "ownir_version": 2, "module": "Extracted", "components": [ { diff --git a/tests/test_effects.py b/tests/test_effects.py index 885072d4..5fc02bbb 100644 --- a/tests/test_effects.py +++ b/tests/test_effects.py @@ -99,7 +99,7 @@ def check(cond: bool, msg: str) -> None: # ---- the OwnIR bridge ---- facts = { - "ownir_version": 1, "module": "D", "components": [], + "ownir_version": 2, "module": "D", "components": [], "effects": [ {"component": "Dashboard", "file": "Dashboard.tsx", "line": 33, "io": True, "deps": ["filters"], @@ -123,11 +123,11 @@ def check(cond: bool, msg: str) -> None: check("EFF001" in rules and "storm" in rules["EFF001"], "EFF001 must appear in the SARIF rules") # malformed effects degrade gracefully (additive/optional, never a crash). - check(check_facts({"ownir_version": 1, "components": [], "effects": "nope"}) == [], + check(check_facts({"ownir_version": 2, "components": [], "effects": "nope"}) == [], "a malformed effects block must not crash check_facts") # a per-entry malformed effect is SKIPPED, not coerced: `deps: "a"` must NOT # become `("a",)` and emit a spurious EFF001 on the direct check_facts() path. - coerce = check_facts({"ownir_version": 1, "components": [], "effects": [ + coerce = check_facts({"ownir_version": 2, "components": [], "effects": [ {"component": "X", "file": "X.tsx", "line": 1, "io": True, "deps": "a", "bindings": [{"name": "a", "init": "object", "refs": [], "line": 1}]}]}) check(coerce == [], f"a malformed deps='a' entry must be skipped, got {coerce}") diff --git a/tests/test_fix_candidates.py b/tests/test_fix_candidates.py index a724cf29..f4c831e7 100644 --- a/tests/test_fix_candidates.py +++ b/tests/test_fix_candidates.py @@ -63,7 +63,7 @@ def _facts(subs: list[dict], qn: str = "N.C", file: str = "N/C.cs", comp = {"name": qn.rsplit(".", 1)[-1], "qualified_name": qn, "is_partial": is_partial, "is_nested": is_nested, "declaration_count": 1, "is_generated": is_generated, "file": file, "subscriptions": subs} - facts: dict = {"ownir_version": 1, "components": [comp, *(extra or [])]} + facts: dict = {"ownir_version": 2, "components": [comp, *(extra or [])]} if version is not _OMIT: facts["fix_candidates_version"] = version return facts diff --git a/tests/test_heap_effects_fixtures.py b/tests/test_heap_effects_fixtures.py index 0305d0cd..89d2fbc2 100644 --- a/tests/test_heap_effects_fixtures.py +++ b/tests/test_heap_effects_fixtures.py @@ -19,7 +19,8 @@ Beyond the bytes this pins the MEANING of the kill fixtures (a golden alone would happily freeze a wrong answer), the order-independence of the solve, and that H0 is -inert: no module of the checker imports the summary domain. +inert except through one door: only the OwnIR v2 `proven_call` admission (ownir.py) +reads the summary domain, and only through the names it needs. Run: python tests/test_heap_effects_fixtures.py (verify) python tests/test_heap_effects_fixtures.py --write (regenerate) @@ -195,21 +196,44 @@ def _semantics() -> list[str]: return fails +# H1 (OwnIR v2 `proven_call`) is the ONE consumer allowed to read the summary domain, +# and only through these names: the admission in ownir.py. Any other checker module +# reaching into it would be a second, unreviewed way for summaries to move a verdict. +_CONSUMER = "ownir.py" +_CONSUMED = {"HeapEffectsError", "load", "site_verdict", "solve"} + + def _inert() -> list[str]: - """H0 is inert: no checker module imports the summary domain.""" + """The summary domain moves a verdict through exactly one door: ownir.py's + `proven_call` admission, importing exactly `_CONSUMED`. Nothing else imports it.""" fails: list[str] = [] pkg = os.path.join(ROOT, "ownlang") + seen: set[str] = set() for name in sorted(os.listdir(pkg)): if not name.endswith(".py") or name == "heap_effects.py": continue with open(os.path.join(pkg, name), encoding="utf-8") as f: tree = ast.parse(f.read()) for node in ast.walk(tree): - mods = ([a.name for a in node.names] if isinstance(node, ast.Import) - else [node.module or ""] if isinstance(node, ast.ImportFrom) else []) - names = [a.name for a in node.names] if isinstance(node, ast.ImportFrom) else [] - if any(m.endswith("heap_effects") for m in mods) or "heap_effects" in names: - fails.append(f"ownlang/{name} imports heap_effects: H0 must stay inert") + if isinstance(node, ast.Import) and any( + a.name.endswith("heap_effects") for a in node.names): + fails.append(f"ownlang/{name} imports heap_effects as a module") + elif isinstance(node, ast.ImportFrom) and (node.module or "").endswith( + "heap_effects"): + names = {a.name for a in node.names} + if name != _CONSUMER: + fails.append(f"ownlang/{name} imports heap_effects: only the " + f"proven_call admission ({_CONSUMER}) may") + elif not names <= _CONSUMED: + fails.append(f"ownlang/{name} imports {sorted(names - _CONSUMED)} from " + f"heap_effects: the admission reads only {sorted(_CONSUMED)}") + seen |= names + elif isinstance(node, ast.ImportFrom) and node.module is None and any( + a.name == "heap_effects" for a in node.names): + fails.append(f"ownlang/{name} imports heap_effects as a module") + if seen != _CONSUMED: + fails.append(f"the proven_call admission imports {sorted(seen)} from heap_effects, " + f"expected {sorted(_CONSUMED)}") return fails diff --git a/tests/test_obligations.py b/tests/test_obligations.py index 05b50054..98874bc7 100644 --- a/tests/test_obligations.py +++ b/tests/test_obligations.py @@ -355,7 +355,7 @@ def rejects(fn: object, raw: object, why: str) -> None: # exit leak through the bridge: OBL003 anchored at the open site, and the # SARIF rules catalogue knows the code. leak = check_facts({ - "ownir_version": 1, "module": "S", + "ownir_version": 2, "module": "S", "protocols": [{ "name": "Suppress", "opens": {"kind": "assign", "target": "_suppress", "value": True}, @@ -377,7 +377,7 @@ def rejects(fn: object, raw: object, why: str) -> None: # OBL005: a scoped protocol matching no reported method is an advisory. dead = check_facts({ - "ownir_version": 1, "module": "S", + "ownir_version": 2, "module": "S", "protocols": [{ "name": "Ghost", "opens": {"kind": "assign", "target": "x", "value": False}, @@ -391,10 +391,10 @@ def rejects(fn: object, raw: object, why: str) -> None: # malformed blocks degrade gracefully on the direct check_facts path # (load() fail-louds; embedders/tests may skip it). - check(check_facts({"ownir_version": 1, "components": [], + check(check_facts({"ownir_version": 2, "components": [], "protocols": "nope"}) == [], "a malformed protocols block must not crash check_facts") - check(check_facts({"ownir_version": 1, "components": [], + check(check_facts({"ownir_version": 2, "components": [], "protocols": [{"name": "P"}], "protocol_functions": [{"name": "m"}]}) == [], "a malformed protocol entry is skipped on the direct path") @@ -403,7 +403,7 @@ def rejects(fn: object, raw: object, why: str) -> None: # On the direct path the first wins deterministically (the second is # skipped — never a mixed message or a dedup-collapsed pair of findings)... dup = check_facts({ - "ownir_version": 1, "module": "S", + "ownir_version": 2, "module": "S", "protocols": [ {"name": "Dup", "opens": {"kind": "assign", "target": "A", "value": False}, @@ -441,14 +441,14 @@ def load_rejects(doc: dict[str, object], why: str) -> None: finally: os.unlink(tmp) - load_rejects({"ownir_version": 1, "module": "S", + load_rejects({"ownir_version": 2, "module": "S", "protocol_functions": [{"name": "m", "events": [{"ev": "goto", "line": 1}]}]}, "an unknown protocol event") _p = {"name": "Dup", "opens": {"kind": "assign", "target": "A", "value": False}, "closes": {"kind": "assign", "target": "A", "value": True}} - load_rejects({"ownir_version": 1, "module": "S", "protocols": [_p, dict(_p)]}, + load_rejects({"ownir_version": 2, "module": "S", "protocols": [_p, dict(_p)]}, "a duplicate protocol name") # both fixtures pass the real load() gate (shape-valid on disk). diff --git a/tests/test_ownir.py b/tests/test_ownir.py index e3d9c2d0..1c023a88 100644 --- a/tests/test_ownir.py +++ b/tests/test_ownir.py @@ -935,7 +935,7 @@ def _sub(source: str | None) -> list[Finding]: fails.append(f"DI003 message missing consuming-constructor anchor: " f"{cache3.message if cache3 else None!r}") # bridge: DI003 surfaces as a WARNING-severity finding; `disposable` is parsed. - di3facts = {"ownir_version": 1, "module": "X", "components": [], "functions": [], + di3facts = {"ownir_version": 2, "module": "X", "components": [], "functions": [], "services": [ {"name": "Cache", "lifetime": "singleton", "deps": ["Conn"], "file": "S.cs", "line": 7}, @@ -986,7 +986,7 @@ def _sub(source: str | None) -> list[Finding]: if not di2 or "WeakReference" not in di2[0].message: fails.append("DI002 message missing 'WeakReference'") # bridge: DI002 surfaces as a WARNING; `weak_deps` is parsed and kept off DI001. - di2facts = {"ownir_version": 1, "module": "X", "components": [], "functions": [], + di2facts = {"ownir_version": 2, "module": "X", "components": [], "functions": [], "services": [ {"name": "WeakCache", "lifetime": "singleton", "deps": [], "weak_deps": ["Db"], "file": "S.cs", "line": 9}, @@ -1058,7 +1058,7 @@ def _sub(source: str | None) -> list[Finding]: # bridge: DI004 surfaces as a WARNING, anchored at the CALL SITE (R.cs:42) — its real # consumer (Codex) — with the REGISTRATION (S.cs:5) as the Finding.related secondary and # named in the message tail. (registration site S.cs:5 differs from the call site R.cs:42.) - di4facts = {"ownir_version": 1, "module": "X", "components": [], "functions": [], + di4facts = {"ownir_version": 2, "module": "X", "components": [], "functions": [], "services": [ {"name": "Resolver", "lifetime": "singleton", "deps": [], "root_resolves": ["Conn"], "file": "S.cs", "line": 5, @@ -1143,7 +1143,7 @@ def _sub(source: str | None) -> list[Finding]: f"{(trans5.cached_file, trans5.cached_line) if trans5 else None}") # bridge: DI005 surfaces as a WARNING anchored at the STORE site (C.cs:21), with the # REGISTRATION (S.cs:7) as the related secondary and named in the message tail. - di5facts = {"ownir_version": 1, "module": "X", "components": [], "functions": [], + di5facts = {"ownir_version": 2, "module": "X", "components": [], "functions": [], "services": [ {"name": "Cacher", "lifetime": "singleton", "deps": [], "scope_cached": ["Db"], "file": "S.cs", "line": 7, @@ -1243,7 +1243,7 @@ def _sub(source: str | None) -> list[Finding]: fails.append(f"DI001 ReportService transitive flow wrong: {rs.flow if rs else None!r}") checks += 1 # a DI001 whose ctor location is UNKNOWN degrades cleanly — no suffix, no related. - nolocf = check_facts({"ownir_version": 1, "module": "X", "components": [], "functions": [], + nolocf = check_facts({"ownir_version": 2, "module": "X", "components": [], "functions": [], "services": [ {"name": "Cap", "lifetime": "singleton", "deps": ["Sc"], "file": "S.cs", "line": 3}, @@ -1257,7 +1257,7 @@ def _sub(source: str | None) -> list[Finding]: # an INTERFACE registration (AddSingleton): the singleton is 'IBilling' # (no ctor) but the consuming ctor is 'Billing's, so the finding must name the IMPL Billing, # never the interface (Codex). ctor_type carries the impl through the fact. - ifacef = check_facts({"ownir_version": 1, "module": "X", "components": [], "functions": [], + ifacef = check_facts({"ownir_version": 2, "module": "X", "components": [], "functions": [], "services": [ {"name": "IBilling", "lifetime": "singleton", "deps": ["Db"], "file": "Startup.cs", "line": 8, "ctor_file": "Billing.cs", @@ -1497,7 +1497,7 @@ def _sub(source: str | None) -> list[Finding]: # subscribe site -> where the longer-lived source service was registered (its lifetime # is *why* the subscriber escapes). The source hop comes from the services graph. checks += 1 - esc = check_facts({"ownir_version": 1, "module": "M", "functions": [], + esc = check_facts({"ownir_version": 2, "module": "M", "functions": [], "components": [{"name": "Vm", "file": "VM.cs", "subscriptions": [ {"event": "bus.Tick", "handler": "OnTick", "line": 11, "released": False, "resource": "subscription", "source": "injected", "source_type": "IBus"}]}], diff --git a/tests/test_ownir_column.py b/tests/test_ownir_column.py index a9c16d26..4ecbf886 100644 --- a/tests/test_ownir_column.py +++ b/tests/test_ownir_column.py @@ -105,7 +105,7 @@ def _subscription_facts(column: int | None = None) -> dict: "line": 12, "released": False} if column is not None: sub["column"] = column - return {"ownir_version": 1, "module": "WpfApp", + return {"ownir_version": 2, "module": "WpfApp", "components": [{"name": "CustomerViewModel", "file": "CustomerViewModel.cs", "subscriptions": [sub]}]} @@ -120,7 +120,7 @@ def _flow_acquire_facts(column: int | None = None) -> dict: acquire: dict = {"op": "acquire", "var": "tfLeak", "line": 105} if column is not None: acquire["column"] = column - return {"ownir_version": 1, "module": "Extracted", "components": [], + return {"ownir_version": 2, "module": "Extracted", "components": [], "functions": [{"name": "FlowLocalsSample.TryNeverDisposed", "file": "FlowLocalsSample.cs", "body": [acquire, @@ -223,11 +223,11 @@ def run() -> int: # the direct `acquire` would leave whole categories line-only, so each path # is exercised here rather than assumed from the code reading. def _fn(body): - return {"ownir_version": 1, "module": "M", "components": [], + return {"ownir_version": 2, "module": "M", "components": [], "functions": [{"name": "F.G", "file": "F.cs", "body": body}]} # a contract param that became an owned obligation (`_lower_fn_params`) - prm = check_facts({"ownir_version": 1, "module": "M", "components": [], + prm = check_facts({"ownir_version": 2, "module": "M", "components": [], "functions": [{"name": "F.G", "file": "F.cs", "params": [{"name": "owned", "line": 30, "column": 26, "effect": "consume"}], @@ -307,8 +307,8 @@ def _fn(body): "a re-indented construct must carry ITS column, not a remembered one") # ---- 8. THINGS THAT MUST NOT MOVE -------------------------------------- - check(OWNIR_VERSION == 1, - f"OWNIR_VERSION must stay 1 (the move/borrow_mut vocabulary) - an " + check(OWNIR_VERSION == 2, + f"OWNIR_VERSION must stay 2 (the proven_call vocabulary) - an " f"optional field with a safe default is " f"additive (spec/OwnIR.md §2), got {OWNIR_VERSION}") if old and new: diff --git a/tests/test_ownir_defensive_limits.py b/tests/test_ownir_defensive_limits.py index ab92a14f..e476bd46 100644 --- a/tests/test_ownir_defensive_limits.py +++ b/tests/test_ownir_defensive_limits.py @@ -90,7 +90,7 @@ def _body(depth: int, key: str = "then") -> dict[str, Any]: node: dict[str, Any] = {"op": "acquire", "column": 1} for _ in range(depth): node = {"op": "if" if key != "body" else "while", key: [node]} - return {"ownir_version": 1, "functions": [{"body": [node]}]} + return {"ownir_version": 2, "functions": [{"body": [node]}]} def _events(depth: int, key: str = "then") -> dict[str, Any]: @@ -98,7 +98,7 @@ def _events(depth: int, key: str = "then") -> dict[str, Any]: node: dict[str, Any] = {"ev": "return", "line": 1} for _ in range(depth): node = {"ev": "if" if key != "body" else "while", "line": 1, key: [node]} - return {"ownir_version": 1, + return {"ownir_version": 2, "protocol_functions": [{"name": "M", "events": [node]}]} @@ -465,12 +465,12 @@ def _subschemas(node: Any, key: str, out: list[Any]) -> None: # Bounding depth is the kind of change that quietly turns that into a # rejection, so it is asserted rather than assumed. for label, document in ( - ("non-list body", {"ownir_version": 1, "functions": [{"body": 7}]}), + ("non-list body", {"ownir_version": 2, "functions": [{"body": 7}]}), ("body of scalars", - {"ownir_version": 1, "functions": [{"body": [1, "x", None]}]}), - ("absent sections", {"ownir_version": 1}), + {"ownir_version": 2, "functions": [{"body": [1, "x", None]}]}), + ("absent sections", {"ownir_version": 2}), ("null column", - {"ownir_version": 1, + {"ownir_version": 2, "components": [{"subscriptions": [{"column": None}]}]}), ): err = _load(document) @@ -486,18 +486,18 @@ def _subschemas(node: Any, key: str, out: list[Any]) -> None: # must not become `2^31 - 1` and `-1` must not become `1`, because a # clamped anchor points at a REAL line the producer did not mean. def _sub(line: Any) -> dict[str, Any]: - return {"ownir_version": 1, "module": "X", + return {"ownir_version": 2, "module": "X", "components": [{"name": "C", "file": "C.cs", "subscriptions": [ {"event": "e", "handler": "h", "line": line, "source": "static"}]}]} def _acquire(line: Any) -> dict[str, Any]: - return {"ownir_version": 1, "module": "X", "functions": [ + return {"ownir_version": 2, "module": "X", "functions": [ {"name": "F", "file": "F.cs", "body": [{"op": "acquire", "var": "x", "line": line}]}]} def _event(line: Any) -> dict[str, Any]: - return {"ownir_version": 1, "module": "X", + return {"ownir_version": 2, "module": "X", "protocols": [{"name": "P", "opens": {"kind": "assign", "target": "f", "value": True}, @@ -549,7 +549,7 @@ def _event(line: Any) -> dict[str, Any]: # only thing that pins the tolerant column bound is right here and the one # synthetic Layer 3 case written for it. def _sub_col(column: Any) -> dict[str, Any]: - return {"ownir_version": 1, "module": "X", + return {"ownir_version": 2, "module": "X", "components": [{"name": "C", "file": "C.cs", "subscriptions": [ {"event": "e", "handler": "h", "line": 7, "column": column, "source": "static"}]}]} diff --git a/tests/test_ownir_input_boundary.py b/tests/test_ownir_input_boundary.py index 0aecba16..e044ed56 100644 --- a/tests/test_ownir_input_boundary.py +++ b/tests/test_ownir_input_boundary.py @@ -140,7 +140,7 @@ def run() -> int: # its offset — rather than in the decoder's voice, which is what lets the # port report it identically. Both halves are asserted, because an offset # that silently became a character index would still "contain 0xff". - invalid_utf8 = b'{"ownir_version": 1, "components": [{"name": "\xff\xfe"}]}' + invalid_utf8 = b'{"ownir_version": 2, "components": [{"name": "\xff\xfe"}]}' assert invalid_utf8.index(b"\xff") == 46 failures += _refusal_case( invalid_utf8, check="invalid-utf8", @@ -151,7 +151,7 @@ def run() -> int: # This is the case an implementation that indexed past the valid prefix # would crash on. failures += _refusal_case( - b'{"ownir_version": 1}\xc3', check="invalid-utf8", + b'{"ownir_version": 2}\xc3', check="invalid-utf8", must_contain="is not valid UTF-8: byte 0xc3 at offset 20") # SCOPE: valid UTF-8 that is invalid JSON must still reach the JSON door, @@ -188,7 +188,7 @@ def run() -> int: # V1 anywhere else in the document is the same refusal: the constants are # refused by the PARSER, so the position cannot matter. failures += _refusal_case( - b'{"ownir_version": 1, "components": [{"line": NaN}]}', + b'{"ownir_version": 2, "components": [{"line": NaN}]}', check="v1-non-standard-constant", must_contain="is not valid JSON: NaN is not a JSON value") @@ -209,7 +209,7 @@ def run() -> int: # SCOPE 2 — a `-0` on any other field is not V2 at all and must not even # be refused: it is an ordinary zero, and the document still analyses. - ok_doc = (b'{"ownir_version": 1, "components": [{"name": "C", ' + ok_doc = (b'{"ownir_version": 2, "components": [{"name": "C", ' b'"file": "a.cs", "line": -0}]}') outcome, _ = _load_bytes(ok_doc) if outcome != "ok": @@ -239,7 +239,7 @@ def run() -> int: big = f"{sign}99999999999999999999999999" outcome, detail = _load_bytes( b'{"ownir_version": ' + big.encode() + b"}") - want = f"OwnIR facts are schema v{big}, but this core understands v1" + want = f"OwnIR facts are schema v{big}, but this core understands v2" if outcome != "refused" or not str(detail).startswith(want): failures += _fail( f"an oversized integral version must keep taking the Version " @@ -253,7 +253,7 @@ def run() -> int: # with ordinary integers is checked to still load and still carry them as # plain values. outcome, doc = _load_bytes( - b'{"ownir_version": 1, "components": [{"name": "C", "file": "a.cs", ' + b'{"ownir_version": 2, "components": [{"name": "C", "file": "a.cs", ' b'"line": 12, "column": 3}]}') if outcome != "ok": failures += _fail(f"an ordinary document must load, got {outcome}: " diff --git a/tests/test_proven_call.py b/tests/test_proven_call.py new file mode 100644 index 00000000..16c4d07c --- /dev/null +++ b/tests/test_proven_call.py @@ -0,0 +1,318 @@ +#!/usr/bin/env python3 +"""OwnIR v2 `proven_call` (H1) — the compatibility controls and the derived refusals. + +H1 lets a call inside a state-protocol region through ONLY when the shared heap-effect +summaries prove it harmless, and it does so through a must-understand op. These controls +hold the "must-understand" and the "only when proven" (docs/notes/h1-proven-call.md): + +* **C1 — old core, new facts.** The REAL v1 core — `ownlang/` exactly as it was at the + H0 landing point, the last commit with `OWNIR_VERSION = 1`, taken out of git history — + is run on v2 facts the extractor wrote for an admitted `proven_call`. It must refuse + (exit 2): on the version stamp, and, with the stamp stripped (an absent version reads + as the core's own), on the unknown op. A v1 core cannot read v2 facts as clean. +* **C2/C3 — missing evidence, malformed op or section.** Documents DERIVED from the real + extractor output for `cases/H1a_harmless_call.cs` (the committed + `typestate_cs_h1a_harmless_call.facts.json`), one targeted corruption each, written to + `tests/fixtures/lowered/proven_call_*.facts.json` by `--write` and held in sync here. + Each is refused; the Layer 2 golden pins the text and the Rust bridge replays it byte + for byte (`own-bridge/tests/replay.rs`), so the two engines refuse identically. +* **C4 — Unknown is poison.** A mutant predicate that reads Unknown as harmless must + ADMIT what the real one refuses (transitive Unknown, an Unknown callee, an Unknown site): + the pinned refusals would go red under it. +* **C5 — the op cannot be dropped.** A core whose admission pass is a no-op admits the + refused kill fixtures; facts whose `proven_call` was dropped read as clean. Both differ + from what the ledgers pin, so neither can happen silently. + +Run: python tests/test_proven_call.py (verify) + python tests/test_proven_call.py --write (regenerate the derived fixtures) +""" + +from __future__ import annotations + +import copy +import io +import json +import os +import subprocess +import sys +import tarfile +import tempfile +from collections.abc import Callable, Iterator +from contextlib import contextmanager +from typing import Any + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) + +from ownlang import heap_effects, ownir +from ownlang.ownir import OwnIRError, check_facts + +ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), "..")) +LOWDIR = os.path.join(ROOT, "tests", "fixtures", "lowered") +BASE = "typestate_cs_h1a_harmless_call" +CALLEE = "Own.Protocols.Cases.H1aHarmlessCall.Twice(int)" +# The H0 landing point: the last commit whose core understands OwnIR v1 (and nothing newer). +V1_CORE = "1c70e867eb408d931ae3dfffd8c0b351190f6547" + + +def _read(name: str) -> dict[str, Any]: + with open(os.path.join(LOWDIR, f"{name}.facts.json"), encoding="utf-8") as f: + doc: dict[str, Any] = json.load(f) + return doc + + +def _region(doc: dict[str, Any]) -> dict[str, Any]: + for fn in doc["functions"]: + for n in fn.get("body", []): + if n.get("op") == "borrow_mut": + return n # type: ignore[no-any-return] + raise KeyError("borrow_mut") + + +def _pc(doc: dict[str, Any]) -> dict[str, Any]: + for n in _region(doc)["body"]: + if n.get("op") == "proven_call": + return n # type: ignore[no-any-return] + raise KeyError("proven_call") + + +def _record(doc: dict[str, Any], key: str) -> dict[str, Any]: + for m in doc["heap_effects"]["methods"]: + if m["key"] == key: + return m # type: ignore[no-any-return] + raise KeyError(key) + + +def _derived() -> dict[str, dict[str, Any]]: + """The refusal fixtures, each one corruption of the real extractor output.""" + base = _read(BASE) + site = _pc(base)["site"] + out: dict[str, dict[str, Any]] = {} + + def make(name: str, edit: Callable[[dict[str, Any]], None]) -> None: + doc = copy.deepcopy(base) + edit(doc) + out[f"proven_call_{name}"] = doc + + def no_section(d: dict[str, Any]) -> None: + del d["heap_effects"] + + def no_site_record(d: dict[str, Any]) -> None: + d["heap_effects"]["methods"] = [m for m in d["heap_effects"]["methods"] + if m["key"] != site] + + def site_not_a_string(d: dict[str, Any]) -> None: + _pc(d)["site"] = 7 + + def empty_callee(d: dict[str, Any]) -> None: + _pc(d)["callee"] = "" + + def outside_region(d: dict[str, Any]) -> None: + call = _pc(d) + _region(d)["body"].remove(call) + body = d["functions"][0]["body"] + body.insert(body.index(_region(d)), call) + + def bad_section(d: dict[str, Any]) -> None: + d["heap_effects"]["heap_effects_version"] = 9 + + def wrong_callee(d: dict[str, Any]) -> None: + _pc(d)["callee"] = "Own.Protocols.Cases.H1aHarmlessCall.Thrice(int)" + + def missing_callee_record(d: dict[str, Any]) -> None: + d["heap_effects"]["methods"] = [m for m in d["heap_effects"]["methods"] + if m["key"] != CALLEE] + + def unknown_callee(d: dict[str, Any]) -> None: + _record(d, CALLEE)["unknown"] = ["dynamic"] + + def unknown_site(d: dict[str, Any]) -> None: + _record(d, site)["unknown"] = ["expression Await"] + + def virtual_in_site(d: dict[str, Any]) -> None: + calls = _record(d, site)["calls"] + calls.append({"id": len(calls), "callee": "Own.Protocols.Cases.IClock.Ticks()", + "dispatch": "virtual", "receiver": ["heap"], "args": [], "line": 18}) + + for name, edit in [("no_section", no_section), ("no_site_record", no_site_record), + ("site_not_a_string", site_not_a_string), + ("empty_callee", empty_callee), ("outside_region", outside_region), + ("bad_section", bad_section), ("wrong_callee", wrong_callee), + ("missing_callee_record", missing_callee_record), + ("unknown_callee", unknown_callee), ("unknown_site", unknown_site), + ("virtual_in_site", virtual_in_site)]: + make(name, edit) + return out + + +def _verdict(facts: dict[str, Any]) -> list[str] | str: + try: + return sorted({f.code for f in check_facts(facts)}) + except OwnIRError as e: + return f"refused: {e}" + + +# --- C2 / C3 ------------------------------------------------------------------ + + +EXPECT_REFUSAL = { + "proven_call_no_section": "needs the 'heap_effects' section", + "proven_call_no_site_record": "has no record in 'heap_effects'", + "proven_call_site_not_a_string": "needs a non-empty string 'site'", + "proven_call_empty_callee": "needs a non-empty string 'site' and a non-empty string 'callee'", + "proven_call_outside_region": "outside a borrow_mut region", + "proven_call_bad_section": "section is malformed — heap-effect facts: heap_effects_version", + "proven_call_wrong_callee": "the site does not call", + "proven_call_missing_callee_record": f"'{CALLEE}' has no summary", + "proven_call_unknown_callee": f"'{CALLEE}': writes.instance is unknown", + "proven_call_unknown_site": "the call site: writes.instance is unknown", + "proven_call_virtual_in_site": "'Own.Protocols.Cases.IClock.Ticks()' is virtual", +} + + +def _derived_controls(write: bool) -> list[str]: + fails: list[str] = [] + derived = _derived() + if set(derived) != set(EXPECT_REFUSAL): + fails.append("the derived fixtures and their expectations name different cases") + with open(os.path.join(LOWDIR, "manifest.json"), encoding="utf-8") as f: + ledger = {c["name"] for c in json.load(f)["cases"]} + for name, doc in sorted(derived.items()): + path = os.path.join(LOWDIR, f"{name}.facts.json") + text = json.dumps(doc, indent=2, ensure_ascii=False) + "\n" + if write: + with open(path, "w", encoding="utf-8", newline="\n") as f: + f.write(text) + elif not os.path.exists(path): + fails.append(f"{name}: derived fixture missing; run with --write") + else: + with open(path, encoding="utf-8") as f: + if json.load(f) != doc: + fails.append(f"{name}: derived fixture is stale; run with --write") + if name not in ledger: + fails.append(f"{name}: not in tests/fixtures/lowered/manifest.json") + got = _verdict(doc) + if not (isinstance(got, str) and EXPECT_REFUSAL.get(name, "\0") in got): + fails.append(f"{name}: expected a refusal naming {EXPECT_REFUSAL.get(name)!r}, " + f"got {got!r}") + if _verdict(_read(BASE)) != []: + fails.append(f"{BASE}: the uncorrupted document must be admitted and clean") + return fails + + +# --- C1 ----------------------------------------------------------------------- + + +def _v1_core(tmp: str) -> str | None: + """Materialize `ownlang/` as it was at V1_CORE; None when history lacks it.""" + archive = subprocess.run(["git", "archive", "--format=tar", V1_CORE, "ownlang"], + cwd=ROOT, capture_output=True, check=False) + if archive.returncode != 0: + return None + with tarfile.open(fileobj=io.BytesIO(archive.stdout)) as tar: + if hasattr(tarfile, "data_filter"): # 3.11.4+; the archive is our own history + tar.extractall(tmp, filter="data") + else: + tar.extractall(tmp) + return tmp + + +def _old_core_controls() -> list[str]: + fails: list[str] = [] + with tempfile.TemporaryDirectory() as tmp: + core = _v1_core(tmp) + if core is None: + return [f"C1: commit {V1_CORE[:12]} (the last v1 core) is not in this clone's " + f"history; the old-core control needs it (CI checks out fetch-depth 0)"] + with open(os.path.join(core, "ownlang", "ownir.py"), encoding="utf-8") as f: + if "\nOWNIR_VERSION = 1\n" not in f.read(): + fails.append(f"C1: {V1_CORE[:12]} is not a v1 core") + stamped = _read(BASE) + unstamped = {k: v for k, v in stamped.items() if k != "ownir_version"} + for label, doc, want in [ + ("stamped v2", stamped, "OwnIR facts are schema v2, but this core understands v1"), + ("stamp removed", unstamped, "unknown OwnIR flow op 'proven_call'")]: + path = os.path.join(tmp, "facts.json") + with open(path, "w", encoding="utf-8") as f: + json.dump(doc, f) + run = subprocess.run([sys.executable, "-m", "ownlang", "ownir", path], + cwd=core, capture_output=True, text=True, check=False) + if run.returncode != 2 or want not in run.stderr: + fails.append(f"C1 ({label}): the v1 core must refuse with {want!r}, got exit " + f"{run.returncode}: {run.stderr.strip()[-300:]!r}") + return fails + + +# --- C4 / C5 ------------------------------------------------------------------ + + +@contextmanager +def _patched(module: Any, name: str, value: Any) -> Iterator[None]: + saved = getattr(module, name) + setattr(module, name, value) + try: + yield + finally: + setattr(module, name, saved) + + +def _unknown_is_harmless(s: heap_effects.Summary) -> str | None: + """The C4 mutant: Unknown read as harmless (the one thing H1 must never do).""" + def lift(level: int, unknown: int, to: int) -> int: + return to if level == unknown else level + return _REAL_HARMLESS(heap_effects.Summary( + tuple(lift(p, heap_effects.UNKNOWN, heap_effects.PLAIN) for p in s.params), + None if s.receiver is None else lift(s.receiver, heap_effects.UNKNOWN, + heap_effects.PLAIN), + (lift(s.writes[0], heap_effects.W_UNKNOWN, heap_effects.W_NONE), + lift(s.writes[1], heap_effects.W_UNKNOWN, heap_effects.W_NONE), + lift(s.writes[2], heap_effects.W_UNKNOWN, heap_effects.W_NONE)), + tuple(r for r in s.returns if r != "unknown"))) + + +_REAL_HARMLESS = heap_effects.harmless + + +def _mutant_controls() -> list[str]: + fails: list[str] = [] + derived = _derived() + poisoned = {"typestate_cs_h1g_transitive_unknown": _read("typestate_cs_h1g_transitive_unknown"), + "proven_call_unknown_callee": derived["proven_call_unknown_callee"], + "proven_call_unknown_site": derived["proven_call_unknown_site"]} + for name, doc in poisoned.items(): + if not isinstance(_verdict(doc), str): + fails.append(f"C4: {name} must be refused by the real predicate") + with _patched(heap_effects, "harmless", _unknown_is_harmless): + if isinstance(_verdict(doc), str): + fails.append(f"C4: {name} is still refused when Unknown reads as harmless, so " + f"it does not pin Unknown-is-poison") + refused = ["typestate_cs_h1d_global_state", "typestate_cs_h1e_transitive_global", + "typestate_cs_h1f_polluted_scc", "typestate_cs_h1j_mutates_outer_value"] + for name in refused: + doc = _read(name) + with _patched(ownir, "_admit_proven_calls", lambda facts: None): + if _verdict(doc) != []: + fails.append(f"C5: {name} must read as clean when the admission is dropped " + f"(so that the pinned refusal catches the drop)") + dropped = copy.deepcopy(doc) + _region(dropped)["body"] = [n for n in _region(dropped)["body"] + if n.get("op") != "proven_call"] + if _verdict(dropped) != [] or not isinstance(_verdict(doc), str): + fails.append(f"C5: {name}: dropping its proven_call must turn a refusal into " + f"clean, which the committed facts and verdict ledgers then catch") + return fails + + +def run(write: bool = False) -> int: + fails = _derived_controls(write) + fails += _old_core_controls() + fails += _mutant_controls() + for f in fails: + print(f"FAIL proven_call: {f}") + print(f"proven_call (OwnIR v2, H1): {len(EXPECT_REFUSAL)} derived refusals, the v1 core " + f"on v2 facts, Unknown-is-poison and dropped-admission mutants — " + f"{'FAIL' if fails else 'PASS'}") + return 1 if fails else 0 + + +if __name__ == "__main__": + raise SystemExit(run(write="--write" in sys.argv[1:])) diff --git a/tests/test_repro_fixtures.py b/tests/test_repro_fixtures.py index 04859c8e..170d0b1f 100644 --- a/tests/test_repro_fixtures.py +++ b/tests/test_repro_fixtures.py @@ -486,7 +486,7 @@ def raw_of_another_document(a: dict[str, Any]) -> None: # The link that makes `input.document` an observation: bytes that are # perfectly self-consistent (their own digest and length hold) and parse # to a DIFFERENT document than the artifact claims. - other = b'{"ownir_version": 1, "module": "SomethingElse"}' + other = b'{"ownir_version": 2, "module": "SomethingElse"}' a["input"]["raw"] = encode_raw(other) def drop_consumed(a: dict[str, Any]) -> None: diff --git a/tests/test_stage3_cancellation.py b/tests/test_stage3_cancellation.py index 85640c76..a6427acf 100644 --- a/tests/test_stage3_cancellation.py +++ b/tests/test_stage3_cancellation.py @@ -101,7 +101,7 @@ def _write_workload(path: str, components: int) -> None: """A large but entirely ORDINARY document. Nothing hostile: the point is a run long enough to interrupt, not a parser stress case.""" with open(path, "w", encoding="utf-8") as f: - f.write('{"ownir_version": 1, "components": [') + f.write('{"ownir_version": 2, "components": [') for i in range(components): if i: f.write(",") diff --git a/tests/test_verify_delta.py b/tests/test_verify_delta.py index 27f1aea9..62f82d02 100644 --- a/tests/test_verify_delta.py +++ b/tests/test_verify_delta.py @@ -159,7 +159,7 @@ def _cfacts(subs: list) -> dict: comp = {"name": _CTYPE.rsplit(".", 1)[-1], "qualified_name": _CTYPE, "is_partial": False, "is_nested": False, "declaration_count": 1, "is_generated": False, "file": _CREL, "subscriptions": subs} - return {"ownir_version": 1, "fix_candidates_version": 1, "components": [comp]} + return {"ownir_version": 2, "fix_candidates_version": 1, "components": [comp]} def _mk_root(work: str) -> str: