@sanning/proof 0.11.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +43 -8
  2. package/dist/agent-proof.d.ts +2 -2
  3. package/dist/agent-proof.js +4 -4
  4. package/dist/case-file.d.ts +126 -0
  5. package/dist/case-file.js +349 -0
  6. package/dist/case.d.ts +199 -43
  7. package/dist/case.js +522 -146
  8. package/dist/cli.d.ts +132 -1
  9. package/dist/cli.js +1140 -96
  10. package/dist/crypto.d.ts +1 -1
  11. package/dist/crypto.js +5 -1
  12. package/dist/declaration.d.ts +58 -52
  13. package/dist/declaration.js +256 -33
  14. package/dist/evidence.d.ts +2 -0
  15. package/dist/evidence.js +134 -19
  16. package/dist/exit-codes.d.ts +17 -0
  17. package/dist/exit-codes.js +50 -0
  18. package/dist/grading.d.ts +28 -13
  19. package/dist/grading.js +90 -31
  20. package/dist/handoff.d.ts +16 -1
  21. package/dist/handoff.js +91 -16
  22. package/dist/index.d.ts +10 -7
  23. package/dist/index.js +15 -7
  24. package/dist/message-parts.d.ts +11 -9
  25. package/dist/message-parts.js +11 -9
  26. package/dist/types.d.ts +1 -0
  27. package/dist/verifier.d.ts +9 -2
  28. package/dist/verifier.js +28 -12
  29. package/dist/zip-reader.d.ts +50 -0
  30. package/dist/zip-reader.js +220 -0
  31. package/package.json +2 -2
  32. package/src/agent-proof.ts +4 -4
  33. package/src/case-file.ts +419 -0
  34. package/src/case.ts +651 -156
  35. package/src/cli.ts +1325 -100
  36. package/src/crypto.ts +5 -1
  37. package/src/declaration.ts +248 -52
  38. package/src/evidence.ts +142 -21
  39. package/src/exit-codes.ts +54 -0
  40. package/src/grading.ts +109 -52
  41. package/src/handoff.ts +108 -17
  42. package/src/index.ts +60 -3
  43. package/src/message-parts.ts +11 -9
  44. package/src/types.ts +5 -0
  45. package/src/verifier.ts +35 -13
  46. package/src/zip-reader.ts +229 -0
  47. package/vectors/README.md +56 -3
  48. package/vectors/case-file-index.json +668 -0
  49. package/vectors/case-split.json +1102 -0
  50. package/vectors/pack-grading.json +68 -4
  51. package/vectors/stamp-on-chain.json +3 -3
package/dist/case.d.ts CHANGED
@@ -166,7 +166,9 @@
166
166
  * gets, since that reads wrapper keys.
167
167
  *
168
168
  * Not exits: a record whose envelope verifies and whose content does not
169
- * match its commitment is `RECORD_CONTENT_MISMATCH`, and one that fails
169
+ * match its commitment is `RECORD_CONTENT_MISMATCH` where that content is
170
+ * inside the signed body and `RECORD_CONTENT_DEPENDENT` where it was handed
171
+ * in beside the pack (proof#159), and one that fails
170
172
  * another check inside its pack is `RECORD_DOES_NOT_VERIFY_IN_ITS_PACK`.
171
173
  * Both are named and both STAY in the pile, so neither unsigned content
172
174
  * handed in beside a pack nor a broken inclusion proof removes a record
@@ -185,7 +187,8 @@
185
187
  * (F2).
186
188
  * 10. **`counterpart_absent`** (`continue`). Skips the ambiguity and pair
187
189
  * reporting, and there is nothing to skip: 4.1 emits that finding only
188
- * for an EMPTY candidate list. Which of the three counterpart kinds it
190
+ * where no candidate is left to read, an EMPTY candidate list or one whose
191
+ * every candidate another record accounts for (4.1 v1.17, A20). Which of the three counterpart kinds it
189
192
  * gets reads the keys of the packs that verified, counted before exit 4,
190
193
  * and whether any pack took exit 2 or 3.
191
194
  *
@@ -206,7 +209,9 @@
206
209
  * verdict, exactly as `counterpart_absent` and `not_a_handoff_record` are
207
210
  * findings beside a verdict in 4.1.
208
211
  *
209
- * A case with more than one outcome is `mixed` (anchor#198, criterion 4).
212
+ * A case with any `failed` contribution is `failed`: a proven failure keeps
213
+ * the headline (5.5.4 v1.16, A17, proof#158). Otherwise a case with more than
214
+ * one outcome is `mixed` (anchor#198, criterion 4).
210
215
  *
211
216
  * WHAT THIS READER DOES NOT CLAIM
212
217
  * ===============================
@@ -225,17 +230,19 @@
225
230
  * with that verdict and its reasons, so the case never reads above its
226
231
  * weakest pack. On-chain re-fetch and `gradePack` are a caller's to run.
227
232
  *
228
- * THE COST OF 4.1's "GRADE EVERY CANDIDATE", INHERITED HERE AND STATED RATHER
229
- * THAN LEFT TO BE FOUND (proof#134, ratified by Phil 2026-09-22). A reader
230
- * whose pile holds two or more records of the complementary type signed by one
231
- * counterparty key cannot reach `verified`: the other exchanges' records are
232
- * candidates too, they commit to other messages, and they fail. One agent
233
- * sending two messages to the same counterparty inside one case lands there,
234
- * and it surfaces as `COUNTERPART_AMBIGUOUS` beside the failure. An
235
- * alternating exchange (A sends, B replies) does NOT, because a reply is
236
- * signed by the other key and is the other type. Narrowing that here with
237
- * `handoffs[]` is precisely the move that would reopen proof#137's door.
238
- */
233
+ * THE COST OF 4.1's "GRADE EVERY CANDIDATE", AND WHAT IS LEFT OF IT (4.1
234
+ * v1.17, amendment A20, which reopens proof#134). Up to v1.16 a pile holding
235
+ * two or more records of the complementary type signed by one counterparty key
236
+ * could not reach `verified`. 4.1 now sets such a candidate aside where a
237
+ * record the subject's own key signed pairs with it verified at another
238
+ * sequence, so two messages in one direction, and the demo's A to B, B to A,
239
+ * A to B, read clean. What is left surfaces as `COUNTERPART_AMBIGUOUS` beside
240
+ * the failure: fan-in, fan-out, and the same pair in two cases at the same
241
+ * sequence. Narrowing any of it here with `handoffs[]` is precisely the move
242
+ * that would reopen proof#137's door.
243
+ */
244
+ import { type DeclarationRole } from "./declaration.js";
245
+ import { type PackGradeCauseKind, type PackVerdict } from "./grading.js";
239
246
  import type { SideContentMap } from "./side-content.js";
240
247
  /**
241
248
  * The verdicts a case can reach. Every one is already in use in
@@ -281,7 +288,9 @@ export declare const CASE_QUARANTINED_PROFILES: readonly ["sanning.mlflow/v1"];
281
288
  /**
282
289
  * A conformant hand-off record with no counterpart among the records this
283
290
  * reader read, where every pack in the case verified under a key this reader
284
- * can read and NO pack in the case is signed by the key the record names.
291
+ * can read and NO pack in the case is signed by the key the record names,
292
+ * or where every candidate it had was accounted for by another record under
293
+ * A20 (the exception then carries `count`, and names no pack).
285
294
  * **An exception, never a failure** (anchor#198, criterion 3).
286
295
  *
287
296
  * That is ALL it says. It does not say the counterparty's account is absent,
@@ -367,9 +376,11 @@ export declare const COUNTERPART_ABSENT_FROM_COUNTERPARTY_RECORDS = "counterpart
367
376
  */
368
377
  export declare const COUNTERPART_ABSENT_SIGNER_UNKNOWN = "counterpart_absent_signer_unknown";
369
378
  /**
370
- * More than one candidate counterpart (4.1, and proof#134's stated cost). The
371
- * reading is the worst of them and the ambiguity is named: a reader permitted
372
- * to take one match can be handed an honest decoy beside a tampered record.
379
+ * More than one candidate counterpart that nothing accounts for (4.1 v1.17,
380
+ * A20). The reading is the worst of them and the ambiguity is named: a reader
381
+ * permitted to take one match can be handed an honest decoy beside a tampered
382
+ * record. `count` is how many of the candidates are live, which is the number
383
+ * the ambiguity is about.
373
384
  */
374
385
  export declare const COUNTERPART_AMBIGUOUS = "counterpart_ambiguous";
375
386
  /**
@@ -545,17 +556,26 @@ export declare const PACK_KEY_UNREADABLE = "pack_key_unreadable";
545
556
  */
546
557
  export declare const PACK_DOES_NOT_VERIFY = "pack_does_not_verify";
547
558
  /**
548
- * The pack's wrapper HOLDS and its own bundle verdict, from
549
- * `verifyEvidenceBundle` run here offline over the pack and the content handed
550
- * in beside it, is not `verified`. The exception carries that verdict
551
- * (`status`) and the verifier's reasons (`reasons`: its bundle errors, then its
552
- * stamp errors, then its checkpoint errors, each as the verifier wrote it), and
553
- * it CONTRIBUTES that verdict, so the case verdict never reads above its
554
- * weakest pack. Gate 3 on proof#140: two unwitnessed (`partial`) packs read as
555
- * a `verified` case with no exception. It does not say who is at fault:
556
- * content handed in beside a pack is not signed by its holder.
557
- */
558
- export declare const PACK_BUNDLE_NOT_VERIFIED = "pack_bundle_not_verified";
559
+ * The pack's wrapper HOLDS and its CASE GRADE is not `verified`
560
+ * (evidence-bundle 5.5.1 step 1 v1.20, A23; it replaces
561
+ * `pack_bundle_not_verified`, which carried the bundle status alone). The case
562
+ * grade is the pack grade of 5.4.5, taken twice: the SIGNED grade over the run
563
+ * with the side map empty, and the FULL grade over the run with it. The signed
564
+ * grade decides where it is `failed` or `malformed`; a failure only the full
565
+ * grade reaches is `incomplete`, because it rests on bytes nobody signed;
566
+ * otherwise the full grade. A body the verifier could not read is `malformed`,
567
+ * a body that is not one of the two event-carrying bodies takes the signed
568
+ * run's status, and a verifier that graded a different number of records than
569
+ * the pack holds takes the signed status, or `malformed` where that status is
570
+ * `verified`.
571
+ *
572
+ * The exception carries `status`, the case grade; `causes`, the 5.4.5 cause
573
+ * kinds of the grade that decided it (none in the first three branches); and
574
+ * `reasons`, the verifier's reasons from the run with the side map empty. It
575
+ * CONTRIBUTES the grade, and `incomplete` for `pending`, `not_found` or
576
+ * `mixed`, so the case verdict never reads above its weakest pack.
577
+ */
578
+ export declare const PACK_GRADE_NOT_VERIFIED = "pack_grade_not_verified";
559
579
  /**
560
580
  * A record in a pack whose wrapper holds, whose OWN envelope does not verify
561
581
  * (`EventResult.envelopeOk` is false). Not read by 4.1, and NAMED with the
@@ -576,12 +596,39 @@ export declare const RECORD_ENVELOPE_DOES_NOT_VERIFY = "record_envelope_does_not
576
596
  export declare const RECORD_DOES_NOT_VERIFY_IN_ITS_PACK = "record_does_not_verify_in_its_pack";
577
597
  /**
578
598
  * A record whose envelope verifies and whose disclosed content does not hash to
579
- * the `content_hash` it commits to (`EventResult.contentOk` is false). `failed`,
580
- * and the record STAYS in the pile: content beside a pack is unsigned and often
599
+ * the hash it commits to, its `content_hash` or a hand-off record's
600
+ * `message_hash` (evidence-bundle v1.19, A20) (`EventResult.contentOk` is false), with the
601
+ * side map EMPTY: the content is inside the signed body. The same mismatch from
602
+ * content handed in beside the pack is `RECORD_CONTENT_DEPENDENT` (proof#159).
603
+ * `failed`, and the record STAYS in the pile: content beside a pack is unsigned and often
581
604
  * supplied by whoever assembled the case, and gate 3 on proof#140 showed that
582
605
  * party erasing an honest verified pair by swapping it.
583
606
  */
584
607
  export declare const RECORD_CONTENT_MISMATCH = "record_content_mismatch";
608
+ /**
609
+ * The two readings proof#147 did not reach, given its shape (proof#159, ruled
610
+ * by Phil 2026-09-22, evidence-bundle.md 5.5.4 v1.16, A17). A pack whose
611
+ * bundle verdict is `failed` ONLY when read with the unsigned content handed
612
+ * in beside it, and `failed` no longer when read with that map empty, is
613
+ * `PACK_BUNDLE_CONTENT_DEPENDENT`; a record whose content mismatch comes from
614
+ * that map alone is `RECORD_CONTENT_DEPENDENT`. Both are `incomplete`: the
615
+ * reader established that the bytes it was handed are not the bytes the record
616
+ * commits to, and nothing about the party that signed the record, because
617
+ * whoever assembled the case chose those bytes with no key. Up to v1.15 both
618
+ * readings carried `failed`, and one flipped nibble of accuser-supplied content
619
+ * put a `failed` against an intact pack; under A17's headline rule that would
620
+ * have become the case's headline.
621
+ *
622
+ * The test that separates the two is the one proof#159 states for the inverse:
623
+ * every deviation a signature covers still reads `failed` with the side map
624
+ * EMPTY. So the pack is verified twice, with the map and without it, and what
625
+ * fails without it is `PACK_GRADE_NOT_VERIFIED`, `RECORD_CONTENT_MISMATCH`
626
+ * (content inside the signed body) or `RECORD_DOES_NOT_VERIFY_IN_ITS_PACK`,
627
+ * each still `failed`. Emptying the map is the most a party that signed
628
+ * nothing can do to starve the check, and it cannot remove any of those.
629
+ */
630
+ export declare const PACK_BUNDLE_CONTENT_DEPENDENT = "pack_bundle_content_dependent";
631
+ export declare const RECORD_CONTENT_DEPENDENT = "record_content_dependent";
585
632
  /**
586
633
  * A record signed under a ratified profile that is under quarantine
587
634
  * (`CASE_QUARANTINED_PROFILES`, pending DL-63). Not read, in any kernel.
@@ -591,16 +638,19 @@ export declare const RECORD_PROFILE_QUARANTINED = "record_profile_quarantined";
591
638
  /** The reader was handed no packs at all. */
592
639
  export declare const CASE_HOLDS_NO_PACKS = "case_holds_no_packs";
593
640
  /**
594
- * Every pack was read and not one hand-off record came out of any of them.
595
- * There is no hand-off to have a verdict about, and saying `verified` over that
596
- * would be the defect class in its purest form.
641
+ * The two NOTEs (5.5.3 v1.20): findings on the reading with no contribution,
642
+ * printed in the scope sentence so a clean verdict never hides either.
643
+ * `pack_undeclared` is a note only where the reading holds no hand-off record;
644
+ * where it holds one, it is the exception of that name.
597
645
  */
598
- export declare const CASE_HOLDS_NO_HANDOFF_RECORDS = "case_holds_no_handoff_records";
646
+ export declare const CONTENT_WITHHELD_BY_DECLARATION = "content_withheld_by_declaration";
647
+ export declare const CASE_NOTE_KINDS: readonly ["pack_undeclared", "content_withheld_by_declaration"];
648
+ export type CaseNoteKind = (typeof CASE_NOTE_KINDS)[number];
599
649
  /**
600
650
  * Every exception this reader can report, as a closed set. A surface may render
601
651
  * them and a test may assert over them; nothing outside this array is emitted.
602
652
  */
603
- export declare const CASE_EXCEPTION_KINDS: readonly ["counterpart_absent", "counterpart_absent_from_counterparty_records", "counterpart_absent_signer_unknown", "counterpart_ambiguous", "counterpart_malformed", "pair_failed", "record_malformed", "record_unclaimed_by_its_pack", "record_bytes_withheld", "record_bytes_unreadable", "pack_declaration_deviates", "pack_declaration_content_dependent", "pack_declaration_unreadable", "pack_undeclared", "pack_body_type_unknown", "pack_holds_no_records", "pack_key_unreadable", "pack_does_not_verify", "pack_bundle_not_verified", "record_envelope_does_not_verify", "record_does_not_verify_in_its_pack", "record_content_mismatch", "record_profile_quarantined", "case_holds_no_packs", "case_holds_no_handoff_records"];
653
+ export declare const CASE_EXCEPTION_KINDS: readonly ["counterpart_absent", "counterpart_absent_from_counterparty_records", "counterpart_absent_signer_unknown", "counterpart_ambiguous", "counterpart_malformed", "pair_failed", "record_malformed", "record_unclaimed_by_its_pack", "record_bytes_withheld", "record_bytes_unreadable", "pack_declaration_deviates", "pack_declaration_content_dependent", "pack_declaration_unreadable", "pack_undeclared", "pack_body_type_unknown", "pack_holds_no_records", "pack_key_unreadable", "pack_does_not_verify", "pack_grade_not_verified", "pack_bundle_content_dependent", "record_envelope_does_not_verify", "record_does_not_verify_in_its_pack", "record_content_mismatch", "record_content_dependent", "record_profile_quarantined", "case_holds_no_packs"];
604
654
  export type CaseExceptionKind = (typeof CASE_EXCEPTION_KINDS)[number];
605
655
  /**
606
656
  * One pack in a case, as a reader was handed it.
@@ -636,13 +686,24 @@ export interface CaseException {
636
686
  counterpartyKey?: string | null;
637
687
  /** Which checks a formed pair failed, in 4.1's fixed order. */
638
688
  failedChecks?: string[];
639
- /** How many of a thing the exception is about, where it is about a count. */
689
+ /**
690
+ * How many of a thing the exception is about, where it is about a count. On
691
+ * `COUNTERPART_ABSENT` it is set only where 4.1 set every candidate aside
692
+ * (v1.17, A20), and it is how many were set aside.
693
+ */
640
694
  count?: number;
641
- /** The pack's own bundle verdict, for `PACK_BUNDLE_NOT_VERIFIED`. */
695
+ /** The pack's case grade, for `PACK_GRADE_NOT_VERIFIED`. */
642
696
  status?: CaseVerdict;
697
+ /**
698
+ * The 5.4.5 cause kinds of the grade that decided the case grade, for
699
+ * `PACK_GRADE_NOT_VERIFIED`, in the grade's order. Empty where the grade was
700
+ * not computed (an unreadable body, a body that is not one of the two
701
+ * event-carrying ones, a verifier that graded too few records).
702
+ */
703
+ causes?: PackGradeCauseKind[];
643
704
  /**
644
705
  * What the bundle verifier said, as it said it, for the kinds that carry a
645
- * verifier's grading: `PACK_BUNDLE_NOT_VERIFIED` and the three record kinds
706
+ * verifier's grading: `PACK_GRADE_NOT_VERIFIED` and the three record kinds
646
707
  * graded on the record's own envelope and content.
647
708
  */
648
709
  reasons?: string[];
@@ -663,6 +724,52 @@ export interface CaseRecordReading {
663
724
  findings: string[];
664
725
  failedChecks: string[];
665
726
  counterparts: string[];
727
+ /**
728
+ * The role the pack's v2 declaration signs for this record, `handoff` or
729
+ * `step`, or `null` where the pack's declaration is absent, unreadable or
730
+ * v1, or does not declare the record (5.5.1 v1.20).
731
+ */
732
+ role: DeclarationRole | null;
733
+ }
734
+ /**
735
+ * One NOTE on the reading (5.5.3 v1.20): something true a reader needs and
736
+ * nothing a reader could not tell, so it carries no contribution.
737
+ */
738
+ export interface CaseNote {
739
+ kind: CaseNoteKind;
740
+ /** Which pack, by the reader's own name for it. */
741
+ packRef: string;
742
+ /**
743
+ * For `CONTENT_WITHHELD_BY_DECLARATION`, how many of the pack's records its
744
+ * declaration withholds.
745
+ */
746
+ count?: number;
747
+ }
748
+ /**
749
+ * One pack as the reading read it, in the order the reader was given them
750
+ * (5.5.4 v1.20). A surface names a pack by `signingKey`, the key that signed
751
+ * its wrapper, and never by an organization (D10).
752
+ */
753
+ export interface CasePackReading {
754
+ ref: string;
755
+ /** The wrapper key, normalized, or `null` where this reader could not read it. */
756
+ signingKey: string | null;
757
+ /**
758
+ * The case grade (5.5.1 step 1), or `null` where the wrapper did not hold or
759
+ * the key could not be read.
760
+ */
761
+ grade: PackVerdict | null;
762
+ /**
763
+ * Records withheld by the pack's declaration (5.4.5): in scope for their
764
+ * signature and commitment only. Never counted as verified records.
765
+ */
766
+ recordsWithheld: number;
767
+ /**
768
+ * `sanning.declaration/v1`, `sanning.declaration/v2`, or `null` where the
769
+ * pack carries no declaration, one this reader does not know, or a body this
770
+ * reader does not read.
771
+ */
772
+ declarationVersion: string | null;
666
773
  }
667
774
  export interface CaseReading {
668
775
  verdict: CaseVerdict;
@@ -705,6 +812,10 @@ export interface CaseReading {
705
812
  * checked packs, which is false.
706
813
  */
707
814
  onChainChecked: boolean;
815
+ /** The NOTEs, in pack order (5.5.3 v1.20). No contribution. */
816
+ notes: CaseNote[];
817
+ /** One reading per pack, in the order the reader was given them. */
818
+ packs: CasePackReading[];
708
819
  }
709
820
  /**
710
821
  * Read a whole case: several packs in, one verdict and its exceptions out.
@@ -735,11 +846,56 @@ export interface CaseReading {
735
846
  */
736
847
  export declare function readCase(packs: readonly CasePack[]): Promise<CaseReading>;
737
848
  export declare function renderException(exception: CaseException): string;
849
+ /** The house wording for one NOTE. Offered, not imposed, as `renderException` is. */
850
+ export declare function renderCaseNote(note: CaseNote): string;
738
851
  /**
739
- * One line a surface can print for a whole case.
852
+ * The scope sentence, printed directly under the headline (evidence-bundle
853
+ * 5.5.6 v1.20, A26), byte for byte the text `render_case_summary` returns.
740
854
  *
741
- * Both kernels print this sentence, so a reader who runs the Python command and
742
- * the TypeScript one over one case archive reads one sentence rather than two
743
- * that differ by a word.
855
+ * The packs in the reading; the distinct keys, compared as keys, that signed
856
+ * the wrapper of a pack whose wrapper held; the hand-off records; the
857
+ * exceptions; and that the reading was made offline. Where any pack holds
858
+ * records withheld by its declaration, their total; where any pack is noted
859
+ * `pack_undeclared`, how many. Those two lines are part of what the headline
860
+ * MEANS, and a surface MUST print them with it.
861
+ *
862
+ * What was not checked on the public record is no longer a clause here. It is
863
+ * the witness line (`renderWitnessLine`), printed with every headline.
744
864
  */
745
865
  export declare function renderCaseSummary(reading: CaseReading): string;
866
+ /**
867
+ * The one display title of each of the eight 3 words. A surface prints the
868
+ * title, never the word, and never a title of its own (#173, A18). The wording
869
+ * is Will's to change through the glossary (DL-71); what each MEANS is pinned
870
+ * in the spec.
871
+ */
872
+ export declare const VERDICT_DISPLAY_TITLES: Readonly<Record<string, string>>;
873
+ /**
874
+ * What a reader may rely on, for each of the six words a case reading reaches
875
+ * (5.5.6 v1.20, A26), the same for every drop. `pending` and `not_found`
876
+ * never head a case reading: they are witness states.
877
+ */
878
+ export declare const CASE_RELIANCE: Readonly<Record<CaseVerdict, string>>;
879
+ /** The three witness states, and how each is printed (5.5.6, D7). No other. */
880
+ export declare const WITNESS_STATES: {
881
+ readonly confirmed: "Confirmed on the public record";
882
+ readonly not_checked: "Not checked";
883
+ readonly differs: "The public record holds different bytes";
884
+ };
885
+ export type WitnessState = keyof typeof WITNESS_STATES;
886
+ /**
887
+ * The witness line: a lookup of the public record, reported beside the
888
+ * headline and never in it (D7). It never raises or lowers the headline and
889
+ * never changes its title. `reasons` says why a `not_checked` line did not
890
+ * settle, in a fixed order; `services` names each service that answered, as
891
+ * the URL the lookup used: named, never trusted (6).
892
+ */
893
+ export interface WitnessLine {
894
+ state: WitnessState;
895
+ reasons: string[];
896
+ services: string[];
897
+ }
898
+ /** The line printed where no lookup ran, which is every reading this kernel produces on its own. */
899
+ export declare const WITNESS_NOT_LOOKED_UP: Readonly<WitnessLine>;
900
+ /** The witness line as both kernels print it. */
901
+ export declare function renderWitnessLine(line: WitnessLine): string;