@cello-protocol/daemon 0.0.135 → 0.0.137
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/close-session-handler.d.ts.map +1 -1
- package/dist/close-session-handler.js +18 -2
- package/dist/close-session-handler.js.map +1 -1
- package/dist/daemon.js +15 -0
- package/dist/daemon.js.map +1 -1
- package/dist/document-ack-inbound.js +18 -8
- package/dist/document-ack-inbound.js.map +1 -1
- package/dist/document-delivery.d.ts.map +1 -1
- package/dist/document-delivery.js +16 -2
- package/dist/document-delivery.js.map +1 -1
- package/dist/document-frame-router.d.ts.map +1 -1
- package/dist/document-frame-router.js +21 -0
- package/dist/document-frame-router.js.map +1 -1
- package/dist/document-gate.d.ts +10 -0
- package/dist/document-gate.d.ts.map +1 -1
- package/dist/document-gate.js.map +1 -1
- package/dist/document-handlers.d.ts.map +1 -1
- package/dist/document-handlers.js +69 -0
- package/dist/document-handlers.js.map +1 -1
- package/dist/document-inbound.d.ts +32 -8
- package/dist/document-inbound.d.ts.map +1 -1
- package/dist/document-inbound.js +112 -42
- package/dist/document-inbound.js.map +1 -1
- package/dist/document-layer.d.ts.map +1 -1
- package/dist/document-layer.js +12 -0
- package/dist/document-layer.js.map +1 -1
- package/dist/document-profile.d.ts +61 -0
- package/dist/document-profile.d.ts.map +1 -0
- package/dist/document-profile.js +112 -0
- package/dist/document-profile.js.map +1 -0
- package/dist/document-screen.d.ts +59 -0
- package/dist/document-screen.d.ts.map +1 -0
- package/dist/document-screen.js +148 -0
- package/dist/document-screen.js.map +1 -0
- package/dist/document-store.d.ts +5 -0
- package/dist/document-store.d.ts.map +1 -1
- package/dist/document-store.js +36 -0
- package/dist/document-store.js.map +1 -1
- package/dist/retry-queue.d.ts +27 -0
- package/dist/retry-queue.d.ts.map +1 -1
- package/dist/retry-queue.js +179 -0
- package/dist/retry-queue.js.map +1 -1
- package/dist/seal-flows.d.ts.map +1 -1
- package/dist/seal-flows.js +5 -2
- package/dist/seal-flows.js.map +1 -1
- package/dist/session-node-manager.d.ts +12 -0
- package/dist/session-node-manager.d.ts.map +1 -1
- package/dist/session-node-manager.js +76 -3
- package/dist/session-node-manager.js.map +1 -1
- package/dist/session-read-handlers.d.ts.map +1 -1
- package/dist/session-read-handlers.js +3 -1
- package/dist/session-read-handlers.js.map +1 -1
- package/package.json +5 -5
package/dist/document-inbound.js
CHANGED
|
@@ -9,16 +9,18 @@
|
|
|
9
9
|
* The order, and what each step is protecting:
|
|
10
10
|
*
|
|
11
11
|
* 1. DECODE — refuse malformed input before any of it is interpreted.
|
|
12
|
-
* 2.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* screening, over peer-controlled bytes; running them first means those
|
|
18
|
-
* rules process input from a party we have not authenticated. An
|
|
19
|
-
* unverified envelope is also not REJECTED — a rejection is a protocol act
|
|
12
|
+
* 2. VERIFY the signature — FIRST, because everything after it is either a judgement about a
|
|
13
|
+
* party or an ANSWER to one. It needs nothing but the envelope: the agent
|
|
14
|
+
* id is the Ed25519 public key (M14-D5). It ran at step 4 until a live
|
|
15
|
+
* defect forced it earlier — see `terminal` on InboundResult. An
|
|
16
|
+
* unverified envelope is also not REJECTED: a rejection is a protocol act
|
|
20
17
|
* that presumes an authenticated counterparty, and writing a 0x05 leaf
|
|
21
18
|
* naming an unauthenticated sender puts their claim in our permanent log.
|
|
19
|
+
* 3. KNOW the document — an envelope for a document we do not hold has no context to judge it in.
|
|
20
|
+
* TERMINAL: we will never hold it, so the sender is told and stops.
|
|
21
|
+
* 4. SENDER is the peer — a document is a pairwise agreement; a third party's envelope does not
|
|
22
|
+
* belong here at all, and is not a rejection case (there is no
|
|
23
|
+
* collaboration to supersede). Refused SILENTLY — see `terminal`.
|
|
22
24
|
* 5. CHAIN link — a redelivery is benign and must still ACK (delivery retries by design, and
|
|
23
25
|
* a redelivery that goes unacked never lets the sender settle it); a gap
|
|
24
26
|
* or a fork refuses.
|
|
@@ -76,24 +78,96 @@ export class DocumentInbound {
|
|
|
76
78
|
return { ok: false, reason: "document_inbound_malformed", detail };
|
|
77
79
|
}
|
|
78
80
|
const envelopeHash = documentEnvelopeHash(env);
|
|
79
|
-
// 2.
|
|
81
|
+
// 2. VERIFY the signature — BEFORE the document is even looked up.
|
|
82
|
+
//
|
|
83
|
+
// It used to run at step 4, after the lookup and the peer check, and the header's reasoning for
|
|
84
|
+
// that was sound as far as it went: verify before the GATE, so pluggable rules never process
|
|
85
|
+
// bytes from a party we have not authenticated. Verifying EARLIER satisfies that strictly more.
|
|
86
|
+
//
|
|
87
|
+
// What forced the move is `terminal` below. A terminal refusal is answered with a SIGNED ack
|
|
88
|
+
// addressed to `sender_agent_id`, and producing one for a sender we have not authenticated
|
|
89
|
+
// would answer whoever reached the channel rather than a known peer. Authentication has to
|
|
90
|
+
// precede the first refusal we are willing to answer, and `document_unknown` is now one.
|
|
91
|
+
//
|
|
92
|
+
// It needs nothing from the document: the agent id IS the Ed25519 public key (M14-D5), so this
|
|
93
|
+
// is self-contained on the envelope. The cost is an Ed25519 verify (~50µs) on envelopes for
|
|
94
|
+
// documents we do not hold — paid to avoid a delivery that never settles.
|
|
95
|
+
if (!this.#d.verifySignature(env.sender_agent_id, buildDocumentUpdateTbs(env), env.signature)) {
|
|
96
|
+
this.#d.logger.error("document.inbound.signature_invalid", {
|
|
97
|
+
documentId: env.document_id,
|
|
98
|
+
senderAgentId: env.sender_agent_id,
|
|
99
|
+
envelopeHash,
|
|
100
|
+
correlationId,
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
ok: false,
|
|
104
|
+
reason: "document_signature_invalid",
|
|
105
|
+
detail: `the envelope claims to come from ${env.sender_agent_id} but its signature does not ` +
|
|
106
|
+
`verify against that agent — nothing was recorded`,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// 3. KNOW the document.
|
|
80
110
|
const doc = this.#d.store.getDocument(ownerAgentId, env.document_id);
|
|
81
111
|
if (!doc) {
|
|
112
|
+
// TERMINAL. We hold no such document and never will — this is what the far side of a REFUSED
|
|
113
|
+
// proposal looks like, and it was leaving the sender redelivering forever: the router only
|
|
114
|
+
// acks `ok: true` results, so an `ok: false` refusal settled nothing and the delivery worker
|
|
115
|
+
// re-sent on every tick. Observed live on `662743b1…`, stuck at `pendingSent: 1`.
|
|
116
|
+
//
|
|
117
|
+
// Safe to answer because step 2 authenticated the sender, and it discloses nothing they do
|
|
118
|
+
// not already have: they authored an envelope for this document_id, and the answer is "no".
|
|
82
119
|
return {
|
|
83
120
|
ok: false,
|
|
84
121
|
reason: "document_unknown",
|
|
122
|
+
terminal: true,
|
|
123
|
+
envelopeHash,
|
|
85
124
|
detail: `no document ${env.document_id.slice(0, 16)}… for this agent`,
|
|
86
125
|
};
|
|
87
126
|
}
|
|
88
|
-
//
|
|
127
|
+
// 4. The sender must be THIS document's peer — BEFORE any lifecycle answer.
|
|
128
|
+
//
|
|
129
|
+
// The order here is the disclosure boundary, and it was wrong. This check used to run AFTER the
|
|
130
|
+
// killed/closed branch, and once that branch became terminal it meant a non-party who signed an
|
|
131
|
+
// envelope naming an existing document received a SIGNED ACK confirming the document exists and
|
|
132
|
+
// what lifecycle state it is in — `sendAck` addresses `env.sender_agent_id` from the envelope,
|
|
133
|
+
// not `doc.peerAgentId`, so it really does go back to the stranger. That is exactly the
|
|
134
|
+
// disclosure the silent refusal below is written to withhold.
|
|
135
|
+
if (env.sender_agent_id !== doc.peerAgentId) {
|
|
136
|
+
this.#d.logger.warn("document.inbound.not_peer", {
|
|
137
|
+
documentId: env.document_id,
|
|
138
|
+
senderAgentId: env.sender_agent_id,
|
|
139
|
+
peerAgentId: doc.peerAgentId,
|
|
140
|
+
correlationId,
|
|
141
|
+
});
|
|
142
|
+
return {
|
|
143
|
+
ok: false,
|
|
144
|
+
reason: "document_sender_not_peer",
|
|
145
|
+
// The peer's identity is NOT in the reply, and there is NO ack — silence is the answer. A
|
|
146
|
+
// third party is authenticated as themselves but is not a party to this document, so
|
|
147
|
+
// nothing about it is theirs to learn.
|
|
148
|
+
//
|
|
149
|
+
// A residual one-bit oracle remains and is accepted deliberately: a prober who already
|
|
150
|
+
// holds a valid document_id learns "exists" from the ABSENCE of an ack, since an unknown
|
|
151
|
+
// document answers and a known one does not. Closing that would mean acking non-parties,
|
|
152
|
+
// which discloses strictly more. It is bounded by document_id being a 32-byte hash
|
|
153
|
+
// (`documentIdFromProposal`), unguessable and never published.
|
|
154
|
+
detail: "you are not a party to this document",
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// 5. The document must still ACCEPT. `acceptsUpdates` exists for exactly this and carries a
|
|
89
158
|
// comment describing the bug it was written to fix — "after a restart the document row said
|
|
90
159
|
// `stalled` while the daemon happily accepted updates on it". The only inbound path in the
|
|
91
160
|
// codebase was reintroducing it, and a killed document is defined by LIFECYCLE-1 as one that
|
|
92
161
|
// stops accepting.
|
|
93
162
|
if (doc.status === "killed" || doc.status === "closed") {
|
|
163
|
+
// TERMINAL, and for the same reason `document_stalled` below is NOT: these are DECISIONS.
|
|
164
|
+
// Nothing the sender does makes a killed or closed document accept this envelope, so leaving
|
|
165
|
+
// their delivery outstanding buys nothing and costs a redelivery per tick, forever.
|
|
94
166
|
return {
|
|
95
167
|
ok: false,
|
|
96
168
|
reason: doc.status === "killed" ? "document_killed" : "document_closed",
|
|
169
|
+
terminal: true,
|
|
170
|
+
envelopeHash,
|
|
97
171
|
detail: doc.status === "killed"
|
|
98
172
|
? "this document was ended locally and no longer accepts updates"
|
|
99
173
|
: "this document was closed by agreement and no longer accepts updates",
|
|
@@ -106,38 +180,6 @@ export class DocumentInbound {
|
|
|
106
180
|
// been frozen for days.
|
|
107
181
|
return { ok: false, reason: accepts.reason, detail: accepts.detail };
|
|
108
182
|
}
|
|
109
|
-
// 3. The sender must be THIS document's peer.
|
|
110
|
-
if (env.sender_agent_id !== doc.peerAgentId) {
|
|
111
|
-
this.#d.logger.warn("document.inbound.not_peer", {
|
|
112
|
-
documentId: env.document_id,
|
|
113
|
-
senderAgentId: env.sender_agent_id,
|
|
114
|
-
peerAgentId: doc.peerAgentId,
|
|
115
|
-
correlationId,
|
|
116
|
-
});
|
|
117
|
-
return {
|
|
118
|
-
ok: false,
|
|
119
|
-
reason: "document_sender_not_peer",
|
|
120
|
-
// The peer's identity is NOT in the reply. This sender has not authenticated, and anyone
|
|
121
|
-
// reaching the channel with a guessed or leaked document_id would otherwise learn who the
|
|
122
|
-
// owner collaborates with. The full detail is in the warn above, where it belongs.
|
|
123
|
-
detail: "you are not a party to this document",
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
// 4. VERIFY, before the gate. See the header.
|
|
127
|
-
if (!this.#d.verifySignature(env.sender_agent_id, buildDocumentUpdateTbs(env), env.signature)) {
|
|
128
|
-
this.#d.logger.error("document.inbound.signature_invalid", {
|
|
129
|
-
documentId: env.document_id,
|
|
130
|
-
senderAgentId: env.sender_agent_id,
|
|
131
|
-
envelopeHash,
|
|
132
|
-
correlationId,
|
|
133
|
-
});
|
|
134
|
-
return {
|
|
135
|
-
ok: false,
|
|
136
|
-
reason: "document_signature_invalid",
|
|
137
|
-
detail: `the envelope claims to come from ${env.sender_agent_id} but its signature does not ` +
|
|
138
|
-
`verify against that agent — nothing was recorded`,
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
183
|
// 5. CHAIN. A redelivery is expected traffic and must still be answered.
|
|
142
184
|
// Hash-only. Reading the whole log meant materializing every payload BLOB on every inbound
|
|
143
185
|
// update, just to build a set for one membership test.
|
|
@@ -153,12 +195,36 @@ export class DocumentInbound {
|
|
|
153
195
|
documentId: env.document_id,
|
|
154
196
|
correlationId,
|
|
155
197
|
detail,
|
|
198
|
+
// THE COMPARISON ITSELF, not just its verdict.
|
|
199
|
+
//
|
|
200
|
+
// The stall path was chased through three fixes on the strength of "the chain was refused",
|
|
201
|
+
// and each fix was reasoned about rather than measured. What was never printed is the only
|
|
202
|
+
// thing that decides it: the link the sender claimed, the head we were holding, and whether
|
|
203
|
+
// we had seen it before. A refusal that names its verdict and hides its inputs is why that
|
|
204
|
+
// took three rounds — the same shape as reading a log tail for an event that is emitted
|
|
205
|
+
// earlier, twice today.
|
|
206
|
+
claimedPrev: env.doc_prev_hash,
|
|
207
|
+
ourHead: head,
|
|
208
|
+
prevIsKnown: env.doc_prev_hash !== null && known.has(env.doc_prev_hash),
|
|
209
|
+
knownCount: known.size,
|
|
156
210
|
});
|
|
157
211
|
// MATCHED against the known set, not split on ":". This file explains sixty lines earlier why
|
|
158
212
|
// splitting an upstream message produces reason codes made of English prose — and the old
|
|
159
213
|
// `?? "document_chain_broken"` fallback mislabelled a FORK as a gap, which is precisely the
|
|
160
214
|
// distinction the envelope module went out of its way to create.
|
|
161
215
|
const reason = ["document_chain_forked", "document_chain_broken"].find((r) => detail.startsWith(r));
|
|
216
|
+
// A FORK IS TERMINAL; A GAP IS NOT. The distinction the envelope module went out of its way
|
|
217
|
+
// to create decides this too. A gap means the predecessor has not arrived YET, so redelivery
|
|
218
|
+
// is exactly the recovery path and the sender must keep trying. A fork means the sender
|
|
219
|
+
// chained onto something that is not our head and never was — our log is append-only, so
|
|
220
|
+
// there is no repair, and no number of redeliveries changes the answer.
|
|
221
|
+
//
|
|
222
|
+
// Left non-terminal, a fork walked to the unacked ceiling and surfaced as "Their client may
|
|
223
|
+
// not support shared documents yet" — an error naming the wrong subsystem entirely, for a
|
|
224
|
+
// condition the receiver had diagnosed precisely.
|
|
225
|
+
if (reason === "document_chain_forked") {
|
|
226
|
+
return { ok: false, reason, detail, terminal: true, envelopeHash };
|
|
227
|
+
}
|
|
162
228
|
return { ok: false, reason: reason ?? "document_chain_refused", detail };
|
|
163
229
|
}
|
|
164
230
|
if (duplicate) {
|
|
@@ -222,6 +288,10 @@ export class DocumentInbound {
|
|
|
222
288
|
// Taking it from an option meant a document configured append-only was unprotected unless
|
|
223
289
|
// every future call site remembered to pass the flag.
|
|
224
290
|
appendOnly: appendOnly(doc),
|
|
291
|
+
// The AGREED profile, from the same persisted row and for the same reason.
|
|
292
|
+
...(typeof doc.properties.content_profile === "string"
|
|
293
|
+
? { contentProfile: doc.properties.content_profile }
|
|
294
|
+
: {}),
|
|
225
295
|
}, nowMs);
|
|
226
296
|
if (!verdict.admit) {
|
|
227
297
|
// 7a. REJECT. The bytes are held, a 0x05 leaf references them, and the peer is ANSWERED —
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-inbound.js","sourceRoot":"","sources":["../src/document-inbound.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"document-inbound.js","sourceRoot":"","sources":["../src/document-inbound.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-layer.d.ts","sourceRoot":"","sources":["../src/document-layer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"document-layer.d.ts","sourceRoot":"","sources":["../src/document-layer.ts"],"names":[],"mappings":"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"}
|
package/dist/document-layer.js
CHANGED
|
@@ -25,6 +25,7 @@ import { verify } from "@cello-protocol/crypto";
|
|
|
25
25
|
import { DocumentStore } from "./document-store.js";
|
|
26
26
|
import { DocumentEngine } from "./document-engine.js";
|
|
27
27
|
import { DocumentGate } from "./document-gate.js";
|
|
28
|
+
import { screeningRule, SCREEN_RULE_ID } from "./document-screen.js";
|
|
28
29
|
import { DocumentRejections } from "./document-rejection.js";
|
|
29
30
|
import { DocumentInbound } from "./document-inbound.js";
|
|
30
31
|
import { DocumentAckInbound } from "./document-ack-inbound.js";
|
|
@@ -57,6 +58,17 @@ export function createDocumentLayer(deps) {
|
|
|
57
58
|
const store = new DocumentStore(db, logger);
|
|
58
59
|
const engine = new DocumentEngine(logger);
|
|
59
60
|
const gate = new DocumentGate(engine, {}, logger);
|
|
61
|
+
// DOD-DOC-SCREEN-1 — REGISTERED, not merely written.
|
|
62
|
+
//
|
|
63
|
+
// The gate has carried a comment saying this rule plugs in here since the gate was built, and the
|
|
64
|
+
// rule not existing was the whole gap: document content reached the CRDT with no content gate at
|
|
65
|
+
// all, because the message sanitizer is deliberately kept off this path (it REWRITES, and
|
|
66
|
+
// rewriting a replica is permanent divergence).
|
|
67
|
+
//
|
|
68
|
+
// Registered at construction rather than by a caller, for the reason this milestone learned four
|
|
69
|
+
// separate times — a unit with no caller reads exactly like a working one. If this line is
|
|
70
|
+
// deleted the screening tests still pass, so `document-surface-e2e` asserts a refusal end to end.
|
|
71
|
+
gate.addRule(SCREEN_RULE_ID, screeningRule);
|
|
60
72
|
const rejections = new DocumentRejections(store, logger);
|
|
61
73
|
// Epoch zero comes from the stored PROPOSAL, not from the envelope log — see `LiveDocuments.get`.
|
|
62
74
|
// Declared before `handshake` exists, so it is resolved lazily; a rebuild only ever happens long
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-layer.js","sourceRoot":"","sources":["../src/document-layer.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"document-layer.js","sourceRoot":"","sources":["../src/document-layer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOD-DOC-PROFILE-1 — the content profile: an ALLOWLIST, agreed at the handshake.
|
|
3
|
+
*
|
|
4
|
+
* ── WHY AN ALLOWLIST WHEN A DENYLIST ALREADY EXISTS ───────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* `document-screen.ts` is the denylist: it argues about characters, one at a time, in an open-ended
|
|
7
|
+
* space, and every argument happens mid-document with whoever is working ambushed by it. A profile
|
|
8
|
+
* inverts that. Only this character space is permitted, so violations are unambiguous — and the
|
|
9
|
+
* decision moves to CONSENT, which is the real win. "Do I want a Devanagari document with this
|
|
10
|
+
* person" is a question an operator can answer once, with a human already engaged, about the whole
|
|
11
|
+
* document. "What is U+200D doing at offset 412" is not a question anyone can answer.
|
|
12
|
+
*
|
|
13
|
+
* ── THE THREE CONSTRAINTS ─────────────────────────────────────────────────────────────────────
|
|
14
|
+
*
|
|
15
|
+
* NAMED AND CLOSED. A free-form profile is a negotiation again, and named profiles are what let
|
|
16
|
+
* an operator hold a standing policy — "never auto-accept `unicode-text` from an unendorsed
|
|
17
|
+
* contact". A sixth name is a protocol decision, not a caller's choice.
|
|
18
|
+
*
|
|
19
|
+
* CODEPOINT SETS, NOT ADJECTIVES. A profile enforced by a heuristic is a promise we do not keep,
|
|
20
|
+
* and "looks like markdown" is a heuristic. Every profile below is a predicate over code points.
|
|
21
|
+
*
|
|
22
|
+
* ENFORCED IN BOTH PLACES, for different reasons (§16.7-14). At authoring, so a stray character
|
|
23
|
+
* is caught where it was written and never becomes a rejection round — that is ERGONOMICS. At
|
|
24
|
+
* receipt, because the sender's enforcement is unverifiable — that is SECURITY. The second is not
|
|
25
|
+
* redundant with the first: a sender's client can be patched, or simply compromised while the
|
|
26
|
+
* sender themselves is a good actor.
|
|
27
|
+
*
|
|
28
|
+
* ── NARROWING ONLY ────────────────────────────────────────────────────────────────────────────
|
|
29
|
+
*
|
|
30
|
+
* Every profile, including the widest, still refuses what `document-screen.ts` refuses. A profile
|
|
31
|
+
* may only narrow the space, never widen it — otherwise choosing `unicode-text` would be a way to
|
|
32
|
+
* opt OUT of screening, and a peer could ask for that at consent time in the same breath as asking
|
|
33
|
+
* for Japanese.
|
|
34
|
+
*/
|
|
35
|
+
/** A violation, in the same machine-readable shape every refusal on this path uses. */
|
|
36
|
+
export interface ProfileViolation {
|
|
37
|
+
profile: string;
|
|
38
|
+
codepoints: string[];
|
|
39
|
+
count: number;
|
|
40
|
+
offsets: number[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The closed set. Each value answers one question: may this code point appear?
|
|
44
|
+
*
|
|
45
|
+
* `ascii-markdown` and `ascii-text` are the same space today — markdown's syntax is printable ASCII.
|
|
46
|
+
* They are kept distinct because the NAME is what an operator consents to and what a future diff
|
|
47
|
+
* renderer keys on, and collapsing them would make "this is a markdown document" unstateable.
|
|
48
|
+
*/
|
|
49
|
+
export declare const CONTENT_PROFILES: Record<string, (cp: number) => boolean>;
|
|
50
|
+
export declare function isKnownProfile(name: string | undefined): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Check text against a profile. Null admits.
|
|
53
|
+
*
|
|
54
|
+
* AN UNKNOWN OR ABSENT PROFILE ENFORCES NOTHING, and this is the one fail-open on the document
|
|
55
|
+
* path. A document agreed before profiles existed carries none, and refusing all of its updates
|
|
56
|
+
* would break a working document to enforce a rule its two parties never agreed to. The screening
|
|
57
|
+
* denylist still applies to it — that is the floor, and it is why failing open here is bounded
|
|
58
|
+
* rather than a hole.
|
|
59
|
+
*/
|
|
60
|
+
export declare function profileViolation(profile: string | undefined, text: string): ProfileViolation | null;
|
|
61
|
+
//# sourceMappingURL=document-profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-profile.d.ts","sourceRoot":"","sources":["../src/document-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,uFAAuF;AACvF,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AA0BD;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAYpE,CAAC;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEhE;AAMD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,IAAI,EAAE,MAAM,GACX,gBAAgB,GAAG,IAAI,CAoBzB"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOD-DOC-PROFILE-1 — the content profile: an ALLOWLIST, agreed at the handshake.
|
|
3
|
+
*
|
|
4
|
+
* ── WHY AN ALLOWLIST WHEN A DENYLIST ALREADY EXISTS ───────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* `document-screen.ts` is the denylist: it argues about characters, one at a time, in an open-ended
|
|
7
|
+
* space, and every argument happens mid-document with whoever is working ambushed by it. A profile
|
|
8
|
+
* inverts that. Only this character space is permitted, so violations are unambiguous — and the
|
|
9
|
+
* decision moves to CONSENT, which is the real win. "Do I want a Devanagari document with this
|
|
10
|
+
* person" is a question an operator can answer once, with a human already engaged, about the whole
|
|
11
|
+
* document. "What is U+200D doing at offset 412" is not a question anyone can answer.
|
|
12
|
+
*
|
|
13
|
+
* ── THE THREE CONSTRAINTS ─────────────────────────────────────────────────────────────────────
|
|
14
|
+
*
|
|
15
|
+
* NAMED AND CLOSED. A free-form profile is a negotiation again, and named profiles are what let
|
|
16
|
+
* an operator hold a standing policy — "never auto-accept `unicode-text` from an unendorsed
|
|
17
|
+
* contact". A sixth name is a protocol decision, not a caller's choice.
|
|
18
|
+
*
|
|
19
|
+
* CODEPOINT SETS, NOT ADJECTIVES. A profile enforced by a heuristic is a promise we do not keep,
|
|
20
|
+
* and "looks like markdown" is a heuristic. Every profile below is a predicate over code points.
|
|
21
|
+
*
|
|
22
|
+
* ENFORCED IN BOTH PLACES, for different reasons (§16.7-14). At authoring, so a stray character
|
|
23
|
+
* is caught where it was written and never becomes a rejection round — that is ERGONOMICS. At
|
|
24
|
+
* receipt, because the sender's enforcement is unverifiable — that is SECURITY. The second is not
|
|
25
|
+
* redundant with the first: a sender's client can be patched, or simply compromised while the
|
|
26
|
+
* sender themselves is a good actor.
|
|
27
|
+
*
|
|
28
|
+
* ── NARROWING ONLY ────────────────────────────────────────────────────────────────────────────
|
|
29
|
+
*
|
|
30
|
+
* Every profile, including the widest, still refuses what `document-screen.ts` refuses. A profile
|
|
31
|
+
* may only narrow the space, never widen it — otherwise choosing `unicode-text` would be a way to
|
|
32
|
+
* opt OUT of screening, and a peer could ask for that at consent time in the same breath as asking
|
|
33
|
+
* for Japanese.
|
|
34
|
+
*/
|
|
35
|
+
/** Shape of text, in every profile: the two characters that are structure rather than content. */
|
|
36
|
+
const TAB = 0x09;
|
|
37
|
+
const NEWLINE = 0x0a;
|
|
38
|
+
const CARRIAGE_RETURN = 0x0d;
|
|
39
|
+
/**
|
|
40
|
+
* Refused by EVERY profile — the floor `document-screen.ts` sets, restated here so a profile cannot
|
|
41
|
+
* be used to bypass it. Kept as its own set rather than imported so the two can be read
|
|
42
|
+
* independently: this one is "no profile may admit these", which is a different claim from "the
|
|
43
|
+
* default rules refuse these".
|
|
44
|
+
*/
|
|
45
|
+
const NEVER = new Set([
|
|
46
|
+
0x200b, 0x202a, 0x202b, 0x202c, 0x202d, 0x202e, 0x2066, 0x2067, 0x2068, 0x2069,
|
|
47
|
+
]);
|
|
48
|
+
function isShapingChar(cp) {
|
|
49
|
+
return cp === TAB || cp === NEWLINE || cp === CARRIAGE_RETURN;
|
|
50
|
+
}
|
|
51
|
+
/** Printable ASCII. Control characters are not content — they address whatever renders them. */
|
|
52
|
+
function isPrintableAscii(cp) {
|
|
53
|
+
return cp >= 0x20 && cp <= 0x7e;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The closed set. Each value answers one question: may this code point appear?
|
|
57
|
+
*
|
|
58
|
+
* `ascii-markdown` and `ascii-text` are the same space today — markdown's syntax is printable ASCII.
|
|
59
|
+
* They are kept distinct because the NAME is what an operator consents to and what a future diff
|
|
60
|
+
* renderer keys on, and collapsing them would make "this is a markdown document" unstateable.
|
|
61
|
+
*/
|
|
62
|
+
export const CONTENT_PROFILES = {
|
|
63
|
+
"ascii-text": (cp) => isShapingChar(cp) || isPrintableAscii(cp),
|
|
64
|
+
"ascii-markdown": (cp) => isShapingChar(cp) || isPrintableAscii(cp),
|
|
65
|
+
// JSON is ASCII-only BY DESIGN: `é` is how JSON carries `é`. Admitting the raw character too
|
|
66
|
+
// would mean two documents that parse identically have different bytes, and a CRDT replica's
|
|
67
|
+
// whole claim is that they do not.
|
|
68
|
+
json: (cp) => isShapingChar(cp) || isPrintableAscii(cp),
|
|
69
|
+
// The wide profiles admit anything that is not explicitly refused — including every sample the
|
|
70
|
+
// sanitizer audit destroyed. A profile that refused Devanagari orthography or a family emoji
|
|
71
|
+
// would be that same failure wearing a different name.
|
|
72
|
+
"unicode-text": (cp) => !NEVER.has(cp),
|
|
73
|
+
"unicode-markdown": (cp) => !NEVER.has(cp),
|
|
74
|
+
};
|
|
75
|
+
export function isKnownProfile(name) {
|
|
76
|
+
return typeof name === "string" && Object.hasOwn(CONTENT_PROFILES, name);
|
|
77
|
+
}
|
|
78
|
+
function formatCodepoint(cp) {
|
|
79
|
+
return `U+${cp.toString(16).toUpperCase().padStart(4, "0")}`;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check text against a profile. Null admits.
|
|
83
|
+
*
|
|
84
|
+
* AN UNKNOWN OR ABSENT PROFILE ENFORCES NOTHING, and this is the one fail-open on the document
|
|
85
|
+
* path. A document agreed before profiles existed carries none, and refusing all of its updates
|
|
86
|
+
* would break a working document to enforce a rule its two parties never agreed to. The screening
|
|
87
|
+
* denylist still applies to it — that is the floor, and it is why failing open here is bounded
|
|
88
|
+
* rather than a hole.
|
|
89
|
+
*/
|
|
90
|
+
export function profileViolation(profile, text) {
|
|
91
|
+
if (!isKnownProfile(profile))
|
|
92
|
+
return null;
|
|
93
|
+
const allows = CONTENT_PROFILES[profile];
|
|
94
|
+
const codepoints = new Set();
|
|
95
|
+
const offsets = [];
|
|
96
|
+
let index = 0;
|
|
97
|
+
for (const ch of text) {
|
|
98
|
+
const cp = ch.codePointAt(0);
|
|
99
|
+
if (!allows(cp) || NEVER.has(cp)) {
|
|
100
|
+
codepoints.add(formatCodepoint(cp));
|
|
101
|
+
offsets.push(index);
|
|
102
|
+
}
|
|
103
|
+
// CODE POINTS, not UTF-16 units — the offsets exist for a human or an agent to find the
|
|
104
|
+
// character in their own editor, and one that lands mid-surrogate in a document containing an
|
|
105
|
+
// emoji is worse than none.
|
|
106
|
+
index++;
|
|
107
|
+
}
|
|
108
|
+
if (codepoints.size === 0)
|
|
109
|
+
return null;
|
|
110
|
+
return { profile: profile, codepoints: [...codepoints], count: offsets.length, offsets };
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=document-profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-profile.js","sourceRoot":"","sources":["../src/document-profile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOD-DOC-SCREEN-1 — the document content gate: REFUSE, never mutate.
|
|
3
|
+
*
|
|
4
|
+
* ── WHY A DOCUMENT DOES NOT GET THE MESSAGE SANITIZER ─────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* The inbound message path may REWRITE content on a `redact` verdict: the operator sees a sanitized
|
|
7
|
+
* form while the leaf still binds the original. That is right for conversation and catastrophic for
|
|
8
|
+
* a document. Measured on 2026-08-05 against eighteen realistic samples, six were silently altered:
|
|
9
|
+
*
|
|
10
|
+
* कर्म → कर्म a different Hindi word; the ZWJ is orthography in Devanagari
|
|
11
|
+
* 👨👩👧 → 👨👩👧 one family emoji becomes three separate people
|
|
12
|
+
* Hello → Hello full-width is how CJK users type
|
|
13
|
+
* file is ½ → file is 1⁄2 ligatures and fractions normalised away
|
|
14
|
+
* <|im_start|> → ␠ a document ABOUT prompt formats loses its subject
|
|
15
|
+
*
|
|
16
|
+
* For a CRDT replica that is not a false positive. It is permanent divergence: the receiver applies
|
|
17
|
+
* different bytes than the sender signed, both sides believe they converged, and nothing reports
|
|
18
|
+
* it. And screening the PROJECTION instead does not help — documents are read-WRITE, so the next
|
|
19
|
+
* write-back diffs the operator's screened file against their replica and publishes the redaction
|
|
20
|
+
* as a real, signed edit that deletes the peer's content.
|
|
21
|
+
*
|
|
22
|
+
* So this rule has exactly two outcomes: carry the text exactly, or refuse the envelope. There is
|
|
23
|
+
* no third return value, and that is deliberate — a rule that COULD return replacement text would
|
|
24
|
+
* eventually be used to.
|
|
25
|
+
*
|
|
26
|
+
* ── WHAT IT REFUSES, AND WHY THAT LIST IS SHORT ───────────────────────────────────────────────
|
|
27
|
+
*
|
|
28
|
+
* Only characters whose presence changes what the text MEANS to a reader or a model, independent of
|
|
29
|
+
* language:
|
|
30
|
+
*
|
|
31
|
+
* - BIDI overrides and isolates, which make what an operator reads differ from what the document
|
|
32
|
+
* says. In a shared document that is a signature on content the signer did not see.
|
|
33
|
+
* - Chat-template control markers, which are not content in any document — they are an attempt to
|
|
34
|
+
* address the reader's model rather than the reader.
|
|
35
|
+
*
|
|
36
|
+
* NOT on the list: zero-width joiners, full-width forms, ligatures, typographic punctuation,
|
|
37
|
+
* combining marks. Every one of those is legitimate text in some language, and refusing them would
|
|
38
|
+
* make CELLO unusable for the operators most likely to need it. Zero-width SPACE is refused —
|
|
39
|
+
* it joins nothing, and its only use in a document is to hide a boundary.
|
|
40
|
+
*
|
|
41
|
+
* This is the denylist half. `DOD-DOC-PROFILE-1` adds the allowlist: a codepoint set agreed at the
|
|
42
|
+
* handshake and bound into `document_id`, which is a stronger instrument because it is decided at
|
|
43
|
+
* consent rather than argued at the boundary. This rule stays underneath it — a profile a peer
|
|
44
|
+
* never agreed to cannot be used to smuggle a BIDI override.
|
|
45
|
+
*/
|
|
46
|
+
import type { GateRule } from "./document-gate.js";
|
|
47
|
+
/** Named so a refusal can say which rule fired without the sender parsing prose (§16.7-6). */
|
|
48
|
+
export declare const SCREEN_RULE_ID = "document_content_screen";
|
|
49
|
+
/** Named separately so a refusal says whether the AGREED profile or the default floor refused. */
|
|
50
|
+
export declare const PROFILE_RULE_ID = "document_content_profile";
|
|
51
|
+
/**
|
|
52
|
+
* The rule. Null admits; anything else refuses.
|
|
53
|
+
*
|
|
54
|
+
* Offsets are in CODE POINTS, not UTF-16 units, because they exist for a human or an agent to find
|
|
55
|
+
* the character in their own editor — and an offset that lands mid-surrogate in a document with an
|
|
56
|
+
* emoji in it is worse than none.
|
|
57
|
+
*/
|
|
58
|
+
export declare const screeningRule: GateRule;
|
|
59
|
+
//# sourceMappingURL=document-screen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-screen.d.ts","sourceRoot":"","sources":["../src/document-screen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAA8B,MAAM,oBAAoB,CAAC;AAG/E,8FAA8F;AAC9F,eAAO,MAAM,cAAc,4BAA4B,CAAC;AAExD,kGAAkG;AAClG,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAqC1D;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAAE,QA6D3B,CAAC"}
|