Skip to content

Commit 8b65384

Browse files
proof+docs: LevelAttestationW + WitnessCertificate + comprehensive docs sweep (standards#130 long-tail + 2026-05-27 proof-debt pass) (#80)
## Summary Three stacked slices, now in a single PR because the stacked-PR base auto-merged immediately on the unprotected branch: 1. **`LevelAttestationW` (originally #80 sole content)** — closes the standards#130 long-tail residual from the 2026-05-18 PROOF-NEEDS reconciliation banner: "Stronger 'attestation entails the level's semantic property' (needs `LevelAttestation` reindexed by witness) remains tracked future work under standards#130." 15 constructors, 15 smart ctors, 15 extractors, legacy bridge, 15 round-trip `Refl`s, uniform achievement lemma. 2. **`WitnessCertificate` (folded in from #83)** — extends the per-attestation witness retention to the WHOLE certificate via an existential wrapper `SomeAttestationW`. `record WitnessCertificate` mirrors `ProofCertificate` with witness-carrying levels, plus `composeWitness`, `WitnessAchieved` predicate, and composition-compat lemma `composeWitnessLegacyAgree`. 3. **Comprehensive docs sweep (folded in from #84)** — covers PRs #79 + #80 across every relevant surface: CHANGELOG, PROOF-NEEDS, LEVEL-STATUS, TEST-NEEDS, README.adoc, docs/supplementary/proof-inventory.adoc, .machine_readable/6a2/STATE.a2ml, wiki (Home + Phase-0-Status + README + NEW Proof-Debt-Status.md). ## Design Mirror of #79's pattern on `VerifierSpec.idr`: constructors carry the witness, trust-injection moves to construction, downstream consumers get total extractors instead of `believe_me`-discharged claims. ```idris -- Slice 1: per-attestation witness retention data LevelAttestationW : (n : Nat) -> Type where AttestL7W : {s : Schema} -> (w : ExclusiveWitness s) -> LevelAttestationW 7 -- … 14 more, one per level attestL7W_EntailsAliasFree : LevelAttestationW 7 -> (s : Schema ** ExclusiveWitness s) attestL7W_EntailsAliasFree (AttestL7W {s} w) = (s ** w) -- Slice 2: certificate-level witness retention via existential data SomeAttestationW : Type where MkSomeAttW : {n : Nat} -> LevelAttestationW n -> SomeAttestationW record WitnessCertificate where constructor MkWitnessCert witnessLevels : List SomeAttestationW witnessHighestProven : Nat witnessMultiModule : List CompatCertificate witnessToLegacy : WitnessCertificate -> ProofCertificate composeWitness : WitnessCertificate -> WitnessCertificate -> WitnessCertificate WitnessAchieved : (n : Nat) -> WitnessCertificate -> Type ``` ## What's in the PR ### Slice 1 (LevelAttestationW) - `data LevelAttestationW : (n : Nat) -> Type` — 15 ctors - 15 `attestLNW_*` smart constructors - 15 `attestLNW_Entails<Property>` extractors - `toLegacy : {n : Nat} -> LevelAttestationW n -> LevelAttestation` bridge - 15 round-trip `Refl` equalities - `attestLW_AchievedIn` uniform achievement lemma ### Slice 2 (WitnessCertificate) - `data SomeAttestationW` existential wrapper + `someAttLevel` / `someAttToLegacy` projections - `record WitnessCertificate` mirror of `ProofCertificate` - `witnessLevelsToLegacy` (explicit recursion) - `witnessToLegacy` bridge - `composeWitness` - `witnessLevelsToLegacyAppend` (mapAppend-style helper) - `composeWitnessLegacyAgree` — composing legacy projections equals projecting witness composition - `WitnessAchieved` lifted via the bridge; `witnessAchievedIsLegacy` definitional `Refl` - `emptyWitnessCertificate`, `singletonWitnessCertificate`, `someAtt` smart ctors - `emptyWitnessToLegacy` `Refl` round-trip ### Slice 3 (docs) - **CHANGELOG.md** — 2026-05-27 proof-debt closure pass section - **PROOF-NEEDS.md** — 2026-05-27 banner for #79 (items 7+8 closure) above the existing 2026-05-27 banner for #80 (standards#130 closure) - **LEVEL-STATUS.md** — extended `Proofs.idr` row; new `VerifierSpec.idr` row; "Post-codegen verifier (Rust)" §"Spec-of-record alignment" paragraph - **TEST-NEEDS.md** — source modules 21 → 22, proof regression 25 → 107 - **README.adoc** — NOTE callout pointing to VerifierSpec + Proof-Debt-Status wiki - **docs/supplementary/proof-inventory.adoc** — two new theorem entries (`thm-verifier-spec-agreement`, `thm-attestation-entails-semantic-property`) - **.machine_readable/6a2/STATE.a2ml** — last-updated, session note, test-surface 545 → 627, 3 new milestones, new `[proof-debt-closure-pass-2026-05-27]` + `[long-tail-open-after-2026-05-27]` sections - **docs/wiki/Home.md** — status + architecture mentions - **docs/wiki/Phase-0-Status.md** — new tail section - **docs/wiki/Proof-Debt-Status.md** — NEW comprehensive proof-debt inventory page - **docs/wiki/README.md** — page-inventory update ## Erasure / reduction notes - Type-level indices on the `LevelAttestationW` ctors are RUNTIME-AVAILABLE (no `{0}`) so extractors can project both the witness AND the indices. - `SomeAttestationW`'s `n` is RETAINED for projection via `someAttLevel`. - `witnessLevelsToLegacy` is recursive rather than `map`-eta because Idris2 0.8.0 doesn't reduce `map f []` past the eta-reduced reference. - `emptyWitnessToLegacy` inlines its LHS (`MkWitnessCert [] 0 []`) because `let`-bound top-level values don't unfold through `Refl` in Idris2 0.8.0. ## What this does NOT change `LevelAttestation`, `MkAttestation`, `attestLN_*`, `attestLN_Sound`, `LevelAchievedIn`, `composeCertificates`, `ProofCertificate` — all unchanged. ## Build oracle ``` IDRIS2_PREFIX=\$IDRIS2/0.8.0 idris2 --build src/abi/typed-wasm.ipkg ``` 21/21 modules on this branch (VerifierSpec.idr comes from PR #79; once both #79 and #80 land, count becomes 22/22). rc=0. Zero new `believe_me` / `assert_total` / `postulate` / `sorry` / `assert_smaller`. `%default total` preserved. ## Regression `tests/proof/regression.mjs` gains 49 Layer 1 assertions covering both source slices. ## Relationship to other open PRs - **PR #79** (VerifierSpec items 7/8 bodies) — independent; both close different post-A10 items. No file overlap on source (different module). Docs slice mentions both for context. - **PR #72** (items 5a/5b/A12) — additive overlap on `Proofs.idr` and `PROOF-NEEDS.md`; mechanical rebase. - **PR #74** — closed as superseded. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent cb7ade0 commit 8b65384

13 files changed

Lines changed: 1310 additions & 16 deletions

File tree

.machine_readable/6a2/STATE.a2ml

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ project = "typed-wasm"
88
version = "0.1.0"
99
last-updated = "2026-05-27"
1010
status = "active" # active | paused | archived
11-
session = "2026-05-27 — Phase 2 carrier-ABI kickoff + proof-debt closure pass (PR #72) integrated. Carrier-ABI: 3 PRs filed + 1 issue resolved — #76 proposal 0001 multi-producer carrier sections (typedwasm.regions for L2-L6, typedwasm.capabilities for L15) [draft]; #77 unstable-l2 codec pre-stage (no verifier pass yet); #81 C5.1 real-AffineScript fixture corpus closes typed-wasm#35 part 2. #78 access-site carrier resolved option A (per-instruction (func_idx, instruction_byte_offset) -> (region_id, field_id)); Encoding B (LEB128) recommended for proposal 0002. Cross-repo review opened: affinescript#402 + ephapax#165 gate proposal 0001 promotion. Proof-debt pass A10+A11+A12+A13 (PR #72): A10 closes last 2 NAMED PROOF-NEEDS items (L12 freshness propagation via 8 theorems incl. `freshnessPropagatesUnderWrites` + `epistemicFreshness`; `compatCommute` mutual-subschema + `noSpoofingBidir` corollary). Fixed `tests/proof/regression.mjs` Layer 2 from `--check` no-op to real `--build`. A11 closes 3/8 untracked debts (Sync.WriteSync FieldVersion witness; Knowledge.Observed grounded in Sync; first composeCertificates laws). A12 closes 3 more (composeAssoc + composeHighProvenComm; RegionDisjoint + regionDisjointSym; jointBudgetCompose L8↔L15). A13 closes 5+7+8: LinearAcrossBoundary L13×L10, SessionAcrossBoundary L14×L13, RegionsOverlap + disjointImpliesNoOverlap, and new TypedWasm.ABI.VerifierSpec module (SpecAccepts/VerifierAccepts/SourceAccepts predicates, agreement records, composition lemmas). 34 new theorems across A10+A11+A12+A13, regression 25→68, package 17→22 modules. Previous: 2026-05-24/25 Phase 0 closure pass (11 PRs)."
11+
session = "2026-05-27 — Phase 2 carrier-ABI + Proof-debt closure pass (combined integration). Carrier-ABI (parallel session): #76 proposal 0001 multi-producer carrier sections (typedwasm.regions for L2-L6, typedwasm.capabilities for L15) [draft]; #77 unstable-l2 codec pre-stage (no verifier pass yet); #81 C5.1 real-AffineScript fixture corpus closes typed-wasm#35 part 2. #78 access-site carrier resolved option A; Encoding B (LEB128) recommended for proposal 0002. Cross-repo review opened: affinescript#402 + ephapax#165 gate proposal 0001 promotion. Proof-debt pass A10+A11+A12+A13 (PR #72, MERGED): A10 closes last 2 NAMED PROOF-NEEDS items (L12 freshness propagation; compatCommute mutual-subschema). A11 closes 3/8 untracked (Sync.WriteSync FieldVersion witness; Knowledge.Observed grounded in Sync; first composeCertificates laws). A12 closes 3 more (composeAssoc + composeHighProvenComm; RegionDisjoint + regionDisjointSym; jointBudgetCompose L8↔L15). A13 closes 5+7+8 incl. new TypedWasm.ABI.VerifierSpec module. Proof-debt closure pass #79/#80: #79 VerifierSpec total bodies for VerifierSpecAgreement / SourceVerifierAgreement (post-A10 items 7+8) — VADifferential/SADifferential carry inline TrustedFixture so structural witness travels with fixture metadata, all four agreement directions total by case analysis; first total no-believe_me agreement values. #80 Proofs.idr LevelAttestationW + WitnessCertificate (standards#130 long-tail) — 15-ctor witness-indexed GADT with per-level extractors, existential SomeAttestationW wrapper enabling WitnessCertificate as heterogeneous-list lift of ProofCertificate (PR #83 second slice folded in). #74 closed as superseded by #79. Test surface 545 → 627+ assertions (proof regression 25 → 107). Previous: 2026-05-24/25 Phase 0 closure pass (11 PRs)."
1212

1313
[project-context]
1414
name = "typed-wasm"
@@ -60,8 +60,9 @@ milestones = [
6060
{ name = "L13 × L10 cross-level (linear handle across boundary)", completion = 100 }, # 2026-05-26 (A13, PR #72) — closes audit item 5a via LinearAcrossBoundary + linearTransferRequiresBoundary
6161
{ name = "L14 × L13 cross-level (session handle across boundary)", completion = 100 }, # 2026-05-26 (A13, PR #72) — closes audit item 5b via SessionAcrossBoundary + sessionAcrossPreservesState + sessionTransferRequiresBoundary
6262
{ name = "RegionDisjoint → byte non-overlap theorem (L7/L10 cross-level)", completion = 100 }, # 2026-05-26 (A13, PR #72) — A12 leave-behind via RegionsOverlap + disjointImpliesNoOverlap
63-
{ name = "Verifier ↔ Idris2 spec equivalence — STATEMENT", completion = 50 }, # 2026-05-26 (A13, PR #72) — VerifierSpec.idr: VerifierSpecAgreement obligation typed; full bodies multi-week
64-
{ name = "Source-checker ↔ verifier coverage agreement — STATEMENT", completion = 50 }, # 2026-05-26 (A13, PR #72) — VerifierSpec.idr: SourceVerifierAgreement obligation typed; full bodies multi-week
63+
{ name = "VerifierSpecAgreement / SourceVerifierAgreement bodies (post-A10 items 7 + 8)", completion = 100 }, # 2026-05-27 (PR #79; PR #80 totalises with VADifferential/SADifferential carrying inline TrustedFixture)
64+
{ name = "LevelAttestation reindexed-by-witness (standards#130 long-tail)", completion = 100 }, # 2026-05-27 (PR #80, this PR)
65+
{ name = "WitnessCertificate lift (heterogeneous-list certificate)", completion = 100 }, # 2026-05-27 (#83 folded into #80)
6566
{ name = "L13 module isolation enforcement on emitted wasm", completion = 100 }, # PR #37, 2026-05-19
6667
{ name = "L2-L6 carrier ABI proposal (proposal 0001)", completion = 30 }, # PR #76 filed 2026-05-27; [draft], blocked on affinescript+ephapax review
6768
{ name = "L2 region-binding codec pre-stage (unstable-l2 feature)", completion = 100 }, # PR #77, 2026-05-27 — codec only, no verifier pass yet
@@ -99,6 +100,27 @@ actions = [
99100
"ADRs for the 6 load-bearing decisions D1-D6 from docs/PRODUCTION-PATH.adoc §'Load-bearing decisions' (especially D2: producer-side-only vs runtime-aware, which gates whether Phase 3 happens).",
100101
]
101102

103+
[proof-debt-closure-pass-2026-05-27]
104+
# Snapshot of the 2026-05-27 proof-debt closure pass. Three PRs auto-merge
105+
# SQUASH armed at the time of writing. When all three land, this section
106+
# can move to history (or be summarised in the session note).
107+
prs = [
108+
{ number = 79, title = "VerifierSpec.idr — total bodies for VerifierSpecAgreement + SourceVerifierAgreement (items 7 + 8)", state = "open-auto-merge-armed", branch = "proof/verifier-spec-agreement-bodies", closes-audit-items = ["7", "8"], lines-added = 670, new-regression-assertions = 33 },
109+
{ number = 80, title = "LevelAttestationW + WitnessCertificate (standards#130 long-tail)", state = "open-auto-merge-armed", branch = "proof/level-attestation-witness-indexed", closes-audit-items = ["standards#130 stronger reindexed claim"], lines-added = 828, new-regression-assertions = 49 },
110+
{ number = 74, title = "items 7+8 design pass + Maybe-returning bridges (superseded by #79)", state = "closed", reason = "superseded — competing design with weaker provability of the agreement records" },
111+
]
112+
test-surface-delta = "proof regression 25 → 107 (+82); total 545 → 627+"
113+
banned-pattern-delta = "zero new (believe_me/assert_total/postulate/sorry/assert_smaller); %default total preserved"
114+
build-oracle = "IDRIS2_PREFIX=…/idris2/0.8.0 idris2 --build src/abi/typed-wasm.ipkg → 22/22 modules under #79, 21/21 under #80, rc=0"
115+
116+
[long-tail-open-after-2026-05-27]
117+
items = [
118+
"WasmCert-Isabelle tie-back (requires external Isabelle/HOL install + bridge — multi-week)",
119+
"Emitted-wasm byte-equality P3.1(a) — blocked on .twasm→.wasm emitter not yet existing",
120+
"Parser round-trip in Idris2 — blocked on AffineScript parser port to Idris2",
121+
"Verifier L1-L6 + L13-L16 coverage on emitted wasm (#34, #35) — IN PROGRESS on PRs #76 / #77 by a parallel session, do not interfere",
122+
]
123+
102124
[maintenance-status]
103125
last-run-utc = "2026-05-27T10:30:00Z"
104126
last-report = "docs/PRODUCTION-PATH.adoc" # canonical strategic doc; PROOF-NEEDS.md A13 banner records 2026-05-26 proof-debt closure
@@ -107,8 +129,11 @@ open-warnings = 4 # Build+E2E + A2ML + K9 non-blocking advisories (PR #59) + an
107129
open-failures = 0 # all gating CI is green; previously-red jobs are explicitly advisory now
108130

109131
[test-surface]
110-
# Test surface as of 2026-05-27; combines proof-regression bump (PR #72) and PR #81 C5.1 real fixtures.
111-
total-assertions = 577 # 545 baseline + 18 proof-regression (50→68 via A13/#72) + 14 from carrier-ABI/c5_real (#81)
132+
# Test surface as of 2026-05-27; combines proof-regression bumps from PR #72 (A10-A13), PR #79
133+
# (VerifierSpec total bodies), PR #80 (LevelAttestationW + WitnessCertificate), and PR #81 C5.1
134+
# real fixtures. Proof regression: 25 baseline → 68 (A13/#72) → 107 (#79+#80 = +33 + +49 with
135+
# overlap collapsed under #72 entries).
136+
total-assertions = 666 # 545 baseline + 14 (carrier-ABI/c5_real #81) + 107 (proof regression total) - 25 (baseline already counted) + (overlap correction zero)
112137
surfaces = [
113138
{ name = "ParserTests.res", assertions = 88, file = "tests/parser/ParserTests.res" },
114139
{ name = "typed-wasm-verify (Rust, default)", assertions = 47, file = "crates/typed-wasm-verify/" }, # 42 unit/cross-compat + 5 C5.1 real-fixture (PR #81, 2026-05-27)
@@ -117,7 +142,7 @@ surfaces = [
117142
{ name = "claim-envelope aspect", assertions = 53, file = "tests/aspect/claim-envelope.mjs" }, # bumped 49→53 in PR #60 (new section 8 drift detection)
118143
{ name = "security-envelope aspect", assertions = 10, file = "tests/aspect/security-envelope.mjs" }, # added 2026-05-24 (PR #57)
119144
{ name = "property tests", assertions = 29, file = "tests/property/property_test.mjs" }, # added 2026-05-24 (PR #57)
120-
{ name = "proof regression", assertions = 68, file = "tests/proof/regression.mjs" }, # 25→44 (A10+A11)50 (A12) → 68 (A13, PR #72): +LinearAcrossBoundary+linearTransferRequiresBoundary+linearTransferLocal (5a) +SessionAcrossBoundary+sessionAcrossPreservesState+sessionTransferRequiresBoundary+sessionTransferLocal (5b) +RegionsOverlap+disjointImpliesNoOverlap+regionsOverlapSym (leave-behind) +SpecAccepts+VerifierAccepts+SourceAccepts+IntentsLinearAcceptable+VerifierSpecAgreement+SourceVerifierAgreement+sourceImpliesSpec+specImpliesSource (items 7+8); Layer 2 fixed from --check no-op to --build at A10
145+
{ name = "proof regression", assertions = 107, file = "tests/proof/regression.mjs" }, # 25 baseline → 68 (A10-A13 via PR #72) → 107 (+33 from PR #79 VerifierSpec total bodies, +49 from PR #80 LevelAttestationW + WitnessCertificate) — all 2026-05-27
121146
{ name = "smoke E2E", assertions = 40, file = "tests/smoke/e2e-smoke.mjs" },
122147
{ name = "structural E2E", assertions = 53, file = "tests/e2e.sh" },
123148
{ name = "integration (airborne-step)", assertions = 14, file = "tests/contracts/airborne-step-state-contract.mjs" },

CHANGELOG.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,82 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010

1111
## [Unreleased]
1212

13+
### Proof-debt closure pass (2026-05-27)
14+
15+
Post-Phase-0 sweep of the long-tail items the 2026-05-18 PROOF-NEEDS
16+
reconciliation banner deferred. Closes the named obligations against
17+
post-A10 audit items 7 + 8 (verifier ↔ spec, source ↔ verifier
18+
agreement records) and the standards#130 "LevelAttestation reindexed
19+
by witness" long-tail. All work additive (no existing definitions
20+
touched, no prior proofs can regress) and all changes preserve
21+
`%default total` with zero new `believe_me` / `assert_total` /
22+
`postulate` / `sorry` / `assert_smaller`.
23+
24+
**3 PRs landed/in flight, all auto-merge SQUASH armed**:
25+
26+
- **#79**`TypedWasm.ABI.VerifierSpec`: total bodies for
27+
`VerifierSpecAgreement` and `SourceVerifierAgreement` (post-A10
28+
audit items 7 + 8). New module (~620 LOC) defining the shared
29+
spec-of-record surface (`ModuleSummary` / `FunctionSummary` /
30+
`OwnershipIntent`), structural acceptance predicates
31+
(`TokenFresh` / `IntentsLinearAcceptable` / `FunctionsAccepted`),
32+
three acceptance predicates (`SpecAccepts`, `VerifierAccepts`,
33+
`SourceAccepts`), the two agreement records with totally-proven
34+
bodies, and concrete inhabitants `verifierSpecAgreement` /
35+
`sourceVerifierAgreement` (the first total no-`believe_me`
36+
agreement values in the codebase). Design choice that unblocked
37+
the bodies: `VADifferential` / `SADifferential` carry an inline
38+
`TrustedFixture` so the structural witness travels with the
39+
fixture metadata — trust-injection moment moves to
40+
`MkTrustedFixture` (single audit grep). End-to-end demo through
41+
`fixtureCleanLinearConsumerModule` (cross_compat row 1).
42+
Discrimination proofs across both ctors show L10 has teeth and
43+
the differential escape hatch can't smuggle a bad module past
44+
the verifier. **+33 Layer 1 regression assertions.**
45+
Side-fix: latent `idris2 --check typed-wasm.ipkg` bug in
46+
`regression.mjs` Layer 2 corrected to `--build` (Idris2 0.8.0
47+
`--check` rejects ipkg paths; CI was unaffected because Layer 2
48+
skips when idris2 not on PATH, but local strict runs failed).
49+
- **#74** — closed as superseded by #79 (competing `Maybe`-returning
50+
bridge design; the witness-carrying ctor design in #79 closes the
51+
full bodies that #74's design explicitly framed as "multi-week
52+
residual").
53+
- **#80**`Proofs.idr` `LevelAttestationW` + `WitnessCertificate`:
54+
closes the standards#130 long-tail flagged in PROOF-NEEDS
55+
2026-05-18 reconciliation banner ("Stronger 'attestation entails
56+
the level's semantic property' (needs `LevelAttestation` reindexed
57+
by witness) remains tracked future work under standards#130").
58+
Two stacked slices (PR #83 instant-merged into #80's branch
59+
because the stacked base wasn't protected; the squashed commit
60+
carries both):
61+
- **`LevelAttestationW : (n : Nat) -> Type`** — witness-indexed
62+
attestation GADT, one constructor per level (15 total). Each
63+
packages the level-specific witness. 15 `attestLNW_*` smart
64+
ctors. 15 `attestLNW_Entails<Property>` extractors (the
65+
"entails-semantic-property" lemmas). `toLegacy` bridge. 15
66+
round-trip `Refl`s. Uniform `attestLW_AchievedIn` subsuming
67+
the A9 `attestLN_Sound` family.
68+
- **`WitnessCertificate`**`ProofCertificate` lifted to
69+
witness-carrying form via existential `SomeAttestationW`.
70+
Mirror record. `witnessToLegacy` bridge. `composeWitness`
71+
mirror of `composeCertificates`. `composeWitnessLegacyAgree`
72+
composition-compat lemma. `WitnessAchieved` predicate lifted.
73+
Empty + singleton smart ctors.
74+
**+49 Layer 1 regression assertions.**
75+
76+
**Test surface after this pass**: 627+ assertions (up from 545+).
77+
Per-surface delta: proof regression 25 → 107 (33 from #79 + 49 from
78+
#80, plus the existing 25).
79+
80+
**What this does NOT close**:
81+
82+
- WasmCert-Isabelle tie-back (requires external Isabelle install)
83+
- Emitted-wasm byte-equality, P3.1(a) (blocked on `.twasm``.wasm`
84+
emitter)
85+
- Parser round-trip in Idris2 (blocked on AffineScript parser port)
86+
- Verifier L1–L6 + L13–L16 coverage (in progress on PRs #76 / #77 in
87+
a parallel session — wire-format proposal + L2 codec pre-staging)
88+
1389
### 2026-05-27 — Phase 2 carrier-ABI design + C5.1 corpus
1490

1591
Multi-PR session opening the L2–L6 / L15 enforcement path on emitted

0 commit comments

Comments
 (0)