@cello-protocol/daemon 0.0.45 → 0.0.47
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-settings-keys.d.ts +52 -0
- package/dist/agent-settings-keys.d.ts.map +1 -0
- package/dist/agent-settings-keys.js +96 -0
- package/dist/agent-settings-keys.js.map +1 -0
- package/dist/contacts-tier-migration.d.ts +90 -0
- package/dist/contacts-tier-migration.d.ts.map +1 -0
- package/dist/contacts-tier-migration.js +149 -0
- package/dist/contacts-tier-migration.js.map +1 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +236 -20
- package/dist/daemon.js.map +1 -1
- package/dist/session-node-manager.d.ts +126 -14
- package/dist/session-node-manager.d.ts.map +1 -1
- package/dist/session-node-manager.js +377 -36
- package/dist/session-node-manager.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CELLO Daemon — the agent_settings key namespace (DOD-SETTINGS-1).
|
|
3
|
+
*
|
|
4
|
+
* A single source for every valid per-agent reachability-policy setting key, so the handler (which
|
|
5
|
+
* REFUSES an unknown key) and the consumers (TIER-BOUNDS-SETTINGS reads the bound overrides,
|
|
6
|
+
* AWAY-TIER-1 reads the away texts) can never drift. Keys are lower-snake, dotted namespaces:
|
|
7
|
+
*
|
|
8
|
+
* bounds.<tier>.max_sessions bounds.<tier>.max_bytes — per-tier bound overrides
|
|
9
|
+
* away.default — the agent's default away text
|
|
10
|
+
* away.tier.<tier> — a per-tier away text
|
|
11
|
+
*
|
|
12
|
+
* `<tier>` is a tier NAME (not the integer), for legibility in the store. BLOCKED is deliberately NOT
|
|
13
|
+
* settable — 0/0 is fixed (you cannot "raise" a block), and it has no away text (a blocked sender is
|
|
14
|
+
* refused before any reply). So the settable tiers are unknown / known / whitelisted / vip.
|
|
15
|
+
*/
|
|
16
|
+
/** The tiers whose bounds and away texts are settable (BLOCKED is fixed, never overridable). */
|
|
17
|
+
export declare const SETTABLE_TIER_NAMES: readonly ["unknown", "known", "whitelisted", "vip"];
|
|
18
|
+
export type SettableTierName = (typeof SETTABLE_TIER_NAMES)[number];
|
|
19
|
+
/** The tier NAME for a tier integer, or null for an unknown/unsettable value (e.g. BLOCKED=0).
|
|
20
|
+
* Keyed off the TIER constants (review F3) so a renumbering in contacts-tier-migration can never
|
|
21
|
+
* silently desync the settings namespace from the grid. */
|
|
22
|
+
export declare function settableTierName(tier: number): SettableTierName | null;
|
|
23
|
+
export type BoundField = "max_sessions" | "max_bytes";
|
|
24
|
+
/** The setting key for a per-tier bound override. */
|
|
25
|
+
export declare function boundSettingKey(tier: SettableTierName, field: BoundField): string;
|
|
26
|
+
/** The setting key for a per-tier away text. */
|
|
27
|
+
export declare function awayTierSettingKey(tier: SettableTierName): string;
|
|
28
|
+
/** The setting key for the agent's default away text (the fallback below any per-tier text). */
|
|
29
|
+
export declare const AWAY_DEFAULT_KEY = "away.default";
|
|
30
|
+
/** True iff `key` is a known, settable reachability-policy key. An unknown key is REFUSED by the
|
|
31
|
+
* handler (never silently stored — a typo'd key that persisted would be a setting that never takes
|
|
32
|
+
* effect, invisible to the operator). */
|
|
33
|
+
export declare function isValidSettingKey(key: string): boolean;
|
|
34
|
+
/** The full list of valid keys (for surfacing in a settings-list / help). */
|
|
35
|
+
export declare function allSettingKeys(): string[];
|
|
36
|
+
/** True iff the key is a per-tier BOUND override (its value must be a positive integer). */
|
|
37
|
+
export declare function isBoundKey(key: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Validate a setting's VALUE for its key (DOD-TIER-BOUNDS-SETTINGS AC2). A bound override may only be
|
|
40
|
+
* a FINITE POSITIVE INTEGER — INV-TIER-BOUND: a setting can RAISE or lower a bound within finite
|
|
41
|
+
* limits, never REMOVE one. So `Infinity`, negatives, zero, non-integers, and non-numeric strings are
|
|
42
|
+
* refused (an unbounded tier is exactly what the grid forbids). Away-text values are free-form strings.
|
|
43
|
+
*/
|
|
44
|
+
export declare function validateSettingValue(key: string, value: string): {
|
|
45
|
+
ok: true;
|
|
46
|
+
} | {
|
|
47
|
+
ok: false;
|
|
48
|
+
reason: string;
|
|
49
|
+
};
|
|
50
|
+
/** Max length of an away message (per-contact or per-tier/agent-default) — an answering-machine line. */
|
|
51
|
+
export declare const AWAY_MESSAGE_MAX_LEN = 2048;
|
|
52
|
+
//# sourceMappingURL=agent-settings-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-settings-keys.d.ts","sourceRoot":"","sources":["../src/agent-settings-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,gGAAgG;AAChG,eAAO,MAAM,mBAAmB,qDAAqE,CAAC;AACtG,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE;;4DAE4D;AAC5D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAQtE;AAED,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,WAAW,CAAC;AAEtD,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CAEjF;AAED,gDAAgD;AAChD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAEjE;AAED,gGAAgG;AAChG,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAa/C;;0CAE0C;AAC1C,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC;AAED,4FAA4F;AAC5F,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAuB7G;AAED,yGAAyG;AACzG,eAAO,MAAM,oBAAoB,OAAO,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CELLO Daemon — the agent_settings key namespace (DOD-SETTINGS-1).
|
|
3
|
+
*
|
|
4
|
+
* A single source for every valid per-agent reachability-policy setting key, so the handler (which
|
|
5
|
+
* REFUSES an unknown key) and the consumers (TIER-BOUNDS-SETTINGS reads the bound overrides,
|
|
6
|
+
* AWAY-TIER-1 reads the away texts) can never drift. Keys are lower-snake, dotted namespaces:
|
|
7
|
+
*
|
|
8
|
+
* bounds.<tier>.max_sessions bounds.<tier>.max_bytes — per-tier bound overrides
|
|
9
|
+
* away.default — the agent's default away text
|
|
10
|
+
* away.tier.<tier> — a per-tier away text
|
|
11
|
+
*
|
|
12
|
+
* `<tier>` is a tier NAME (not the integer), for legibility in the store. BLOCKED is deliberately NOT
|
|
13
|
+
* settable — 0/0 is fixed (you cannot "raise" a block), and it has no away text (a blocked sender is
|
|
14
|
+
* refused before any reply). So the settable tiers are unknown / known / whitelisted / vip.
|
|
15
|
+
*/
|
|
16
|
+
import { TIER } from "./contacts-tier-migration.js";
|
|
17
|
+
/** The tiers whose bounds and away texts are settable (BLOCKED is fixed, never overridable). */
|
|
18
|
+
export const SETTABLE_TIER_NAMES = Object.freeze(["unknown", "known", "whitelisted", "vip"]);
|
|
19
|
+
/** The tier NAME for a tier integer, or null for an unknown/unsettable value (e.g. BLOCKED=0).
|
|
20
|
+
* Keyed off the TIER constants (review F3) so a renumbering in contacts-tier-migration can never
|
|
21
|
+
* silently desync the settings namespace from the grid. */
|
|
22
|
+
export function settableTierName(tier) {
|
|
23
|
+
switch (tier) {
|
|
24
|
+
case TIER.UNKNOWN: return "unknown";
|
|
25
|
+
case TIER.KNOWN: return "known";
|
|
26
|
+
case TIER.WHITELISTED: return "whitelisted";
|
|
27
|
+
case TIER.VIP: return "vip";
|
|
28
|
+
default: return null; // BLOCKED or out-of-range — not settable
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** The setting key for a per-tier bound override. */
|
|
32
|
+
export function boundSettingKey(tier, field) {
|
|
33
|
+
return `bounds.${tier}.${field}`;
|
|
34
|
+
}
|
|
35
|
+
/** The setting key for a per-tier away text. */
|
|
36
|
+
export function awayTierSettingKey(tier) {
|
|
37
|
+
return `away.tier.${tier}`;
|
|
38
|
+
}
|
|
39
|
+
/** The setting key for the agent's default away text (the fallback below any per-tier text). */
|
|
40
|
+
export const AWAY_DEFAULT_KEY = "away.default";
|
|
41
|
+
const BOUND_FIELDS = Object.freeze(["max_sessions", "max_bytes"]);
|
|
42
|
+
/** Every valid setting key, precomputed. The handler validates a `set` against this exact set. */
|
|
43
|
+
const VALID_KEYS = new Set([
|
|
44
|
+
AWAY_DEFAULT_KEY,
|
|
45
|
+
...SETTABLE_TIER_NAMES.flatMap((t) => [
|
|
46
|
+
...BOUND_FIELDS.map((f) => boundSettingKey(t, f)),
|
|
47
|
+
awayTierSettingKey(t),
|
|
48
|
+
]),
|
|
49
|
+
]);
|
|
50
|
+
/** True iff `key` is a known, settable reachability-policy key. An unknown key is REFUSED by the
|
|
51
|
+
* handler (never silently stored — a typo'd key that persisted would be a setting that never takes
|
|
52
|
+
* effect, invisible to the operator). */
|
|
53
|
+
export function isValidSettingKey(key) {
|
|
54
|
+
return VALID_KEYS.has(key);
|
|
55
|
+
}
|
|
56
|
+
/** The full list of valid keys (for surfacing in a settings-list / help). */
|
|
57
|
+
export function allSettingKeys() {
|
|
58
|
+
return [...VALID_KEYS];
|
|
59
|
+
}
|
|
60
|
+
/** True iff the key is a per-tier BOUND override (its value must be a positive integer). */
|
|
61
|
+
export function isBoundKey(key) {
|
|
62
|
+
return key.startsWith("bounds.");
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Validate a setting's VALUE for its key (DOD-TIER-BOUNDS-SETTINGS AC2). A bound override may only be
|
|
66
|
+
* a FINITE POSITIVE INTEGER — INV-TIER-BOUND: a setting can RAISE or lower a bound within finite
|
|
67
|
+
* limits, never REMOVE one. So `Infinity`, negatives, zero, non-integers, and non-numeric strings are
|
|
68
|
+
* refused (an unbounded tier is exactly what the grid forbids). Away-text values are free-form strings.
|
|
69
|
+
*/
|
|
70
|
+
export function validateSettingValue(key, value) {
|
|
71
|
+
if (isBoundKey(key)) {
|
|
72
|
+
// `^[1-9][0-9]*$` — a positive integer with no sign, decimal, or `Infinity`/`NaN` spelling.
|
|
73
|
+
if (!/^[1-9][0-9]*$/.test(value)) {
|
|
74
|
+
return { ok: false, reason: "a bound must be a finite positive integer (no 0, negative, decimal, or Infinity)" };
|
|
75
|
+
}
|
|
76
|
+
// Number.MAX_SAFE_INTEGER guard — a value past it loses precision and is meaningless as a cap.
|
|
77
|
+
if (Number(value) > Number.MAX_SAFE_INTEGER) {
|
|
78
|
+
return { ok: false, reason: "a bound must be <= Number.MAX_SAFE_INTEGER" };
|
|
79
|
+
}
|
|
80
|
+
return { ok: true };
|
|
81
|
+
}
|
|
82
|
+
// Away-text (review F2/F3): an EMPTY / whitespace-only away text is refused — to CLEAR, use null
|
|
83
|
+
// (cello_contact_set_away) or omit the key; storing "" would silently blank every away reply,
|
|
84
|
+
// including the minimal stranger disclosure. Bounded to a sane length (an answering-machine line,
|
|
85
|
+
// not a document).
|
|
86
|
+
if (value.trim().length === 0) {
|
|
87
|
+
return { ok: false, reason: "an away message cannot be empty or whitespace-only (omit the key or pass null to clear)" };
|
|
88
|
+
}
|
|
89
|
+
if (value.length > AWAY_MESSAGE_MAX_LEN) {
|
|
90
|
+
return { ok: false, reason: `an away message must be <= ${AWAY_MESSAGE_MAX_LEN} characters` };
|
|
91
|
+
}
|
|
92
|
+
return { ok: true };
|
|
93
|
+
}
|
|
94
|
+
/** Max length of an away message (per-contact or per-tier/agent-default) — an answering-machine line. */
|
|
95
|
+
export const AWAY_MESSAGE_MAX_LEN = 2048;
|
|
96
|
+
//# sourceMappingURL=agent-settings-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-settings-keys.js","sourceRoot":"","sources":["../src/agent-settings-keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CELLO Daemon — contacts tier metadata (DOD-TIER-1, address-book Step 1).
|
|
3
|
+
*
|
|
4
|
+
* `contacts` was re-keyed to the stable `agent_id` in daemon@0.0.45 (DOD-AGENT-ID-JOINKEY-1). This
|
|
5
|
+
* module lands the address-book's per-contact metadata ON that key: a reachability `tier`, the
|
|
6
|
+
* `provenance` of the relationship, the last self-declared name a peer offered (for Option-C rename
|
|
7
|
+
* detection, Step 3), and a per-contact `away_message` (Step 4). All four are pure ADD COLUMN — no
|
|
8
|
+
* table rebuild, no PK change — so, unlike the join-key migration, this one is simple and idempotent
|
|
9
|
+
* and never has to appear in that migration's pinned DDL. It runs AFTER `migrateSessionTablesToAgentId`.
|
|
10
|
+
*
|
|
11
|
+
* Design source: docs/planning/user-stories/m8c/2026-07-10_contact-address-book-design.md (§1).
|
|
12
|
+
*/
|
|
13
|
+
import type { DaemonDatabase } from "./sqlcipher-db.js";
|
|
14
|
+
import type { Logger } from "./types.js";
|
|
15
|
+
/**
|
|
16
|
+
* The five reachability tiers, ordered so `>=` is meaningful (blocked < unknown < known < whitelisted
|
|
17
|
+
* < vip). Stored as the INTEGER `contacts.tier`. This const map is the SINGLE source of the numbers;
|
|
18
|
+
* no bare tier integer may appear at a call site (DOD-TIER-1 AC2).
|
|
19
|
+
*
|
|
20
|
+
* BLOCKED is a real, meaningful ZERO — see `normalizeTier` for why that matters.
|
|
21
|
+
*/
|
|
22
|
+
export declare const TIER: Readonly<{
|
|
23
|
+
readonly BLOCKED: 0;
|
|
24
|
+
readonly UNKNOWN: 1;
|
|
25
|
+
readonly KNOWN: 2;
|
|
26
|
+
readonly WHITELISTED: 3;
|
|
27
|
+
readonly VIP: 4;
|
|
28
|
+
}>;
|
|
29
|
+
export type TierName = keyof typeof TIER;
|
|
30
|
+
export type TierValue = (typeof TIER)[TierName];
|
|
31
|
+
/** True iff `n` is exactly one of the five defined tier integers (0..4). The validation gate for
|
|
32
|
+
* `cello_contact_set_tier` (Step 3) — an unknown value is refused, never coerced. */
|
|
33
|
+
export declare function isKnownTierValue(n: number): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* The read-side default, and the single most safety-critical function in this unit.
|
|
36
|
+
*
|
|
37
|
+
* A contact's effective tier is UNKNOWN when there is NO row (undefined) OR when the row's `tier`
|
|
38
|
+
* column is NULL (a row that predates a tier being set, or a stray never-stamped row). Both collapse
|
|
39
|
+
* to UNKNOWN — the tighter default: a caller must never accidentally treat an unresolved contact as
|
|
40
|
+
* reachable.
|
|
41
|
+
*
|
|
42
|
+
* It is written with EXPLICIT null/undefined checks, never `tier || UNKNOWN`, for two reasons that
|
|
43
|
+
* are both live bugs otherwise:
|
|
44
|
+
* - `0 || 1 === 1`: a `|| UNKNOWN` would swallow BLOCKED(0) and silently un-block a blocked contact.
|
|
45
|
+
* - `null >= 0 === true`: a NULL reaching a `>=` bound check reads as "not blocked", and a NULL
|
|
46
|
+
* reaching a `grid[tier]` lookup is `grid[null]` → undefined → crash. Normalizing NULL→UNKNOWN
|
|
47
|
+
* here keeps every downstream comparison and lookup total.
|
|
48
|
+
*/
|
|
49
|
+
export declare function normalizeTier(tier: number | null | undefined): number;
|
|
50
|
+
/** DOD-TIER-2: the abuse bounds for one tier. INV-TIER-BOUND — every field is FINITE (no tier is
|
|
51
|
+
* unbounded; `vip` is a large but real number, never Infinity). Step 4 lets settings OVERRIDE these
|
|
52
|
+
* defaults, but a setting may only raise/lower within finite bounds, never remove one. */
|
|
53
|
+
export interface TierBound {
|
|
54
|
+
/** Max concurrent (active|interrupted) sessions this agent will hold from ONE sender at this tier. */
|
|
55
|
+
readonly maxSessionsPerSender: number;
|
|
56
|
+
/** Max cumulative RECEIVED bytes for a single session at this tier (anti-drip-feed). */
|
|
57
|
+
readonly maxBytesPerSession: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The hardcoded default bounds grid (DOD-TIER-2). One named map — the SINGLE source; call sites
|
|
61
|
+
* reference it via `tierBoundsFor`, never inline a number. Step 4 (DOD-TIER-BOUNDS-SETTINGS) makes
|
|
62
|
+
* these overridable per agent; until then they are the policy.
|
|
63
|
+
*
|
|
64
|
+
* INV-TIER-BOUND: a HIGHER tier only RAISES a bound — no tier removes one. `vip` is 50 sessions / 2 GiB,
|
|
65
|
+
* deliberately finite. `blocked` is 0/0, which is what makes DOD-TIER-3 fall out for free: a 0 session
|
|
66
|
+
* cap refuses a blocked sender through the SAME per-sender-cap path an over-cap unknown takes, with no
|
|
67
|
+
* separate branch and therefore no distinguishing oracle.
|
|
68
|
+
*/
|
|
69
|
+
export declare const DEFAULT_TIER_BOUNDS: Readonly<Record<number, TierBound>>;
|
|
70
|
+
/** The bounds for a tier, TOTAL: any input is normalized to a defined tier first, so the return is
|
|
71
|
+
* always a real `TierBound` — a corrupt/out-of-range tier gets UNKNOWN's bounds, never `undefined`
|
|
72
|
+
* (the `grid[99]` crash the whole tier design guards against). */
|
|
73
|
+
export declare function tierBoundsFor(tier: number | null | undefined): TierBound;
|
|
74
|
+
/**
|
|
75
|
+
* Idempotently add the tier-metadata columns to `contacts` and grandfather existing contacts.
|
|
76
|
+
*
|
|
77
|
+
* SQLite has no `ADD COLUMN IF NOT EXISTS`, so each ALTER is PRAGMA-guarded. Crucially the columns
|
|
78
|
+
* are added with NO DEFAULT: a `DEFAULT` would give every existing row a value the instant the column
|
|
79
|
+
* is created, so the grandfather backfill (`UPDATE … WHERE tier IS NULL`) would then match NOTHING —
|
|
80
|
+
* every auto-accepting contact would silently drop to UNKNOWN. No default → existing rows read NULL →
|
|
81
|
+
* the explicit backfill promotes them to WHITELISTED, preserving today's binary-whitelist behaviour
|
|
82
|
+
* (design §1). Silently revoking access people already rely on is a worse failure than grandfathering
|
|
83
|
+
* a permissive default for a handful of contacts they can list and demote at leisure.
|
|
84
|
+
*
|
|
85
|
+
* The grandfather is ONE-TIME: it runs only in the invocation that first adds the `tier` column. A
|
|
86
|
+
* NULL that appears later (a stray un-stamped row) is NOT promoted — it is read as UNKNOWN by
|
|
87
|
+
* `normalizeTier`, the tighter default. The promotion is tied to the column's birth, not to NULL-ness.
|
|
88
|
+
*/
|
|
89
|
+
export declare function migrateContactsAddTierMetadata(db: DaemonDatabase, logger: Logger): void;
|
|
90
|
+
//# sourceMappingURL=contacts-tier-migration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contacts-tier-migration.d.ts","sourceRoot":"","sources":["../src/contacts-tier-migration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,IAAI;;;;;;EAMN,CAAC;AAEZ,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,IAAI,CAAC;AACzC,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC;AAIhD;sFACsF;AACtF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAQrE;AAED;;2FAE2F;AAC3F,MAAM,WAAW,SAAS;IACxB,sGAAsG;IACtG,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,wFAAwF;IACxF,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAMlE,CAAC;AAEH;;mEAEmE;AACnE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,CAExE;AAeD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,8BAA8B,CAAC,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA8CvF"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CELLO Daemon — contacts tier metadata (DOD-TIER-1, address-book Step 1).
|
|
3
|
+
*
|
|
4
|
+
* `contacts` was re-keyed to the stable `agent_id` in daemon@0.0.45 (DOD-AGENT-ID-JOINKEY-1). This
|
|
5
|
+
* module lands the address-book's per-contact metadata ON that key: a reachability `tier`, the
|
|
6
|
+
* `provenance` of the relationship, the last self-declared name a peer offered (for Option-C rename
|
|
7
|
+
* detection, Step 3), and a per-contact `away_message` (Step 4). All four are pure ADD COLUMN — no
|
|
8
|
+
* table rebuild, no PK change — so, unlike the join-key migration, this one is simple and idempotent
|
|
9
|
+
* and never has to appear in that migration's pinned DDL. It runs AFTER `migrateSessionTablesToAgentId`.
|
|
10
|
+
*
|
|
11
|
+
* Design source: docs/planning/user-stories/m8c/2026-07-10_contact-address-book-design.md (§1).
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The five reachability tiers, ordered so `>=` is meaningful (blocked < unknown < known < whitelisted
|
|
15
|
+
* < vip). Stored as the INTEGER `contacts.tier`. This const map is the SINGLE source of the numbers;
|
|
16
|
+
* no bare tier integer may appear at a call site (DOD-TIER-1 AC2).
|
|
17
|
+
*
|
|
18
|
+
* BLOCKED is a real, meaningful ZERO — see `normalizeTier` for why that matters.
|
|
19
|
+
*/
|
|
20
|
+
export const TIER = Object.freeze({
|
|
21
|
+
BLOCKED: 0,
|
|
22
|
+
UNKNOWN: 1,
|
|
23
|
+
KNOWN: 2,
|
|
24
|
+
WHITELISTED: 3,
|
|
25
|
+
VIP: 4,
|
|
26
|
+
});
|
|
27
|
+
const TIER_VALUES = Object.freeze(Object.values(TIER));
|
|
28
|
+
/** True iff `n` is exactly one of the five defined tier integers (0..4). The validation gate for
|
|
29
|
+
* `cello_contact_set_tier` (Step 3) — an unknown value is refused, never coerced. */
|
|
30
|
+
export function isKnownTierValue(n) {
|
|
31
|
+
return Number.isInteger(n) && TIER_VALUES.includes(n);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The read-side default, and the single most safety-critical function in this unit.
|
|
35
|
+
*
|
|
36
|
+
* A contact's effective tier is UNKNOWN when there is NO row (undefined) OR when the row's `tier`
|
|
37
|
+
* column is NULL (a row that predates a tier being set, or a stray never-stamped row). Both collapse
|
|
38
|
+
* to UNKNOWN — the tighter default: a caller must never accidentally treat an unresolved contact as
|
|
39
|
+
* reachable.
|
|
40
|
+
*
|
|
41
|
+
* It is written with EXPLICIT null/undefined checks, never `tier || UNKNOWN`, for two reasons that
|
|
42
|
+
* are both live bugs otherwise:
|
|
43
|
+
* - `0 || 1 === 1`: a `|| UNKNOWN` would swallow BLOCKED(0) and silently un-block a blocked contact.
|
|
44
|
+
* - `null >= 0 === true`: a NULL reaching a `>=` bound check reads as "not blocked", and a NULL
|
|
45
|
+
* reaching a `grid[tier]` lookup is `grid[null]` → undefined → crash. Normalizing NULL→UNKNOWN
|
|
46
|
+
* here keeps every downstream comparison and lookup total.
|
|
47
|
+
*/
|
|
48
|
+
export function normalizeTier(tier) {
|
|
49
|
+
if (tier === null || tier === undefined)
|
|
50
|
+
return TIER.UNKNOWN;
|
|
51
|
+
// TOTAL over ALL inputs: a stored value that is not one of the five defined tiers (a corrupt or
|
|
52
|
+
// future-version row) also collapses to UNKNOWN, so `getTier` is guaranteed to return a value in
|
|
53
|
+
// 0..4 and every downstream `grid[tier]` lookup / `>=` comparison is total. Without this, a corrupt
|
|
54
|
+
// `tier = 99` would sail through and become the `grid[99] → undefined` crash the bound grid fears.
|
|
55
|
+
if (!isKnownTierValue(tier))
|
|
56
|
+
return TIER.UNKNOWN;
|
|
57
|
+
return tier;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The hardcoded default bounds grid (DOD-TIER-2). One named map — the SINGLE source; call sites
|
|
61
|
+
* reference it via `tierBoundsFor`, never inline a number. Step 4 (DOD-TIER-BOUNDS-SETTINGS) makes
|
|
62
|
+
* these overridable per agent; until then they are the policy.
|
|
63
|
+
*
|
|
64
|
+
* INV-TIER-BOUND: a HIGHER tier only RAISES a bound — no tier removes one. `vip` is 50 sessions / 2 GiB,
|
|
65
|
+
* deliberately finite. `blocked` is 0/0, which is what makes DOD-TIER-3 fall out for free: a 0 session
|
|
66
|
+
* cap refuses a blocked sender through the SAME per-sender-cap path an over-cap unknown takes, with no
|
|
67
|
+
* separate branch and therefore no distinguishing oracle.
|
|
68
|
+
*/
|
|
69
|
+
export const DEFAULT_TIER_BOUNDS = Object.freeze({
|
|
70
|
+
[TIER.BLOCKED]: { maxSessionsPerSender: 0, maxBytesPerSession: 0 },
|
|
71
|
+
[TIER.UNKNOWN]: { maxSessionsPerSender: 3, maxBytesPerSession: 25 * 1024 * 1024 },
|
|
72
|
+
[TIER.KNOWN]: { maxSessionsPerSender: 5, maxBytesPerSession: 100 * 1024 * 1024 },
|
|
73
|
+
[TIER.WHITELISTED]: { maxSessionsPerSender: 20, maxBytesPerSession: 500 * 1024 * 1024 },
|
|
74
|
+
[TIER.VIP]: { maxSessionsPerSender: 50, maxBytesPerSession: 2 * 1024 * 1024 * 1024 },
|
|
75
|
+
});
|
|
76
|
+
/** The bounds for a tier, TOTAL: any input is normalized to a defined tier first, so the return is
|
|
77
|
+
* always a real `TierBound` — a corrupt/out-of-range tier gets UNKNOWN's bounds, never `undefined`
|
|
78
|
+
* (the `grid[99]` crash the whole tier design guards against). */
|
|
79
|
+
export function tierBoundsFor(tier) {
|
|
80
|
+
return DEFAULT_TIER_BOUNDS[normalizeTier(tier)];
|
|
81
|
+
}
|
|
82
|
+
const TIER_METADATA_COLUMNS = [
|
|
83
|
+
{ name: "tier", ddl: "tier INTEGER" },
|
|
84
|
+
{ name: "provenance", ddl: "provenance TEXT" },
|
|
85
|
+
{ name: "last_offered_moniker", ddl: "last_offered_moniker TEXT" },
|
|
86
|
+
{ name: "away_message", ddl: "away_message TEXT" },
|
|
87
|
+
];
|
|
88
|
+
/**
|
|
89
|
+
* Idempotently add the tier-metadata columns to `contacts` and grandfather existing contacts.
|
|
90
|
+
*
|
|
91
|
+
* SQLite has no `ADD COLUMN IF NOT EXISTS`, so each ALTER is PRAGMA-guarded. Crucially the columns
|
|
92
|
+
* are added with NO DEFAULT: a `DEFAULT` would give every existing row a value the instant the column
|
|
93
|
+
* is created, so the grandfather backfill (`UPDATE … WHERE tier IS NULL`) would then match NOTHING —
|
|
94
|
+
* every auto-accepting contact would silently drop to UNKNOWN. No default → existing rows read NULL →
|
|
95
|
+
* the explicit backfill promotes them to WHITELISTED, preserving today's binary-whitelist behaviour
|
|
96
|
+
* (design §1). Silently revoking access people already rely on is a worse failure than grandfathering
|
|
97
|
+
* a permissive default for a handful of contacts they can list and demote at leisure.
|
|
98
|
+
*
|
|
99
|
+
* The grandfather is ONE-TIME: it runs only in the invocation that first adds the `tier` column. A
|
|
100
|
+
* NULL that appears later (a stray un-stamped row) is NOT promoted — it is read as UNKNOWN by
|
|
101
|
+
* `normalizeTier`, the tighter default. The promotion is tied to the column's birth, not to NULL-ness.
|
|
102
|
+
*/
|
|
103
|
+
export function migrateContactsAddTierMetadata(db, logger) {
|
|
104
|
+
const existing = new Set(db.prepare("PRAGMA table_info(contacts)").all().map((c) => c.name));
|
|
105
|
+
const toAdd = TIER_METADATA_COLUMNS.filter((c) => !existing.has(c.name));
|
|
106
|
+
if (toAdd.length === 0)
|
|
107
|
+
return; // idempotent: every column already present → nothing to do
|
|
108
|
+
// The ADD COLUMNs and the grandfather backfill MUST commit atomically, in ONE transaction (SQLite
|
|
109
|
+
// DDL is transactional — the same reason the join-key migration uses one BEGIN…COMMIT). If a crash
|
|
110
|
+
// landed between the `tier` ALTER committing and the backfill, the next init would see the column
|
|
111
|
+
// exists, skip the one-time grandfather FOREVER, and silently demote every legacy contact to
|
|
112
|
+
// UNKNOWN — the exact "silently revoking access people already rely on" failure this file exists to
|
|
113
|
+
// avoid, with no log and no error. Wrapping both makes "column added" and "existing rows
|
|
114
|
+
// grandfathered" inseparable: a crash rolls back BOTH, and the clean re-run does the whole thing —
|
|
115
|
+
// which is what makes column-existence a VALID durability marker for the one-time gate.
|
|
116
|
+
const addsTier = toAdd.some((c) => c.name === "tier");
|
|
117
|
+
let grandfathered = 0;
|
|
118
|
+
db.exec("BEGIN");
|
|
119
|
+
try {
|
|
120
|
+
for (const col of toAdd)
|
|
121
|
+
db.exec(`ALTER TABLE contacts ADD COLUMN ${col.ddl}`);
|
|
122
|
+
// Grandfather EXISTING contacts to WHITELISTED — but ONLY on the migration that first adds `tier`
|
|
123
|
+
// (a one-time, column-birth event). A NULL written AFTER the column exists is never promoted here;
|
|
124
|
+
// it is a read-time UNKNOWN via normalizeTier, the tighter default.
|
|
125
|
+
if (addsTier) {
|
|
126
|
+
grandfathered = Number(db.prepare("UPDATE contacts SET tier = ? WHERE tier IS NULL").run(TIER.WHITELISTED).changes);
|
|
127
|
+
}
|
|
128
|
+
db.exec("COMMIT");
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
// SQLite may have already aborted the transaction; a failing ROLLBACK must not mask the real error.
|
|
132
|
+
try {
|
|
133
|
+
db.exec("ROLLBACK");
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
/* the failing statement may have already aborted the txn */
|
|
137
|
+
}
|
|
138
|
+
logger.error("contacts.tier.migration.failed", {
|
|
139
|
+
columns: toAdd.map((c) => c.name),
|
|
140
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
141
|
+
});
|
|
142
|
+
throw err;
|
|
143
|
+
}
|
|
144
|
+
logger.info("contacts.tier.columns.added", { columns: toAdd.map((c) => c.name) });
|
|
145
|
+
if (grandfathered > 0) {
|
|
146
|
+
logger.info("contacts.tier.grandfathered", { count: grandfathered, tier: TIER.WHITELISTED });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=contacts-tier-migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contacts-tier-migration.js","sourceRoot":"","sources":["../src/contacts-tier-migration.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EAQrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EAQrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAU/D,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAsB7G,OAAO,KAAK,EAAE,kBAAkB,EAA+C,MAAM,yBAAyB,CAAC;AAQ/G,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AA0InF,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,SAAS,IAAI,oBAAoB,CAAC;IAClC;;;;OAIG;IACH,qBAAqB,IAAI,kBAAkB,CAAC;IAC5C;;;;;;;;OAQG;IACH,gBAAgB,IAAI,SAAS,GAAG,IAAI,CAAC;IACrC;;;;OAIG;IACH,oBAAoB,IAAI,kBAAkB,CAAC;IAC3C;;;OAGG;IACH,iBAAiB,IAAI,eAAe,CAAC;CACtC;AA2CD,eAAO,MAAM,sBAAsB,QAAsB,CAAC;AAE1D,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAy8L7E"}
|