@cello-protocol/daemon 0.0.181 → 0.0.183
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/agent-id-migration.d.ts +9 -0
- package/dist/agent-id-migration.d.ts.map +1 -1
- package/dist/agent-id-migration.js +73 -1
- package/dist/agent-id-migration.js.map +1 -1
- package/dist/agent-selection.d.ts +73 -0
- package/dist/agent-selection.d.ts.map +1 -0
- package/dist/agent-selection.js +80 -0
- package/dist/agent-selection.js.map +1 -0
- package/dist/agent-settings-keys.d.ts.map +1 -1
- package/dist/agent-settings-keys.js +18 -0
- package/dist/agent-settings-keys.js.map +1 -1
- package/dist/assignment-verify.d.ts +62 -0
- package/dist/assignment-verify.d.ts.map +1 -0
- package/dist/assignment-verify.js +185 -0
- package/dist/assignment-verify.js.map +1 -0
- package/dist/backup-restore.d.ts +102 -0
- package/dist/backup-restore.d.ts.map +1 -0
- package/dist/backup-restore.js +340 -0
- package/dist/backup-restore.js.map +1 -0
- package/dist/bin/cello-daemon.js +91 -49
- package/dist/bin/cello-daemon.js.map +1 -1
- package/dist/close-commitment.d.ts +67 -0
- package/dist/close-commitment.d.ts.map +1 -0
- package/dist/close-commitment.js +78 -0
- package/dist/close-commitment.js.map +1 -0
- package/dist/close-session-handler.d.ts +20 -0
- package/dist/close-session-handler.d.ts.map +1 -1
- package/dist/close-session-handler.js +351 -58
- package/dist/close-session-handler.js.map +1 -1
- package/dist/consortium-bootstrap.d.ts +2 -0
- package/dist/consortium-bootstrap.d.ts.map +1 -1
- package/dist/consortium-bootstrap.js +182 -9
- package/dist/consortium-bootstrap.js.map +1 -1
- package/dist/content-encryption-status.d.ts +97 -0
- package/dist/content-encryption-status.d.ts.map +1 -0
- package/dist/content-encryption-status.js +122 -0
- package/dist/content-encryption-status.js.map +1 -0
- package/dist/content-park-client.d.ts +10 -0
- package/dist/content-park-client.d.ts.map +1 -1
- package/dist/content-park-client.js +84 -3
- package/dist/content-park-client.js.map +1 -1
- package/dist/content-park.d.ts.map +1 -1
- package/dist/content-park.js +323 -21
- package/dist/content-park.js.map +1 -1
- package/dist/daemon.d.ts +13 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +1168 -141
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-session-suspects.d.ts.map +1 -1
- package/dist/delivery-session-suspects.js +5 -0
- package/dist/delivery-session-suspects.js.map +1 -1
- package/dist/directory-auth-posture.d.ts +87 -0
- package/dist/directory-auth-posture.d.ts.map +1 -0
- package/dist/directory-auth-posture.js +134 -0
- package/dist/directory-auth-posture.js.map +1 -0
- package/dist/directory-bootstrap.d.ts +66 -3
- package/dist/directory-bootstrap.d.ts.map +1 -1
- package/dist/directory-bootstrap.js +133 -7
- package/dist/directory-bootstrap.js.map +1 -1
- package/dist/document-delivery-transport.d.ts +22 -2
- package/dist/document-delivery-transport.d.ts.map +1 -1
- package/dist/document-delivery-transport.js +11 -3
- package/dist/document-delivery-transport.js.map +1 -1
- package/dist/document-handlers.d.ts.map +1 -1
- package/dist/document-handlers.js +119 -0
- package/dist/document-handlers.js.map +1 -1
- package/dist/document-layer.d.ts +0 -2
- package/dist/document-layer.d.ts.map +1 -1
- package/dist/document-layer.js.map +1 -1
- package/dist/inbound-sessions.d.ts +31 -1
- package/dist/inbound-sessions.d.ts.map +1 -1
- package/dist/inbound-sessions.js +276 -16
- package/dist/inbound-sessions.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/initiate-session-handler.d.ts.map +1 -1
- package/dist/initiate-session-handler.js +34 -3
- package/dist/initiate-session-handler.js.map +1 -1
- package/dist/ipc-server.d.ts +5 -1
- package/dist/ipc-server.d.ts.map +1 -1
- package/dist/ipc-server.js +19 -3
- package/dist/ipc-server.js.map +1 -1
- package/dist/manifest-deps.d.ts +0 -11
- package/dist/manifest-deps.d.ts.map +1 -1
- package/dist/manifest-deps.js +28 -2
- package/dist/manifest-deps.js.map +1 -1
- package/dist/manifest-validity.d.ts +153 -0
- package/dist/manifest-validity.d.ts.map +1 -0
- package/dist/manifest-validity.js +268 -0
- package/dist/manifest-validity.js.map +1 -0
- package/dist/notification-handlers.d.ts.map +1 -1
- package/dist/notification-handlers.js +15 -0
- package/dist/notification-handlers.js.map +1 -1
- package/dist/outbound-sessions.d.ts +31 -0
- package/dist/outbound-sessions.d.ts.map +1 -1
- package/dist/outbound-sessions.js +217 -17
- package/dist/outbound-sessions.js.map +1 -1
- package/dist/park-envelope.d.ts +95 -1
- package/dist/park-envelope.d.ts.map +1 -1
- package/dist/park-envelope.js +195 -4
- package/dist/park-envelope.js.map +1 -1
- package/dist/refusal-reasons.d.ts +72 -0
- package/dist/refusal-reasons.d.ts.map +1 -0
- package/dist/refusal-reasons.js +69 -0
- package/dist/refusal-reasons.js.map +1 -0
- package/dist/register-handler.d.ts.map +1 -1
- package/dist/register-handler.js +76 -0
- package/dist/register-handler.js.map +1 -1
- package/dist/registration-manager.d.ts.map +1 -1
- package/dist/registration-manager.js +20 -1
- package/dist/registration-manager.js.map +1 -1
- package/dist/relay-only.d.ts +133 -0
- package/dist/relay-only.d.ts.map +1 -0
- package/dist/relay-only.js +183 -0
- package/dist/relay-only.js.map +1 -0
- package/dist/restart-seal-resolver.d.ts.map +1 -1
- package/dist/restart-seal-resolver.js +6 -0
- package/dist/restart-seal-resolver.js.map +1 -1
- package/dist/retry-queue.d.ts +49 -2
- package/dist/retry-queue.d.ts.map +1 -1
- package/dist/retry-queue.js +55 -10
- package/dist/retry-queue.js.map +1 -1
- package/dist/roster-freshness.d.ts +169 -0
- package/dist/roster-freshness.d.ts.map +1 -0
- package/dist/roster-freshness.js +249 -0
- package/dist/roster-freshness.js.map +1 -0
- package/dist/seal-certificate-pull.d.ts +17 -1
- package/dist/seal-certificate-pull.d.ts.map +1 -1
- package/dist/seal-certificate-pull.js +37 -3
- package/dist/seal-certificate-pull.js.map +1 -1
- package/dist/seal-coordinator.d.ts +17 -1
- package/dist/seal-coordinator.d.ts.map +1 -1
- package/dist/seal-coordinator.js +71 -0
- package/dist/seal-coordinator.js.map +1 -1
- package/dist/seal-failure-store.d.ts +104 -0
- package/dist/seal-failure-store.d.ts.map +1 -0
- package/dist/seal-failure-store.js +126 -0
- package/dist/seal-failure-store.js.map +1 -0
- package/dist/seal-flows.d.ts.map +1 -1
- package/dist/seal-flows.js +35 -6
- package/dist/seal-flows.js.map +1 -1
- package/dist/seal-upgrade.d.ts +20 -5
- package/dist/seal-upgrade.d.ts.map +1 -1
- package/dist/seal-upgrade.js +28 -5
- package/dist/seal-upgrade.js.map +1 -1
- package/dist/session-assignment-parser.d.ts +41 -5
- package/dist/session-assignment-parser.d.ts.map +1 -1
- package/dist/session-assignment-parser.js +77 -14
- package/dist/session-assignment-parser.js.map +1 -1
- package/dist/session-ceremony.d.ts +35 -0
- package/dist/session-ceremony.d.ts.map +1 -1
- package/dist/session-ceremony.js +97 -0
- package/dist/session-ceremony.js.map +1 -1
- package/dist/session-connection-gater.d.ts +46 -7
- package/dist/session-connection-gater.d.ts.map +1 -1
- package/dist/session-connection-gater.js +163 -12
- package/dist/session-connection-gater.js.map +1 -1
- package/dist/session-content-handlers.d.ts +12 -0
- package/dist/session-content-handlers.d.ts.map +1 -1
- package/dist/session-content-handlers.js +149 -8
- package/dist/session-content-handlers.js.map +1 -1
- package/dist/session-node-manager.d.ts +653 -40
- package/dist/session-node-manager.d.ts.map +1 -1
- package/dist/session-node-manager.js +5938 -374
- package/dist/session-node-manager.js.map +1 -1
- package/dist/session-read-handlers.d.ts +27 -0
- package/dist/session-read-handlers.d.ts.map +1 -1
- package/dist/session-read-handlers.js +127 -6
- package/dist/session-read-handlers.js.map +1 -1
- package/dist/session-relay-client.d.ts +177 -2
- package/dist/session-relay-client.d.ts.map +1 -1
- package/dist/session-relay-client.js +564 -16
- package/dist/session-relay-client.js.map +1 -1
- package/dist/session-salt-agreement.d.ts +338 -0
- package/dist/session-salt-agreement.d.ts.map +1 -0
- package/dist/session-salt-agreement.js +478 -0
- package/dist/session-salt-agreement.js.map +1 -0
- package/dist/signal-submission.d.ts.map +1 -1
- package/dist/signal-submission.js +10 -1
- package/dist/signal-submission.js.map +1 -1
- package/dist/signaling-connect.d.ts +18 -1
- package/dist/signaling-connect.d.ts.map +1 -1
- package/dist/signaling-connect.js +206 -6
- package/dist/signaling-connect.js.map +1 -1
- package/dist/types.d.ts +75 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vocabulary.d.ts.map +1 -1
- package/dist/vocabulary.js +10 -0
- package/dist/vocabulary.js.map +1 -1
- package/dist/wire-content-hash.d.ts +68 -0
- package/dist/wire-content-hash.d.ts.map +1 -1
- package/dist/wire-content-hash.js +83 -0
- package/dist/wire-content-hash.js.map +1 -1
- package/package.json +5 -5
package/dist/park-envelope.js
CHANGED
|
@@ -30,6 +30,7 @@ import { decode as cborDecode } from "cbor-x";
|
|
|
30
30
|
import { encodeCbor } from "@cello-protocol/protocol-types";
|
|
31
31
|
import { verify, sealToRecipient } from "@cello-protocol/crypto";
|
|
32
32
|
import { buildParkContentTbs } from "@cello-protocol/protocol-types";
|
|
33
|
+
import { CONTENT_HASH_ALGS, isKnownContentHashAlg } from "./wire-content-hash.js";
|
|
33
34
|
/**
|
|
34
35
|
* Compare an identity key (raw bytes) against a stored hex pubkey — on BYTES, never on the hex
|
|
35
36
|
* strings.
|
|
@@ -61,20 +62,130 @@ export function pubkeyMatchesHex(pubkey, storedHex) {
|
|
|
61
62
|
}
|
|
62
63
|
/** Current envelope version. v1 (unsigned) is decodable but NEVER acceptable — see authenticate(). */
|
|
63
64
|
export const PARK_ENVELOPE_VERSION = 2;
|
|
65
|
+
/**
|
|
66
|
+
* v3 — a v2 envelope plus the CONTENT-HASH ALGORITHM (`DOD-M15-SEALWIRE-1` part B2a).
|
|
67
|
+
*
|
|
68
|
+
* ⚠️ EMITTED ONLY WHEN THE ALGORITHM IS NOT THE DEFAULT, and that is the whole compatibility story.
|
|
69
|
+
* Every envelope this build produces today is still v2, because nothing salts — so no current peer
|
|
70
|
+
* sees a version it cannot read.
|
|
71
|
+
*
|
|
72
|
+
* 🚨 AND THE GATE IS A PUBLISHING FACT, NOT A STRUCTURAL ONE — review B2a F6 corrected this. The
|
|
73
|
+
* header used to claim *"a salted envelope can only be addressed to a peer that completed the salt
|
|
74
|
+
* agreement, and a build able to do that necessarily contains this decoder."* **False as stated:**
|
|
75
|
+
* the salt agreement landed several commits before this decoder, so any build cut from that interval
|
|
76
|
+
* has the agreement and not the decoder. On such a peer a v3 envelope matches no decode branch,
|
|
77
|
+
* falls through to the bare-content v1 shape, and `authenticateParkedEntry` refuses it as
|
|
78
|
+
* `unsigned_envelope` — the ATTACKER shape — the entry is never confirm-deleted, and it re-pulls
|
|
79
|
+
* forever. Exactly the failure this unit exists to prevent.
|
|
80
|
+
*
|
|
81
|
+
* What is true, and checkable: **no published build has the salt agreement without this decoder** —
|
|
82
|
+
* nothing in that interval is tagged. Part B2b must therefore gate salting on a real peer-capability
|
|
83
|
+
* signal rather than inferring capability from "they completed the salt agreement".
|
|
84
|
+
*
|
|
85
|
+
* Why the algorithm is NOT in the signed statement: `parkSig` covers `(session_id, recipient_pubkey,
|
|
86
|
+
* content_hash)` — the HASH, not the name of the function that produced it. Adding the name would
|
|
87
|
+
* change `buildParkContentTbs`, a cross-repo type, for no security gain. An attacker who flips the
|
|
88
|
+
* name cannot make altered content verify, because the recomputed hash must still equal the SIGNED
|
|
89
|
+
* one; a flip can only turn an acceptance into a REFUSAL. `dod-m15-park-envelope-alg.test.ts` pins
|
|
90
|
+
* that, because "only a refusal" is a claim rather than a hope.
|
|
91
|
+
*/
|
|
92
|
+
export const PARK_ENVELOPE_VERSION_ALG = 3;
|
|
93
|
+
/**
|
|
94
|
+
* The versions that carry a sender signature and may therefore be authenticated.
|
|
95
|
+
*
|
|
96
|
+
* A SET, not a single constant, and the difference is mail loss. `authenticateParkedEntry` refused
|
|
97
|
+
* anything whose version was not the one `PARK_ENVELOPE_VERSION` names — so bumping that constant to
|
|
98
|
+
* 3 would have turned every v2 envelope sitting in every relay mailbox into `unsigned_envelope`:
|
|
99
|
+
* store-and-forward mail destroyed, and reported as an attack.
|
|
100
|
+
*/
|
|
101
|
+
const SIGNED_ENVELOPE_VERSIONS = new Set([PARK_ENVELOPE_VERSION, PARK_ENVELOPE_VERSION_ALG]);
|
|
102
|
+
/**
|
|
103
|
+
* Why this build refused to SEAL an entry — the producer side, distinct from `ParkAuthFailure`,
|
|
104
|
+
* which is why it refused to ACCEPT one.
|
|
105
|
+
*/
|
|
106
|
+
export const PARK_ENVELOPE_REASONS = {
|
|
107
|
+
/** The entry names a content-hash algorithm this build cannot itself reproduce. */
|
|
108
|
+
ALG_UNREADABLE: "park_envelope_alg_unreadable",
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* The relay's park-refusal codes.
|
|
112
|
+
*
|
|
113
|
+
* ⚠️ RE-EXPORTED FROM `@cello-protocol/protocol-types`, NOT declared here. They used to be a private
|
|
114
|
+
* copy that happened to agree with the relay's strings — verified by hand once, which is not a
|
|
115
|
+
* guard. A rename on the relay side would have left this copy silently unmatched, falling through to
|
|
116
|
+
* the generic "the relay link is down" wording: the exact defect this family of work removed,
|
|
117
|
+
* reintroduced by a change nobody would think of as a protocol change.
|
|
118
|
+
*/
|
|
119
|
+
import { RELAY_PARK_REFUSALS } from "@cello-protocol/protocol-types";
|
|
120
|
+
export { RELAY_PARK_REFUSALS };
|
|
121
|
+
/**
|
|
122
|
+
* A REFUSAL TO SEAL, carrying a code the caller can branch on — `DOD-M15-SEALWIRE-1` B2b-2
|
|
123
|
+
* constraint 6, inherited from B2a's review.
|
|
124
|
+
*
|
|
125
|
+
* ⚠️ THE PROSE WAS NEVER THE PROBLEM; WHERE IT LANDED WAS. This threw a bare `Error` with a clear
|
|
126
|
+
* paragraph, and `#parkContent`'s catch put `err.message` into `cause` — a field its own callers
|
|
127
|
+
* document as the MACHINE-READABLE half, added (M12-P13) so that nobody would have to substring-match
|
|
128
|
+
* English to decide what to do. A paragraph there is unbranchable, so this fault fell into the
|
|
129
|
+
* generic relay branch and inherited its guidance: *"the relay refused the hand-off, so the message
|
|
130
|
+
* is queued and will be re-sent automatically when the relay link is back."*
|
|
131
|
+
*
|
|
132
|
+
* Both halves of that are false here. The relay was never asked, and every re-park throws in exactly
|
|
133
|
+
* the same place, so the message sits in the queue while its sender waits for a recovery that cannot
|
|
134
|
+
* happen. Splitting the code from the prose is what lets the caller say something true instead.
|
|
135
|
+
*/
|
|
136
|
+
export class ParkEnvelopeError extends Error {
|
|
137
|
+
reason;
|
|
138
|
+
/** The offending value alone, so a caller can log it without re-parsing the sentence. */
|
|
139
|
+
detail;
|
|
140
|
+
constructor(reason, detail, message) {
|
|
141
|
+
super(message);
|
|
142
|
+
this.name = "ParkEnvelopeError";
|
|
143
|
+
this.reason = reason;
|
|
144
|
+
this.detail = detail;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
64
147
|
/**
|
|
65
148
|
* SEC-1: encode a SIGNED park envelope. `senderPubkey` and `parkSig` are REQUIRED — the type system
|
|
66
149
|
* is the enforcement point, so no call site can construct an unsigned envelope by omission (the
|
|
67
150
|
* exact drift that made this a downgrade attack: verification existed, but was opt-in).
|
|
68
151
|
*/
|
|
69
152
|
export function encodeParkEnvelope(args) {
|
|
70
|
-
|
|
71
|
-
PARK_ENVELOPE_VERSION,
|
|
153
|
+
const base = [
|
|
72
154
|
args.content,
|
|
73
155
|
args.structure1Cbor ?? null,
|
|
74
156
|
args.structure2Cbor ?? null,
|
|
75
157
|
args.senderPubkey,
|
|
76
158
|
args.parkSig,
|
|
77
|
-
]
|
|
159
|
+
];
|
|
160
|
+
/**
|
|
161
|
+
* The DEFAULT algorithm stays on v2 even when named explicitly. A caller that starts passing the
|
|
162
|
+
* algorithm through would otherwise push every envelope to a version older peers cannot read,
|
|
163
|
+
* without anyone having decided to.
|
|
164
|
+
*
|
|
165
|
+
* ABSENT is `undefined`/`null` ONLY, never "falsy" — review B2a F4. `!args.contentHashAlg` also
|
|
166
|
+
* caught the EMPTY STRING, which is the collapse `resolveContentHashAlg` documents as forbidden
|
|
167
|
+
* and which this file's own `contentHashAlg` doc cites B1 for. A caller whose variable is `""`
|
|
168
|
+
* would have emitted a v2 envelope labelled sha256-by-absence, and the recipient would report a
|
|
169
|
+
* tamper on a message nobody touched.
|
|
170
|
+
*/
|
|
171
|
+
const alg = args.contentHashAlg;
|
|
172
|
+
if (alg === undefined || alg === null || alg === CONTENT_HASH_ALGS.SHA256) {
|
|
173
|
+
return encodeCbor([PARK_ENVELOPE_VERSION, ...base]);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* REFUSE TO EMIT A NAME WE CANNOT READ OURSELVES — the producer-side mirror of what
|
|
177
|
+
* `contentHashFor` already does, and it costs nothing to have.
|
|
178
|
+
*
|
|
179
|
+
* Without it a caller can seal an envelope every peer refuses — including this build — with no
|
|
180
|
+
* signal at the sender at all: the message parks, is pulled, is refused, is kept, and repeats.
|
|
181
|
+
* A throw here is a developer error at the moment it is made, rather than a silent mail loop.
|
|
182
|
+
*/
|
|
183
|
+
if (!isKnownContentHashAlg(alg)) {
|
|
184
|
+
throw new ParkEnvelopeError(PARK_ENVELOPE_REASONS.ALG_UNREADABLE, alg, `PARK ENVELOPE: refusing to seal an entry naming content-hash algorithm "${alg}", which this ` +
|
|
185
|
+
"build cannot itself reproduce. The recipient would refuse it and keep re-pulling it forever, " +
|
|
186
|
+
"and nothing at the sender would say why.");
|
|
187
|
+
}
|
|
188
|
+
return encodeCbor([PARK_ENVELOPE_VERSION_ALG, ...base, alg]);
|
|
78
189
|
}
|
|
79
190
|
/**
|
|
80
191
|
* SEC-1 — THE ONLY PRODUCER. Sign the entry as the sending agent, wrap it in a v2 envelope, and seal
|
|
@@ -97,6 +208,7 @@ export async function sealParkEnvelope(args) {
|
|
|
97
208
|
structure2Cbor: args.structure2Cbor,
|
|
98
209
|
senderPubkey,
|
|
99
210
|
parkSig,
|
|
211
|
+
contentHashAlg: args.contentHashAlg,
|
|
100
212
|
});
|
|
101
213
|
// The signature rides INSIDE the seal — the relay (the adversary) never sees it, so it can neither
|
|
102
214
|
// strip nor forge it. INV-3 is untouched: the relay still holds only ciphertext.
|
|
@@ -110,6 +222,20 @@ export async function sealParkEnvelope(args) {
|
|
|
110
222
|
export function decodeParkEnvelope(plaintext) {
|
|
111
223
|
try {
|
|
112
224
|
const arr = cborDecode(plaintext);
|
|
225
|
+
// v3 first: a v2 envelope plus the content-hash algorithm as a 7th element.
|
|
226
|
+
if (Array.isArray(arr) && arr.length === 7 && arr[0] === PARK_ENVELOPE_VERSION_ALG && arr[1] instanceof Uint8Array) {
|
|
227
|
+
return {
|
|
228
|
+
version: PARK_ENVELOPE_VERSION_ALG,
|
|
229
|
+
content: arr[1],
|
|
230
|
+
structure1Cbor: arr[2] instanceof Uint8Array ? arr[2] : undefined,
|
|
231
|
+
structure2Cbor: arr[3] instanceof Uint8Array ? arr[3] : undefined,
|
|
232
|
+
senderPubkey: arr[4] instanceof Uint8Array ? arr[4] : undefined,
|
|
233
|
+
parkSig: arr[5] instanceof Uint8Array ? arr[5] : undefined,
|
|
234
|
+
// A non-string here stays ABSENT rather than being coerced. `resolveContentHashAlg` refuses
|
|
235
|
+
// a name it cannot read; it must never be handed a `"42"` that looks like one.
|
|
236
|
+
contentHashAlg: typeof arr[6] === "string" ? arr[6] : undefined,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
113
239
|
if (Array.isArray(arr) && arr.length === 6 && arr[0] === PARK_ENVELOPE_VERSION && arr[1] instanceof Uint8Array) {
|
|
114
240
|
return {
|
|
115
241
|
version: PARK_ENVELOPE_VERSION,
|
|
@@ -148,7 +274,7 @@ export function authenticateParkedEntry(args) {
|
|
|
148
274
|
const { env, sessionIdHex, recipientPubkey, contentHash, counterpartyPubkeyHex } = args;
|
|
149
275
|
// 1. Unsigned (v1 envelope, or raw bare content) — the shape an attacker sends, and the shape the
|
|
150
276
|
// pre-SEC-1 daemon ingested without a single check. Refused outright.
|
|
151
|
-
if (env.version
|
|
277
|
+
if (!SIGNED_ENVELOPE_VERSIONS.has(env.version) || !env.senderPubkey || !env.parkSig) {
|
|
152
278
|
return { ok: false, reason: "unsigned_envelope" };
|
|
153
279
|
}
|
|
154
280
|
// 2. Fail closed when there is no counterparty to bind the signer to.
|
|
@@ -170,4 +296,69 @@ export function authenticateParkedEntry(args) {
|
|
|
170
296
|
}
|
|
171
297
|
return { ok: true };
|
|
172
298
|
}
|
|
299
|
+
/**
|
|
300
|
+
* The operator-facing guidance for a refused park hand-off — **a pure function, deliberately.**
|
|
301
|
+
*
|
|
302
|
+
* ⚠️ It was an inline ternary inside `sendContent`, which meant the only way to assert any branch of
|
|
303
|
+
* it was to stand up a two-connection fixture and drive a real send. That is why the branch that was
|
|
304
|
+
* WRONG for a throttling relay survived: nothing cheap could reach it. A guidance string is a
|
|
305
|
+
* decision about what a person does next, and it deserves to be testable on its own.
|
|
306
|
+
*
|
|
307
|
+
* `durable` distinguishes "queued and will retry" from "not queued — it is lost", which is the one
|
|
308
|
+
* distinction that changes whether the reader must act right now.
|
|
309
|
+
*/
|
|
310
|
+
export function parkRefusalGuidance(cause, durable, retryAfterMs) {
|
|
311
|
+
if (cause === PARK_ENVELOPE_REASONS.ALG_UNREADABLE) {
|
|
312
|
+
return ("This message names a content-hash algorithm your build cannot produce, so it could not be " +
|
|
313
|
+
"sealed for hand-off. The relay is NOT involved and this will not clear on its own — the " +
|
|
314
|
+
"message is safely stored but every retry fails the same way. Upgrade to a build that knows " +
|
|
315
|
+
"the algorithm, or start a new session with this counterparty. Re-sending on this build " +
|
|
316
|
+
"changes nothing.");
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* ⚠️ DIAGNOSIS AND ACTION ARE COMPOSED, NOT WRITTEN TOGETHER — and this shape is the fix for a
|
|
320
|
+
* defect review found in the first version.
|
|
321
|
+
*
|
|
322
|
+
* That version returned a complete paragraph per cause and **never consulted `durable`**, so all
|
|
323
|
+
* three new branches ended "The message is queued and re-sent automatically. Do not re-send it."
|
|
324
|
+
* `durable` is OBSERVED, not assumed: it is false when the durable enqueue was refused as a
|
|
325
|
+
* duplicate, or when the retry hook is unwired. In that case the daemon logs at ERROR that the
|
|
326
|
+
* content is *not* separately retained while the operator was simultaneously told it was queued
|
|
327
|
+
* and instructed not to re-send. **Nothing held the message.** That is precisely the lie this
|
|
328
|
+
* family of work exists to kill, reintroduced one layer up.
|
|
329
|
+
*
|
|
330
|
+
* Splitting them makes the mistake unavailable: the action half is produced in exactly one place
|
|
331
|
+
* and cannot be reached without reading the flag.
|
|
332
|
+
*/
|
|
333
|
+
const diagnosis = cause === RELAY_PARK_REFUSALS.RATE_LIMITED
|
|
334
|
+
? `The relay is healthy and deliberately rate-limiting this agent's hand-offs, so it refused this one. NOTHING IS WRONG with the link or the counterparty, and the limit clears on its own${describeRetryWindow(retryAfterMs)}.`
|
|
335
|
+
: cause === RELAY_PARK_REFUSALS.RECIPIENT_FULL
|
|
336
|
+
? "The relay is holding as much undelivered content for THIS counterparty as it will, so it refused the hand-off. That is about their mailbox, not your connection, and another relay would refuse it too. It clears when they come online and collect it, or when older entries expire."
|
|
337
|
+
: cause === RELAY_PARK_REFUSALS.STORE_FULL
|
|
338
|
+
? "The relay's parked-content store is full, so it refused the hand-off. The link is fine. If this persists the relay operator needs to know — it means the store is under sustained pressure."
|
|
339
|
+
: null;
|
|
340
|
+
if (diagnosis !== null) {
|
|
341
|
+
return durable
|
|
342
|
+
? `${diagnosis} The message is queued and re-sent automatically. Do not re-send it: an identical re-send is not separately queued.`
|
|
343
|
+
: `${diagnosis} ⚠️ BUT THIS MESSAGE WAS NOT QUEUED — it is lost. Send it again.`;
|
|
344
|
+
}
|
|
345
|
+
return durable
|
|
346
|
+
? "Direct delivery failed and the relay refused the hand-off, so the message is queued and will be re-sent automatically when the relay link is back. Do not re-send it: an identical re-send is not separately queued."
|
|
347
|
+
: "Direct delivery failed and the message could NOT be queued for retry — it is lost. Send it again.";
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Render the relay's own retry delay, or say nothing at all.
|
|
351
|
+
*
|
|
352
|
+
* ⚠️ SAYS NOTHING WHEN THE RELAY DID NOT SAY — review MEDIUM-6. The first version of the guidance
|
|
353
|
+
* asserted the limit clears *"in about a minute"*, which is a hardcoded guess about the relay's
|
|
354
|
+
* CONFIGURABLE window: a relay run at ten minutes makes that a wrong promise, and a wrong number is
|
|
355
|
+
* worse than no number because the reader plans around it. When the relay tells us, we quote it;
|
|
356
|
+
* when it does not, the sentence simply ends.
|
|
357
|
+
*/
|
|
358
|
+
function describeRetryWindow(retryAfterMs) {
|
|
359
|
+
if (retryAfterMs === undefined || !Number.isFinite(retryAfterMs) || retryAfterMs <= 0)
|
|
360
|
+
return "";
|
|
361
|
+
const seconds = Math.ceil(retryAfterMs / 1000);
|
|
362
|
+
return seconds < 90 ? ` in about ${String(seconds)} seconds` : ` in about ${String(Math.ceil(seconds / 60))} minutes`;
|
|
363
|
+
}
|
|
173
364
|
//# sourceMappingURL=park-envelope.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"park-envelope.js","sourceRoot":"","sources":["../src/park-envelope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,eAAe,EAAoB,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"park-envelope.js","sourceRoot":"","sources":["../src/park-envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refusal reason codes shared between the site that RECORDS a refusal and the site that EXPLAINS it.
|
|
3
|
+
*
|
|
4
|
+
* DOD-M15-OFFER-SIGNED-1 review N8. These strings were duplicated literals across
|
|
5
|
+
* `inbound-sessions.ts` (which calls `recordRefusal`) and `notification-handlers.ts` (which looks
|
|
6
|
+
* the reason up to attach guidance), with nothing binding them. Rename or mistype either side and
|
|
7
|
+
* the lookup silently misses: the operator gets a bare reason code again, which is exactly the
|
|
8
|
+
* defect the guidance was added to fix — reintroduced by a typo, with every test still green.
|
|
9
|
+
*
|
|
10
|
+
* A shared constant makes that a compile error instead. `REFUSAL_REASONS` is the single source; the
|
|
11
|
+
* guidance table below is keyed by its values, so a reason without guidance cannot be added silently.
|
|
12
|
+
*/
|
|
13
|
+
export declare const REFUSAL_REASONS: {
|
|
14
|
+
/** The session_offer and the session_assignment named different dialers for one session. */
|
|
15
|
+
readonly OFFER_ASSIGNMENT_DIALER_MISMATCH: "offer_assignment_dialer_mismatch";
|
|
16
|
+
/** The directory named a different threshold group key for an already-known counterparty. */
|
|
17
|
+
readonly COUNTERPARTY_PRIMARY_KEY_CHANGED: "counterparty_primary_key_changed";
|
|
18
|
+
/** The inbound assignment failed verification (signature, signer, or shape). */
|
|
19
|
+
readonly INBOUND_ASSIGNMENT_INVALID: "inbound_assignment_invalid";
|
|
20
|
+
};
|
|
21
|
+
export type RefusalReason = (typeof REFUSAL_REASONS)[keyof typeof REFUSAL_REASONS];
|
|
22
|
+
/**
|
|
23
|
+
* The CAPACITY refusals — bounds, not security findings.
|
|
24
|
+
*
|
|
25
|
+
* These deliberately carry no guidance: their codes say what happened, and the cap path already
|
|
26
|
+
* sends the sender their own numbers over the wire. They are declared here anyway so that
|
|
27
|
+
* `recordRefusal` can take a CLOSED union.
|
|
28
|
+
*
|
|
29
|
+
* ⚠️ BYTE-IDENTICAL BY DESIGN. A BLOCKED sender and an over-cap UNKNOWN one must be
|
|
30
|
+
* indistinguishable, or the refusal tells someone they are blocked. Do not add a reason that
|
|
31
|
+
* separates them.
|
|
32
|
+
*/
|
|
33
|
+
export declare const CAPACITY_REASONS: {
|
|
34
|
+
readonly ABUSE_BOUND_SESSIONS_PER_SENDER: "abuse_bound_sessions_per_sender";
|
|
35
|
+
readonly ABUSE_BOUND_UNKNOWN_SESSIONS_GLOBAL: "abuse_bound_unknown_sessions_global";
|
|
36
|
+
};
|
|
37
|
+
export type CapacityReason = (typeof CAPACITY_REASONS)[keyof typeof CAPACITY_REASONS];
|
|
38
|
+
/**
|
|
39
|
+
* Every reason a session may be refused with — the CLOSED set.
|
|
40
|
+
*
|
|
41
|
+
* ─── Why this is a union and not `string` ──────────────────────────────────────────────────────
|
|
42
|
+
*
|
|
43
|
+
* `recordRefusal` used to take `reason: string`, because capacity bounds legitimately pass their own
|
|
44
|
+
* codes. A review measured what that permitted: **add a new security refusal recording a free-form
|
|
45
|
+
* `"assignment_epoch_replayed"` and the entire gate stays green** — the guard fires, the operator
|
|
46
|
+
* gets a bare code with no guidance, and nothing notices, because every test enumerates
|
|
47
|
+
* `REFUSAL_REASONS` and the new code was never in it.
|
|
48
|
+
*
|
|
49
|
+
* That is the guard-nobody-hears pattern in its FORWARD direction: not the four occurrences already
|
|
50
|
+
* fixed, but the next one. A test cannot see a code that does not exist yet. A type can.
|
|
51
|
+
*
|
|
52
|
+
* So the set is closed. Adding a refusal now means adding a member here, and a security member
|
|
53
|
+
* without guidance fails to compile against `REFUSAL_GUIDANCE`'s total map. `DOD-M15-GUARD-HEARD-1`.
|
|
54
|
+
*/
|
|
55
|
+
export type AnyRefusalReason = RefusalReason | CapacityReason;
|
|
56
|
+
/**
|
|
57
|
+
* What the operator should DO, per reason.
|
|
58
|
+
*
|
|
59
|
+
* A bare reason code is not an affordance. These are the SECURITY refusals from the inbound
|
|
60
|
+
* assignment path — the ones where the operator needs to know something was refused on purpose,
|
|
61
|
+
* what it means, and (for the identity change) that the next step happens OUTSIDE CELLO.
|
|
62
|
+
*
|
|
63
|
+
* Typed as a total map over `RefusalReason`, so adding a reason without guidance fails to compile.
|
|
64
|
+
*
|
|
65
|
+
* ⚠️ THE READER IS THE RESPONDER'S OPERATOR, and every verb here must be one THEY can perform.
|
|
66
|
+
* Two of these said "Retry" — which is the INITIATOR's move. The person reading this did not start
|
|
67
|
+
* the session and has nothing to retry; telling them to is an affordance that resolves to nothing,
|
|
68
|
+
* which is worse than no advice because they will try to follow it. The retry advice belongs in the
|
|
69
|
+
* `session_refused` frame, which goes to the side that can act on it.
|
|
70
|
+
*/
|
|
71
|
+
export declare const REFUSAL_GUIDANCE: Record<RefusalReason, string>;
|
|
72
|
+
//# sourceMappingURL=refusal-reasons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refusal-reasons.d.ts","sourceRoot":"","sources":["../src/refusal-reasons.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,eAAe;IAC1B,4FAA4F;;IAE5F,6FAA6F;;IAE7F,gFAAgF;;CAExE,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEnF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB;;;CAGnB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAEtF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG,cAAc,CAAC;AAE9D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAoB1D,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refusal reason codes shared between the site that RECORDS a refusal and the site that EXPLAINS it.
|
|
3
|
+
*
|
|
4
|
+
* DOD-M15-OFFER-SIGNED-1 review N8. These strings were duplicated literals across
|
|
5
|
+
* `inbound-sessions.ts` (which calls `recordRefusal`) and `notification-handlers.ts` (which looks
|
|
6
|
+
* the reason up to attach guidance), with nothing binding them. Rename or mistype either side and
|
|
7
|
+
* the lookup silently misses: the operator gets a bare reason code again, which is exactly the
|
|
8
|
+
* defect the guidance was added to fix — reintroduced by a typo, with every test still green.
|
|
9
|
+
*
|
|
10
|
+
* A shared constant makes that a compile error instead. `REFUSAL_REASONS` is the single source; the
|
|
11
|
+
* guidance table below is keyed by its values, so a reason without guidance cannot be added silently.
|
|
12
|
+
*/
|
|
13
|
+
export const REFUSAL_REASONS = {
|
|
14
|
+
/** The session_offer and the session_assignment named different dialers for one session. */
|
|
15
|
+
OFFER_ASSIGNMENT_DIALER_MISMATCH: "offer_assignment_dialer_mismatch",
|
|
16
|
+
/** The directory named a different threshold group key for an already-known counterparty. */
|
|
17
|
+
COUNTERPARTY_PRIMARY_KEY_CHANGED: "counterparty_primary_key_changed",
|
|
18
|
+
/** The inbound assignment failed verification (signature, signer, or shape). */
|
|
19
|
+
INBOUND_ASSIGNMENT_INVALID: "inbound_assignment_invalid",
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The CAPACITY refusals — bounds, not security findings.
|
|
23
|
+
*
|
|
24
|
+
* These deliberately carry no guidance: their codes say what happened, and the cap path already
|
|
25
|
+
* sends the sender their own numbers over the wire. They are declared here anyway so that
|
|
26
|
+
* `recordRefusal` can take a CLOSED union.
|
|
27
|
+
*
|
|
28
|
+
* ⚠️ BYTE-IDENTICAL BY DESIGN. A BLOCKED sender and an over-cap UNKNOWN one must be
|
|
29
|
+
* indistinguishable, or the refusal tells someone they are blocked. Do not add a reason that
|
|
30
|
+
* separates them.
|
|
31
|
+
*/
|
|
32
|
+
export const CAPACITY_REASONS = {
|
|
33
|
+
ABUSE_BOUND_SESSIONS_PER_SENDER: "abuse_bound_sessions_per_sender",
|
|
34
|
+
ABUSE_BOUND_UNKNOWN_SESSIONS_GLOBAL: "abuse_bound_unknown_sessions_global",
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* What the operator should DO, per reason.
|
|
38
|
+
*
|
|
39
|
+
* A bare reason code is not an affordance. These are the SECURITY refusals from the inbound
|
|
40
|
+
* assignment path — the ones where the operator needs to know something was refused on purpose,
|
|
41
|
+
* what it means, and (for the identity change) that the next step happens OUTSIDE CELLO.
|
|
42
|
+
*
|
|
43
|
+
* Typed as a total map over `RefusalReason`, so adding a reason without guidance fails to compile.
|
|
44
|
+
*
|
|
45
|
+
* ⚠️ THE READER IS THE RESPONDER'S OPERATOR, and every verb here must be one THEY can perform.
|
|
46
|
+
* Two of these said "Retry" — which is the INITIATOR's move. The person reading this did not start
|
|
47
|
+
* the session and has nothing to retry; telling them to is an affordance that resolves to nothing,
|
|
48
|
+
* which is worse than no advice because they will try to follow it. The retry advice belongs in the
|
|
49
|
+
* `session_refused` frame, which goes to the side that can act on it.
|
|
50
|
+
*/
|
|
51
|
+
export const REFUSAL_GUIDANCE = {
|
|
52
|
+
[REFUSAL_REASONS.COUNTERPARTY_PRIMARY_KEY_CHANGED]: "REFUSED ON PURPOSE. The directory named a different signing identity for a contact you have " +
|
|
53
|
+
"completed sessions with before. Either they genuinely re-registered — confirm that with them " +
|
|
54
|
+
"OUT OF BAND (a channel that is not this one), then run cello_contact_remove for them, which " +
|
|
55
|
+
"clears the pinned identity so the next session re-pins — or a directory is substituting an " +
|
|
56
|
+
"identity. Do not accept a session from them until you know which.",
|
|
57
|
+
[REFUSAL_REASONS.OFFER_ASSIGNMENT_DIALER_MISMATCH]: "REFUSED ON PURPOSE. The directory's session offer named one dialer and the session assignment " +
|
|
58
|
+
"named another, so the two frames for one session disagree. A stale or replayed offer produces " +
|
|
59
|
+
"this too, so one occurrence is not proof of a hostile directory. Nothing was accepted, and " +
|
|
60
|
+
"nothing is wrong on your side — the other party has been told to start a new session. If the " +
|
|
61
|
+
"SAME counterparty keeps failing this way, stop treating it as noise: confirm out of band that " +
|
|
62
|
+
"they are the one dialling you, and until they answer, do not accept a session from them.",
|
|
63
|
+
[REFUSAL_REASONS.INBOUND_ASSIGNMENT_INVALID]: "REFUSED ON PURPOSE. The session assignment did not verify, so this agent would have been " +
|
|
64
|
+
"opening its receiver to a peer named by a document it could not check. Nothing was accepted. " +
|
|
65
|
+
"There is nothing for you to retry — the other party holds the session and has been told to " +
|
|
66
|
+
"start a new one. If it repeats for the SAME counterparty, do not accept anything from them " +
|
|
67
|
+
"until you have confirmed out of band that they still control the identity you know them by.",
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=refusal-reasons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refusal-reasons.js","sourceRoot":"","sources":["../src/refusal-reasons.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,4FAA4F;IAC5F,gCAAgC,EAAE,kCAAkC;IACpE,6FAA6F;IAC7F,gCAAgC,EAAE,kCAAkC;IACpE,gFAAgF;IAChF,0BAA0B,EAAE,4BAA4B;CAChD,CAAC;AAIX;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,+BAA+B,EAAE,iCAAiC;IAClE,mCAAmC,EAAE,qCAAqC;CAClE,CAAC;AAuBX;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAkC;IAC7D,CAAC,eAAe,CAAC,gCAAgC,CAAC,EAChD,8FAA8F;QAC9F,+FAA+F;QAC/F,8FAA8F;QAC9F,6FAA6F;QAC7F,mEAAmE;IACrE,CAAC,eAAe,CAAC,gCAAgC,CAAC,EAChD,gGAAgG;QAChG,gGAAgG;QAChG,6FAA6F;QAC7F,+FAA+F;QAC/F,gGAAgG;QAChG,0FAA0F;IAC5F,CAAC,eAAe,CAAC,0BAA0B,CAAC,EAC1C,2FAA2F;QAC3F,+FAA+F;QAC/F,6FAA6F;QAC7F,6FAA6F;QAC7F,6FAA6F;CAChG,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-handler.d.ts","sourceRoot":"","sources":["../src/register-handler.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"register-handler.d.ts","sourceRoot":"","sources":["../src/register-handler.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAOnE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACvC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,yBAAyB,CAAC;IACjE,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,KAAK;QAAE,SAAS,EAAE,gBAAgB,CAAC;QAAC,OAAO,EAAE,MAAM,SAAS,GAAG,IAAI,CAAA;KAAE,CAAC;IACxJ,yBAAyB,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1F,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACrG,yBAAyB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,wBAAwB,EAAE,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACrG,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,WAAW,CAAA;KAAE,CAAC,CAAC;IAChF,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClE,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CA4PvE"}
|
package/dist/register-handler.js
CHANGED
|
@@ -18,6 +18,7 @@ import { manifestNodesToEndpoints } from "./directory-bootstrap.js";
|
|
|
18
18
|
import { DaemonRegistrationContext } from "./registration-context.js";
|
|
19
19
|
import { RegistrationManager } from "./registration-manager.js";
|
|
20
20
|
import { validatorNodes } from "@cello-protocol/protocol-types";
|
|
21
|
+
import { classifyManifestValidity } from "./manifest-validity.js";
|
|
21
22
|
export function registerRegisterHandler(deps) {
|
|
22
23
|
const { handlers, logger, keyProviders, getPersistence, getAgentSignaling, waitForSignalingConnected, dropAgentSignaling, startAgentInternal, directoryEndpointResolver, loadedAgents, registrationGuidance, manifestProvider, } = deps;
|
|
23
24
|
// Single-flight guard (M1): the directory's registration reply frames (dkg_ready /
|
|
@@ -107,6 +108,81 @@ export function registerRegisterHandler(deps) {
|
|
|
107
108
|
// load-bearing: an empty roster (consortium configured but unreachable) must REFUSE in
|
|
108
109
|
// registration-manager, NOT downgrade to single-node (code-reviewer B1 / fallback-finder).
|
|
109
110
|
const currentManifest = manifestProvider?.getCurrentManifest();
|
|
111
|
+
/**
|
|
112
|
+
* DOD-M15-EXPIRY-CONSUMER-POLICY-1 — this consumer PROCEEDS on a lapsed manifest, and that is
|
|
113
|
+
* now a decision rather than an omission. Written down because the split looked accidental:
|
|
114
|
+
* `signal-submission` REFUSES on expiry while this, the higher-stakes consumer, did not even
|
|
115
|
+
* look.
|
|
116
|
+
*
|
|
117
|
+
* **Why it proceeds.** Startup already fails closed on an expired manifest, so a lapsed one
|
|
118
|
+
* exists only inside a LONG-RUNNING daemon. Refusing here sends the operator to the one remedy
|
|
119
|
+
* `signal-submission`'s own guidance warns against — *"a restart without a REPLACEMENT does not
|
|
120
|
+
* reload anything: the daemon refuses to come back and every agent goes offline."* So refusing
|
|
121
|
+
* would brick a running operator to close a window that needs a roster CHANGE to be
|
|
122
|
+
* exploitable at all: the risk is dealing a share to a validator removed since the manifest
|
|
123
|
+
* lapsed, not expiry itself.
|
|
124
|
+
*
|
|
125
|
+
* **Why `signal-submission` is different, and why "make them consistent" would be wrong.** It
|
|
126
|
+
* uses the manifest's PORTAL INTAKE KEY, and a rotated key means a message the portal cannot
|
|
127
|
+
* open and cannot attribute — unattributable poison, its own word, with no error anywhere.
|
|
128
|
+
* Different field, different failure, different answer.
|
|
129
|
+
*
|
|
130
|
+
* **What was actually missing was not the gate — it was the RECORD.** `cello_status` already
|
|
131
|
+
* reports an expired manifest, so the STATE was visible; nothing said a FROST share had been
|
|
132
|
+
* dealt against one. That is what this event is.
|
|
133
|
+
*/
|
|
134
|
+
const manifestValidity = classifyManifestValidity(currentManifest ?? null, Date.now());
|
|
135
|
+
/**
|
|
136
|
+
* ⚠️ NOT ONLY `expired` — review F7. `unreadable_window` (a window field that does not parse)
|
|
137
|
+
* and `not_yet_valid` (a wrong clock, or a manifest rotated in early) both reached the DKG
|
|
138
|
+
* with no event at all. `unreadable_window` matters more than it looks: since the startup gate
|
|
139
|
+
* was hardened it cannot start a daemon, but a manifest POLLED IN after startup can still put
|
|
140
|
+
* a running daemon into it.
|
|
141
|
+
*/
|
|
142
|
+
const lapsed = manifestValidity.state === "expired"
|
|
143
|
+
|| manifestValidity.state === "unreadable_window"
|
|
144
|
+
|| manifestValidity.state === "not_yet_valid";
|
|
145
|
+
if (lapsed) {
|
|
146
|
+
logger.warn("registration.manifest.lapsed", {
|
|
147
|
+
agent: name,
|
|
148
|
+
state: manifestValidity.state,
|
|
149
|
+
window: manifestValidity.state === "expired" ? manifestValidity.expires : manifestValidity.notBefore,
|
|
150
|
+
validators: currentManifest ? validatorNodes(currentManifest.nodes).length : 0,
|
|
151
|
+
/**
|
|
152
|
+
* ⚠️ THIS USED TO SAY "a share MAY BE DEALT to a node that is no longer authorized", and
|
|
153
|
+
* that over-claimed in the very case it named. Review traced the path: a validator removed
|
|
154
|
+
* since the lapse is either unreachable — dropped at the dial layer by the peerId
|
|
155
|
+
* cross-check against the signed manifest — or reachable but absent from the DIRECTORY's
|
|
156
|
+
* current manifest, in which case the roster/participants counts disagree and registration
|
|
157
|
+
* REFUSES with `dkg_below_threshold`. **Dealing a share to a de-authorized node is not
|
|
158
|
+
* reachable through this path.** The event was about to be emitted alongside a FAILED
|
|
159
|
+
* registration while telling the operator a share may have gone somewhere.
|
|
160
|
+
*
|
|
161
|
+
* What it says now is what is actually true, and it is still worth saying: this event is
|
|
162
|
+
* emitted immediately before that refusal, so it is the line that explains an otherwise
|
|
163
|
+
* bare `dkg_below_threshold` — which names an exit point and not a cause.
|
|
164
|
+
*/
|
|
165
|
+
/**
|
|
166
|
+
* ⚠️ ONE CAUSE OF A MULTI-CAUSE EXIT — pass 2, and the previous wording inverted the
|
|
167
|
+
* redundancy invariant in prose. `dkg_below_threshold` comes from a single comparison
|
|
168
|
+
* (`roster.length !== participants`) whose own comment names TWO causes: a node we reported
|
|
169
|
+
* is now unreachable, OR a manifest version skew. **An unreachable node is the routine
|
|
170
|
+
* one** — under the sovereign-node design a node being down is the expected steady state,
|
|
171
|
+
* not the exception. Saying "THIS is the cause" and "replace the trust anchor rather than
|
|
172
|
+
* retrying" told the operator to replace a threshold-signed anchor in the case where the
|
|
173
|
+
* correct move is to retry.
|
|
174
|
+
*/
|
|
175
|
+
impact: "the consortium roster this registration works from came from a manifest whose validity " +
|
|
176
|
+
"window is not currently open. This is ONE possible cause of a subsequent " +
|
|
177
|
+
"dkg_below_threshold — a directory node being momentarily unreachable is the more common " +
|
|
178
|
+
"one, and is expected rather than exceptional.",
|
|
179
|
+
guidance: "Registration was NOT blocked here — blocking it would strand a running daemon, since a " +
|
|
180
|
+
"restart without a replacement manifest does not come back. If it then fails with " +
|
|
181
|
+
"dkg_below_threshold: RETRY FIRST, because an unreachable node is the usual cause. " +
|
|
182
|
+
"Replace the trust anchor only if cello_status shows the manifest window is the " +
|
|
183
|
+
"discrepancy.",
|
|
184
|
+
});
|
|
185
|
+
}
|
|
110
186
|
const consortiumRoster = currentManifest
|
|
111
187
|
? await manifestNodesToEndpoints(validatorNodes(currentManifest.nodes), { logger })
|
|
112
188
|
: null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-handler.js","sourceRoot":"","sources":["../src/register-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"register-handler.js","sourceRoot":"","sources":["../src/register-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration-manager.d.ts","sourceRoot":"","sources":["../src/registration-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAExE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,yFAAyF;AACzF,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;gFAE4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,6BAA6B,GAAG,IAAI,CAAC;IAC3D,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C;;;;OAIG;IACH,OAAO,IAAI,SAAS,GAAG,IAAI,CAAC;IAC5B,cAAc,IAAI,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,oBAAoB,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE;;;;;;;;OAQG;IACH,sBAAsB,IAAI,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACtD,kBAAkB,IAAI,gBAAgB,GAAG,SAAS,CAAC;IACnD,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACnD,kBAAkB,IAAI,UAAU,GAAG,IAAI,CAAC;IACxC,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7C,yFAAyF;IACzF,oBAAoB,IAAI,OAAO,CAAC;IAChC,kFAAkF;IAClF,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACjF,yBAAyB,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAC5F,yBAAyB,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;CAC7F;AAED,qBAAa,mBAAmB;;gBAOlB,GAAG,EAAE,mBAAmB;IAMpC,oBAAoB,IAAI,iBAAiB,GAAG,IAAI;IAIhD,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAI3D,gBAAgB,IAAI,gBAAgB,GAAG,IAAI;IAI3C,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAgDzD;;;OAGG;IACG,QAAQ,CAAC,SAAS,GAAE,MAAW,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"registration-manager.d.ts","sourceRoot":"","sources":["../src/registration-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAExE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,yFAAyF;AACzF,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;gFAE4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,6BAA6B,GAAG,IAAI,CAAC;IAC3D,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C;;;;OAIG;IACH,OAAO,IAAI,SAAS,GAAG,IAAI,CAAC;IAC5B,cAAc,IAAI,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,oBAAoB,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE;;;;;;;;OAQG;IACH,sBAAsB,IAAI,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACtD,kBAAkB,IAAI,gBAAgB,GAAG,SAAS,CAAC;IACnD,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACnD,kBAAkB,IAAI,UAAU,GAAG,IAAI,CAAC;IACxC,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7C,yFAAyF;IACzF,oBAAoB,IAAI,OAAO,CAAC;IAChC,kFAAkF;IAClF,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACjF,yBAAyB,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAC5F,yBAAyB,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;CAC7F;AAED,qBAAa,mBAAmB;;gBAOlB,GAAG,EAAE,mBAAmB;IAMpC,oBAAoB,IAAI,iBAAiB,GAAG,IAAI;IAIhD,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAI3D,gBAAgB,IAAI,gBAAgB,GAAG,IAAI;IAI3C,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAgDzD;;;OAGG;IACG,QAAQ,CAAC,SAAS,GAAE,MAAW,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CA4T/H"}
|
|
@@ -177,7 +177,26 @@ export class RegistrationManager {
|
|
|
177
177
|
// stream-death window) — null-check before FROST DKG opens streams on it.
|
|
178
178
|
const dkgNode = this.#ctx.getNode();
|
|
179
179
|
if (!dkgNode) {
|
|
180
|
-
|
|
180
|
+
/**
|
|
181
|
+
* NAMES THE LOCAL STATE, not the network. This returned `directory_unreachable` — a network
|
|
182
|
+
* verdict for a purely local lifecycle fact, and the comment two lines above already says so:
|
|
183
|
+
* the daemon's own node reference is briefly null while a stream dies and is rebuilt. The
|
|
184
|
+
* directory may be perfectly reachable.
|
|
185
|
+
*
|
|
186
|
+
* Found by the `DOD-M15-SURFACE-1` review as `[pre-existing]`; fixed under the standing rule
|
|
187
|
+
* that an error naming the wrong subsystem gets corrected when it is found. It is also the
|
|
188
|
+
* exact shape M15 is closing elsewhere — one string sending an investigation at the network
|
|
189
|
+
* when the cause is local — so leaving it while fixing its siblings would be inconsistent.
|
|
190
|
+
*/
|
|
191
|
+
this.#ctx.logger.warn("registration.dkg.node_unavailable", {
|
|
192
|
+
impact: "the daemon's own transport node was momentarily absent while a signaling stream was rebuilt; registration was not attempted and nothing about the directory's reachability was established",
|
|
193
|
+
});
|
|
194
|
+
// `detail` is the shape this return type carries — the affordance rides there rather than in
|
|
195
|
+
// a `guidance` key the caller would drop on the floor.
|
|
196
|
+
return {
|
|
197
|
+
error: "transport_node_unavailable",
|
|
198
|
+
detail: "The daemon's transport node was briefly unavailable while its directory connection was rebuilding. This is local and usually clears within seconds; it says nothing about whether the directory is reachable. Retry registration, and if it repeats check the directory connection state with cello status.",
|
|
199
|
+
};
|
|
181
200
|
}
|
|
182
201
|
// DOD-DKG-1: build the directory-node set the DKG fans across. With a verified consortium
|
|
183
202
|
// manifest the client resolved the full N-node roster (getConsortiumEndpoints) and the DKG
|