@cello-protocol/protocol-types 0.0.26 → 0.0.28

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.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export { encodeCbor, decodeCbor } from "./cbor.js";
2
2
  export { TRUST_SIGNAL_DOMAIN, encodeTrustSignalEnvelope, decodeTrustSignalEnvelope, hashTrustSignalEnvelope, verifyTrustSignalHash, } from "./trust-signal.js";
3
3
  export type { TrustSignalEnvelope, SignalSubjectKind, SignalIssuerKind, } from "./trust-signal.js";
4
+ export { SUBMISSION_DOMAIN, buildSubmissionTbs, encodeSubmission, decodeSubmission, submissionId, } from "./submission.js";
5
+ export type { SubmissionBody, SubmissionOp, SignedSubmission } from "./submission.js";
4
6
  export type { MessageEnvelope, MessageEnvelopeV1, EnvelopeError, BuildResult, BuildResultV1, ValidateResult, ValidateResultV1, DeserializeResult, DeserializeResultV1, } from "./types.js";
5
7
  export { MAX_CONTENT_BYTES } from "./limits.js";
6
8
  export { encodeStructure1, STRUCTURE1_VERSION } from "./structure1.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -3,6 +3,10 @@ export { encodeCbor, decodeCbor } from "./cbor.js";
3
3
  // portal (mint), the directory (submission + presentation), and both daemons (receipt +
4
4
  // verification) — M10-D16.
5
5
  export { TRUST_SIGNAL_DOMAIN, encodeTrustSignalEnvelope, decodeTrustSignalEnvelope, hashTrustSignalEnvelope, verifyTrustSignalHash, } from "./trust-signal.js";
6
+ // M10B / DOD-END-SUBMIT-1 — the sealed submission wire contract (M10B-D2). ONE implementation,
7
+ // because the daemon signs these bytes and the portal verifies and re-derives them; a byte-identical
8
+ // local copy on each side is how two implementations drift into disagreeing (M10B-D28).
9
+ export { SUBMISSION_DOMAIN, buildSubmissionTbs, encodeSubmission, decodeSubmission, submissionId, } from "./submission.js";
6
10
  export { MAX_CONTENT_BYTES } from "./limits.js";
7
11
  export { encodeStructure1, STRUCTURE1_VERSION } from "./structure1.js";
8
12
  export { SCAN_RESULT_SENTINEL, buildStructure2, encodeStructure2, encodeScanResultSentinel, verifyStructure2Signature, } from "./structure2.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEnD,8FAA8F;AAC9F,wFAAwF;AACxF,2BAA2B;AAC3B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAmB3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGvE,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AA0BjK,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAmBjC,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AA8DnF,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,eAAe,CAAC;AAuBvB,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAE/B,wFAAwF;AACxF,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEnD,8FAA8F;AAC9F,wFAAwF;AACxF,2BAA2B;AAC3B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAO3B,+FAA+F;AAC/F,qGAAqG;AACrG,wFAAwF;AACxF,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GACb,MAAM,iBAAiB,CAAC;AAezB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGvE,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AA0BjK,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAmBjC,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AA8DnF,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,eAAe,CAAC;AAuBvB,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAE/B,wFAAwF;AACxF,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
@@ -62,6 +62,20 @@ export interface OfficerSignature {
62
62
  signature: string;
63
63
  }
64
64
  /** The full consortium manifest with threshold signatures. */
65
+ /**
66
+ * The portal's intake encryption key, as published in the manifest (M10B-D11).
67
+ *
68
+ * OPTIONAL, and a daemon that does not find it must REFUSE to submit and name the reason — never
69
+ * fall back to sending unsealed (§5a ABSENT IS NOT FINE). An unsealed submission hands the directory
70
+ * every endorsement in the clear, which is the one property the sealed queue exists to provide.
71
+ */
72
+ export interface ManifestIntakeKey {
73
+ /** Which key this is. Recorded on every queue row, so a rotated-out private key can be retained
74
+ * until no undrained row references it — retention driven by the queue, not by a timer. */
75
+ key_id: string;
76
+ /** Ed25519 public key, hex. Submissions are sealed to this. */
77
+ pubkey: string;
78
+ }
65
79
  export interface ConsortiumManifest {
66
80
  version: number;
67
81
  /** ISO 8601 timestamp — manifest is not valid before this time. */
@@ -70,6 +84,19 @@ export interface ConsortiumManifest {
70
84
  expires: string;
71
85
  nodes: ConsortiumNode[];
72
86
  signatures: OfficerSignature[];
87
+ /**
88
+ * M10B-D11 — the portal's intake key. Additive and optional: manifests written before it still
89
+ * verify byte-for-byte, because `canonicalManifestBody` builds the signed body from
90
+ * `Object.keys(manifest)` minus `signatures`, an OPEN field set. So a new top-level field is
91
+ * automatically covered by the officer signatures — which is the whole reason the manifest is the
92
+ * right channel for a SEALING key. An unauthenticated channel (a `/bootstrap` route, client
93
+ * config) is not a shortcut here: a substituted intake key means every endorsement is sealed to
94
+ * the attacker.
95
+ *
96
+ * Rotation is a manifest version bump the daemon's existing poll rolls forward, under its
97
+ * `manifest_version_rollback` guard.
98
+ */
99
+ intake_key?: ManifestIntakeKey;
73
100
  }
74
101
  /** Distinct error codes for manifest verification failures. */
75
102
  export type ManifestError = "manifest_signature_invalid" | "manifest_version_rollback" | "manifest_expired";
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;AAE/C,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,QAAQ,CAEvD;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,cAAc,EAAE,CAEjF;AAED,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GACrB,4BAA4B,GAC5B,2BAA2B,GAC3B,kBAAkB,CAAC;AAEvB,qDAAqD;AACrD,eAAO,MAAM,0BAA0B,EAAE,aAA4C,CAAC;AAEtF,mFAAmF;AACnF,eAAO,MAAM,yBAAyB,EAAE,aAA2C,CAAC;AAEpF,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,EAAE,aAAkC,CAAC"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;AAE/C,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,QAAQ,CAEvD;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,cAAc,EAAE,CAEjF;AAED,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,8DAA8D;AAC9D;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC;gGAC4F;IAC5F,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GACrB,4BAA4B,GAC5B,2BAA2B,GAC3B,kBAAkB,CAAC;AAEvB,qDAAqD;AACrD,eAAO,MAAM,0BAA0B,EAAE,aAA4C,CAAC;AAEtF,mFAAmF;AACnF,eAAO,MAAM,yBAAyB,EAAE,aAA2C,CAAC;AAEpF,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,EAAE,aAAkC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkCH;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAoB;IAC3C,OAAQ,IAAI,CAAC,IAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;AACxE,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,WAAW,CAAC,IAAoB;IAC9C,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,WAAW,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAgC;IAC7D,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACnC,CAAC;AA2BD,qDAAqD;AACrD,MAAM,CAAC,MAAM,0BAA0B,GAAkB,4BAA4B,CAAC;AAEtF,mFAAmF;AACnF,MAAM,CAAC,MAAM,yBAAyB,GAAkB,2BAA2B,CAAC;AAEpF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAkB,kBAAkB,CAAC"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkCH;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAoB;IAC3C,OAAQ,IAAI,CAAC,IAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;AACxE,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,WAAW,CAAC,IAAoB;IAC9C,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,WAAW,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAgC;IAC7D,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACnC,CAAC;AAuDD,qDAAqD;AACrD,MAAM,CAAC,MAAM,0BAA0B,GAAkB,4BAA4B,CAAC;AAEtF,mFAAmF;AACnF,MAAM,CAAC,MAAM,yBAAyB,GAAkB,2BAA2B,CAAC;AAEpF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAkB,kBAAkB,CAAC"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * M10B / DOD-END-SUBMIT-1 — the sealed submission wire contract (M10B-D2, D-20, D-28, D-31).
3
+ *
4
+ * The client-supplied source's only wire shape. Bob's daemon builds a body, signs the canonical TBS
5
+ * with his agent's K_local, and seals the encoded pair to the portal's intake key; the directory
6
+ * carries the ciphertext without being able to read it; the portal opens it, verifies, and mints.
7
+ *
8
+ * IT LIVES HERE, NOT IN THE DAEMON, AND THAT IS LOAD-BEARING. Three parties rebuild these bytes
9
+ * independently — the daemon signing, the portal verifying, the portal re-deriving `submission_id`
10
+ * to dedupe a retry. A byte-identical local copy on each side is exactly how two implementations
11
+ * drift apart, and the failure it produces is a signature that will not verify, which reads as a bad
12
+ * key rather than as an encoder disagreement (M10B-D28).
13
+ *
14
+ * THE TBS IS AN ARRAY, NOT A MAP. `cbor.ts` is not deterministic for maps — keys follow insertion
15
+ * order and map headers are not minimal-length — so two parties building the same map in a different
16
+ * field order produce different bytes. Every signed structure in CELLO is a fixed-order array for
17
+ * this reason (`buildAgentRevocationTbs`, `buildPrimaryTransferTbs`, `buildSealTbs`).
18
+ *
19
+ * FIELD ORDER IS THE WIRE FORMAT and the field set is CLOSED. Reordering is a breaking signature
20
+ * change, not a refactor; an unknown field is REJECTED rather than ignored, because silently
21
+ * dropping it would let two parties who disagree about the field set still agree on the signature —
22
+ * making the extra field unauthenticated data riding inside a "verified" submission (spec §4).
23
+ *
24
+ * WHAT IS *NOT* HERE: nothing that names a signal TYPE. The discriminator is `op` — a protocol verb
25
+ * the directory already branches on — and `subject_kind`, which is envelope data. A second
26
+ * client-sourced type sends this identical structure (INV-ZEROBUMP).
27
+ *
28
+ * Crypto: Ed25519 → RFC 8032, CBOR → RFC 8949, SHA-256 → FIPS 180-4.
29
+ */
30
+ import type { SignalSubjectKind } from "./trust-signal.js";
31
+ /** Domain separation, bound as element 0 — the house convention. Distinct from `CELLO-TSIG-v1` (the
32
+ * envelope preimage) and `CELLO-TSIG-REQ-v1` (the directory's request TBS), so a signature over one
33
+ * can never be replayed as another. */
34
+ export declare const SUBMISSION_DOMAIN = "CELLO-SUBMIT-v1";
35
+ /**
36
+ * What the submitter is ASKING FOR — an operation, never a signal type (M10B-D28).
37
+ *
38
+ * `signal-write.ts` already discriminates its request bodies this way, and the distinction matters
39
+ * for INV-ZEROBUMP: branching on what a signal *means* is forbidden; branching on what the caller is
40
+ * *asking for* is what a protocol verb is. It rides INSIDE the seal, so the directory still cannot
41
+ * tell a withdrawal from an endorsement.
42
+ *
43
+ * `refuse` (M10B-D4) carries the SUBJECT's optional message back to the issuer after she refuses an
44
+ * endorsement about her. It is a third verb rather than a new structure, and widening this union
45
+ * changes no field and no order — so every signature already made over a `submit` or `withdraw`
46
+ * body still verifies. For `refuse` and `withdraw` alike, `subject` is the TARGET SIGNAL HASH: both
47
+ * act on an existing signal instead of asserting a fact about a party.
48
+ */
49
+ export type SubmissionOp = "submit" | "withdraw" | "refuse";
50
+ /**
51
+ * The signed part of a submission. Every field is inside the TBS — a field outside it is
52
+ * unauthenticated data an attacker can edit in flight while the signature still verifies.
53
+ */
54
+ export interface SubmissionBody {
55
+ /** Wire version. Signed, so it cannot be downgraded in flight. */
56
+ v: number;
57
+ op: SubmissionOp;
58
+ /** Whose fact this is. The portal resolves an agent subject to an account when it needs one — no
59
+ * account identifier ever crosses the wire (the directory is hash-only by design). */
60
+ subject_kind: SignalSubjectKind;
61
+ /** For `subject_kind: "agent"`, the subject's K_local pubkey hex — the only identifier a contact
62
+ * actually holds. For a withdrawal, the target signal hash. */
63
+ subject: string;
64
+ /**
65
+ * The submitter's K_local pubkey hex.
66
+ *
67
+ * **This field is worthless until the signature verifies against it, and it must never be read for
68
+ * any other purpose.** Ed25519 has no key recovery (RFC 8032), so "derive `issuer_pubkey` from the
69
+ * signature" cannot mean literal recovery — it means the pubkey is present but carries no
70
+ * authority on its own. A body claiming P together with a valid signature by P proves possession
71
+ * of P's private key; a body claiming P with any other signature proves nothing and must be
72
+ * refused. Reading it before verification is the INV-ATTRIBUTION defect: anyone could mint an
73
+ * endorsement attributed to anyone, permanently, inside the hash.
74
+ */
75
+ submitter_pubkey: string;
76
+ /** The operator's own words, untrusted and unscanned at this layer. Scanned at intake, BEFORE
77
+ * hashing (spec §6), and never restated in the portal's attested voice (INV-UNTRUSTED). */
78
+ body: string;
79
+ /** Integer epoch SECONDS. Inside the TBS, so the verifier's clock-skew bound applies — without it
80
+ * a signature is a permanent bearer capability replayable at every node forever (M10B-D28). */
81
+ issued_at: number;
82
+ }
83
+ /** A decoded submission: the body as signed, plus the detached signature over its TBS. */
84
+ export interface SignedSubmission {
85
+ body: SubmissionBody;
86
+ signature: Uint8Array;
87
+ }
88
+ /**
89
+ * Canonical to-be-signed bytes. Field order is LOAD-BEARING — the daemon signing and the portal
90
+ * verifying must produce identical bytes, across two repos, forever.
91
+ */
92
+ export declare function buildSubmissionTbs(body: SubmissionBody): Uint8Array;
93
+ /** The sealed plaintext: the TBS fields followed by the detached signature. */
94
+ export declare function encodeSubmission(body: SubmissionBody, signature: Uint8Array): Uint8Array;
95
+ /**
96
+ * Decode a sealed submission's plaintext.
97
+ *
98
+ * THROWS on anything it does not fully recognise, and that is the design. A submission that cannot
99
+ * be decoded is POISON — the identity is derived from the signature, so an unparseable body has no
100
+ * known sender and there is nobody to reply to (M10B-D22b). The failure must therefore be loud
101
+ * HERE, not a partly-populated body that flows onward and gets attributed to whatever
102
+ * `submitter_pubkey` happened to decode as.
103
+ */
104
+ export declare function decodeSubmission(bytes: Uint8Array): SignedSubmission;
105
+ /**
106
+ * `submission_id` — sha256 over the ENCODED signed submission (M10B-D20), lowercase hex.
107
+ *
108
+ * Content-derived, which is what makes retry-across-nodes safe rather than a duplication mechanism:
109
+ * a daemon that fails over to a second node produces the same id, so the second row is a strict
110
+ * no-op. A legitimate re-issue after a refusal differs, because `issued_at` is inside the signed
111
+ * body — otherwise the portal would dedupe Bob's correction away as a retry and Alice would never
112
+ * see it.
113
+ *
114
+ * **At the directory this id is a ROUTING HINT and nothing more.** The directory cannot open the
115
+ * seal, so it cannot check that the id matches the bytes; the portal re-derives it from the opened
116
+ * body and discards any row whose id disagrees. A daemon writing the same body under two different
117
+ * ids to two nodes would otherwise get two mints and double quota consumption (M10B-D20's
118
+ * second-review correction).
119
+ */
120
+ export declare function submissionId(encodedSubmission: Uint8Array): string;
121
+ //# sourceMappingURL=submission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submission.d.ts","sourceRoot":"","sources":["../src/submission.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;wCAEwC;AACxC,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAO5D;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,YAAY,CAAC;IACjB;2FACuF;IACvF,YAAY,EAAE,iBAAiB,CAAC;IAChC;oEACgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;OAUG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;gGAC4F;IAC5F,IAAI,EAAE,MAAM,CAAC;IACb;oGACgG;IAChG,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,0FAA0F;AAC1F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,UAAU,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAWnE;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,GAAG,UAAU,CAYxF;AAeD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,gBAAgB,CA6CpE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,iBAAiB,EAAE,UAAU,GAAG,MAAM,CAElE"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * M10B / DOD-END-SUBMIT-1 — the sealed submission wire contract (M10B-D2, D-20, D-28, D-31).
3
+ *
4
+ * The client-supplied source's only wire shape. Bob's daemon builds a body, signs the canonical TBS
5
+ * with his agent's K_local, and seals the encoded pair to the portal's intake key; the directory
6
+ * carries the ciphertext without being able to read it; the portal opens it, verifies, and mints.
7
+ *
8
+ * IT LIVES HERE, NOT IN THE DAEMON, AND THAT IS LOAD-BEARING. Three parties rebuild these bytes
9
+ * independently — the daemon signing, the portal verifying, the portal re-deriving `submission_id`
10
+ * to dedupe a retry. A byte-identical local copy on each side is exactly how two implementations
11
+ * drift apart, and the failure it produces is a signature that will not verify, which reads as a bad
12
+ * key rather than as an encoder disagreement (M10B-D28).
13
+ *
14
+ * THE TBS IS AN ARRAY, NOT A MAP. `cbor.ts` is not deterministic for maps — keys follow insertion
15
+ * order and map headers are not minimal-length — so two parties building the same map in a different
16
+ * field order produce different bytes. Every signed structure in CELLO is a fixed-order array for
17
+ * this reason (`buildAgentRevocationTbs`, `buildPrimaryTransferTbs`, `buildSealTbs`).
18
+ *
19
+ * FIELD ORDER IS THE WIRE FORMAT and the field set is CLOSED. Reordering is a breaking signature
20
+ * change, not a refactor; an unknown field is REJECTED rather than ignored, because silently
21
+ * dropping it would let two parties who disagree about the field set still agree on the signature —
22
+ * making the extra field unauthenticated data riding inside a "verified" submission (spec §4).
23
+ *
24
+ * WHAT IS *NOT* HERE: nothing that names a signal TYPE. The discriminator is `op` — a protocol verb
25
+ * the directory already branches on — and `subject_kind`, which is envelope data. A second
26
+ * client-sourced type sends this identical structure (INV-ZEROBUMP).
27
+ *
28
+ * Crypto: Ed25519 → RFC 8032, CBOR → RFC 8949, SHA-256 → FIPS 180-4.
29
+ */
30
+ import { hash as sha256 } from "@cello-protocol/crypto";
31
+ import { encodeCbor, decodeCbor } from "./cbor.js";
32
+ /** Domain separation, bound as element 0 — the house convention. Distinct from `CELLO-TSIG-v1` (the
33
+ * envelope preimage) and `CELLO-TSIG-REQ-v1` (the directory's request TBS), so a signature over one
34
+ * can never be replayed as another. */
35
+ export const SUBMISSION_DOMAIN = "CELLO-SUBMIT-v1";
36
+ /** The number of elements in the TBS array, INCLUDING the domain tag. Bump only with the wire. */
37
+ const TBS_ARITY = 8;
38
+ /** The encoded submission is the TBS fields plus the detached signature. */
39
+ const ENCODED_ARITY = TBS_ARITY + 1;
40
+ /**
41
+ * Canonical to-be-signed bytes. Field order is LOAD-BEARING — the daemon signing and the portal
42
+ * verifying must produce identical bytes, across two repos, forever.
43
+ */
44
+ export function buildSubmissionTbs(body) {
45
+ return encodeCbor([
46
+ SUBMISSION_DOMAIN,
47
+ body.v,
48
+ body.op,
49
+ body.subject_kind,
50
+ body.subject,
51
+ body.submitter_pubkey,
52
+ body.body,
53
+ body.issued_at,
54
+ ]);
55
+ }
56
+ /** The sealed plaintext: the TBS fields followed by the detached signature. */
57
+ export function encodeSubmission(body, signature) {
58
+ return encodeCbor([
59
+ SUBMISSION_DOMAIN,
60
+ body.v,
61
+ body.op,
62
+ body.subject_kind,
63
+ body.subject,
64
+ body.submitter_pubkey,
65
+ body.body,
66
+ body.issued_at,
67
+ signature,
68
+ ]);
69
+ }
70
+ function str(v, field) {
71
+ if (typeof v !== "string")
72
+ throw new Error(`submission_malformed: ${field} must be a string`);
73
+ return v;
74
+ }
75
+ function int(v, field) {
76
+ const n = typeof v === "bigint" ? Number(v) : v;
77
+ if (typeof n !== "number" || !Number.isInteger(n)) {
78
+ throw new Error(`submission_malformed: ${field} must be an integer`);
79
+ }
80
+ return n;
81
+ }
82
+ /**
83
+ * Decode a sealed submission's plaintext.
84
+ *
85
+ * THROWS on anything it does not fully recognise, and that is the design. A submission that cannot
86
+ * be decoded is POISON — the identity is derived from the signature, so an unparseable body has no
87
+ * known sender and there is nobody to reply to (M10B-D22b). The failure must therefore be loud
88
+ * HERE, not a partly-populated body that flows onward and gets attributed to whatever
89
+ * `submitter_pubkey` happened to decode as.
90
+ */
91
+ export function decodeSubmission(bytes) {
92
+ let decoded;
93
+ try {
94
+ decoded = decodeCbor(bytes);
95
+ }
96
+ catch (err) {
97
+ throw new Error(`submission_malformed: not valid CBOR: ${err instanceof Error ? err.message : String(err)}`);
98
+ }
99
+ if (!Array.isArray(decoded))
100
+ throw new Error("submission_malformed: expected an array");
101
+ if (decoded.length !== ENCODED_ARITY) {
102
+ // Closed field set: a longer array is an unknown field, a shorter one is a missing field, and
103
+ // both must refuse rather than be read positionally into the wrong slots.
104
+ throw new Error(`submission_malformed: expected ${ENCODED_ARITY} elements, got ${decoded.length}`);
105
+ }
106
+ if (decoded[0] !== SUBMISSION_DOMAIN) {
107
+ throw new Error(`submission_malformed: wrong domain tag — refusing to read a foreign structure`);
108
+ }
109
+ const op = str(decoded[2], "op");
110
+ if (op !== "submit" && op !== "withdraw" && op !== "refuse") {
111
+ throw new Error(`submission_malformed: unknown op '${op}'`);
112
+ }
113
+ const subjectKind = str(decoded[3], "subject_kind");
114
+ if (subjectKind !== "agent" && subjectKind !== "account") {
115
+ throw new Error(`submission_malformed: unknown subject_kind '${subjectKind}'`);
116
+ }
117
+ const signature = decoded[8];
118
+ if (!(signature instanceof Uint8Array)) {
119
+ throw new Error("submission_malformed: signature must be bytes");
120
+ }
121
+ // The CBOR decoder hands back a Node `Buffer` (a Uint8Array SUBCLASS). Normalise it, so the
122
+ // declared type is the actual type: a caller that received a Buffer here could come to depend on
123
+ // Buffer-only methods, and the same code would then break in any runtime whose decoder returns a
124
+ // plain view. Copying 64 bytes is not a cost worth trading that for.
125
+ const signatureBytes = new Uint8Array(signature);
126
+ return {
127
+ body: {
128
+ v: int(decoded[1], "v"),
129
+ op,
130
+ subject_kind: subjectKind,
131
+ subject: str(decoded[4], "subject"),
132
+ submitter_pubkey: str(decoded[5], "submitter_pubkey"),
133
+ body: str(decoded[6], "body"),
134
+ issued_at: int(decoded[7], "issued_at"),
135
+ },
136
+ signature: signatureBytes,
137
+ };
138
+ }
139
+ /**
140
+ * `submission_id` — sha256 over the ENCODED signed submission (M10B-D20), lowercase hex.
141
+ *
142
+ * Content-derived, which is what makes retry-across-nodes safe rather than a duplication mechanism:
143
+ * a daemon that fails over to a second node produces the same id, so the second row is a strict
144
+ * no-op. A legitimate re-issue after a refusal differs, because `issued_at` is inside the signed
145
+ * body — otherwise the portal would dedupe Bob's correction away as a retry and Alice would never
146
+ * see it.
147
+ *
148
+ * **At the directory this id is a ROUTING HINT and nothing more.** The directory cannot open the
149
+ * seal, so it cannot check that the id matches the bytes; the portal re-derives it from the opened
150
+ * body and discards any row whose id disagrees. A daemon writing the same body under two different
151
+ * ids to two nodes would otherwise get two mints and double quota consumption (M10B-D20's
152
+ * second-review correction).
153
+ */
154
+ export function submissionId(encodedSubmission) {
155
+ return Buffer.from(sha256(encodedSubmission)).toString("hex");
156
+ }
157
+ //# sourceMappingURL=submission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submission.js","sourceRoot":"","sources":["../src/submission.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cello-protocol/protocol-types",
3
- "version": "0.0.26",
3
+ "version": "0.0.28",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -26,7 +26,7 @@
26
26
  ],
27
27
  "dependencies": {
28
28
  "cbor-x": "^1.6.4",
29
- "@cello-protocol/crypto": "0.0.24"
29
+ "@cello-protocol/crypto": "0.0.26"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@claude-flow/testing": "3.0.0-alpha.6",