@odla-ai/brand 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,7 +1,340 @@
1
- import { B as BrandDb, A as AssetAnalysis, S as Swatch, a as BrandBook, b as BrandOp, c as BrandEntityRef, d as SectionKind, e as SectionStatus, f as BrandProposal, g as AssetKind, h as BrandActor } from './index-bj73h3qo.cjs';
2
- export { i as ASSET_KINDS, j as BOOK_STATUSES, k as BRAND_CHART_TOKENS, l as BRAND_CHAT_TOKENS, m as BRAND_DERIVED_TOKENS, n as BRAND_EMITTED_TOKENS, o as BRAND_NS, p as BRAND_REQUIRED_TOKENS, q as BookStatus, r as BrandAsset, s as BrandAttrs, t as BrandFileRecord, u as BrandLookup, v as BrandPalette, w as BrandResult, x as BrandRow, y as BrandScalar, z as BrandSection, C as BrandStorage, D as BrandTokens, E as BrandTokensSnapshot, F as BrandUploadBody, G as CompileInput, H as CompiledBrandTokens, I as DARK_FLIP_L_MAX, J as DARK_FLIP_L_MIN, K as DEFAULT_ACCENT_SEED, L as ImagerySection, M as LogoSection, N as MapResult, P as PALETTE_SOURCES, O as PALETTE_STATUSES, Q as PROPOSAL_KINDS, R as PROPOSAL_STATUSES, T as PaletteSection, U as PaletteSource, V as PaletteStatus, W as ProposalKind, X as ProposalStatus, Y as RenderTokensCssOptions, Z as SECTION_KINDS, _ as SECTION_STATUSES, $ as SWATCH_ROLES, a0 as SwatchRole, a1 as TokenWarning, a2 as TypographySection, a3 as VoiceSection, a4 as compileBrandTokens, a5 as deriveDarkTokens, a6 as mapPaletteToTokens, a7 as renderTokensCss } from './index-bj73h3qo.cjs';
1
+ import { P as ProposalKind, a as ProposalStatus, A as AssetKind, b as AssetAnalysis, B as BookStatus, c as BrandTokensSnapshot, d as PaletteStatus, S as Swatch, e as PaletteSource, f as SectionKind, g as SectionStatus } from './index-CRl3IXHB.cjs';
2
+ export { h as ASSET_KINDS, i as BOOK_STATUSES, j as BRAND_CHART_TOKENS, k as BRAND_CHAT_TOKENS, l as BRAND_DERIVED_TOKENS, m as BRAND_EMITTED_TOKENS, n as BRAND_NS, o as BRAND_REQUIRED_TOKENS, p as BrandTokens, C as CompileInput, q as CompiledBrandTokens, D as DARK_FLIP_L_MAX, r as DARK_FLIP_L_MIN, s as DEFAULT_ACCENT_SEED, I as ImagerySection, L as LogoSection, M as MapResult, t as PALETTE_SOURCES, u as PALETTE_STATUSES, v as PROPOSAL_KINDS, w as PROPOSAL_STATUSES, x as PaletteSection, R as RenderTokensCssOptions, y as SECTION_KINDS, z as SECTION_STATUSES, E as SWATCH_ROLES, F as SwatchRole, T as TokenWarning, G as TypographySection, V as VoiceSection, H as compileBrandTokens, J as deriveDarkTokens, K as mapPaletteToTokens, N as renderTokensCss } from './index-CRl3IXHB.cjs';
3
3
  import { ToolHandler, Skill, ToolDef, Persona, Inference, AgentRunInput, ImageBlock, OracleContentBlock } from '@odla-ai/ai';
4
4
 
5
+ /** Immutable storage snapshot captured by the trusted semantic Brand bridge. */
6
+ interface BrandSourceAssetSnapshot {
7
+ assetId: string;
8
+ contentDigest: string;
9
+ objectEtag: string;
10
+ objectSize: number;
11
+ pathDigest: string;
12
+ contentType: string | null;
13
+ analysisRevision: number | null;
14
+ analysisDigest: string | null;
15
+ }
16
+ /** Required proposal provenance. Nulls keep the reviewed snapshot lossless. */
17
+ interface BrandProposalProvenance {
18
+ sourceAssetId: string | null;
19
+ sourceAsset: BrandSourceAssetSnapshot | null;
20
+ messageId: string | null;
21
+ turnId: string | null;
22
+ taintLabels: string[];
23
+ }
24
+ /** Agent output parked for explicit human resolution. */
25
+ interface BrandProposal {
26
+ id: string;
27
+ bookId: string;
28
+ kind: ProposalKind;
29
+ status: ProposalStatus;
30
+ payload: Record<string, unknown>;
31
+ rationale: string;
32
+ provenance: BrandProposalProvenance;
33
+ reviewDigest: string;
34
+ audience: string[];
35
+ createdBy: string;
36
+ createdAuthorityRef: string;
37
+ createdAt: number;
38
+ resolvedBy?: string;
39
+ resolvedAt?: number;
40
+ resolutionNote?: string;
41
+ approvedBy?: string;
42
+ appliedBy?: string;
43
+ resolutionReceiptId?: string;
44
+ resolutionActionDigest?: string;
45
+ }
46
+ /** Immutable proposal fields a human sends back when resolving it. */
47
+ interface BrandProposalReviewSnapshot {
48
+ id: string;
49
+ bookId: string;
50
+ kind: ProposalKind;
51
+ status: "open";
52
+ payload: Record<string, unknown>;
53
+ rationale: string;
54
+ provenance: BrandProposalProvenance;
55
+ reviewDigest: string;
56
+ audience: string[];
57
+ createdBy: string;
58
+ createdAuthorityRef: string;
59
+ createdAt: number;
60
+ }
61
+ /** Host receipt returned after consuming one central human-exact decision. */
62
+ interface BrandHumanAuthorityConsumption {
63
+ id: string;
64
+ grantId: string;
65
+ grantVersion: number;
66
+ useNumber: number;
67
+ actorPrincipalId: string;
68
+ actorKind: "human";
69
+ credentialId: string;
70
+ credentialKind: "clerk";
71
+ appId: string;
72
+ /** Exact Registry project lifetime authorized for this Brand decision. */
73
+ appIncarnation: string;
74
+ capability: "brand.proposal.resolve";
75
+ projectCapability: "brand.approve";
76
+ effect: "internal";
77
+ actionDigest: string;
78
+ resourceDigest: string;
79
+ constraintEvidence: Record<string, unknown>;
80
+ consumptionIdempotencyKey: string;
81
+ requestDigest: string;
82
+ consumedAt: number;
83
+ }
84
+ /** Live dependency revision and intended effect consumed by the decision. */
85
+ interface BrandDecisionBinding {
86
+ version: 1;
87
+ bookVersion: number;
88
+ activationRevision: number;
89
+ activePaletteId: string | null;
90
+ memberIdsDigest: string;
91
+ activePaletteDigest: string | null;
92
+ typographyDigest: string | null;
93
+ sourceAssetDigest: string | null;
94
+ effectDigest: string;
95
+ }
96
+ /** Durable projection of one centrally authorized decision. */
97
+ interface BrandApprovalReceipt {
98
+ version: 1;
99
+ id: string;
100
+ mutationKey: string;
101
+ bookId: string;
102
+ proposalId: string;
103
+ resolution: "accepted" | "rejected";
104
+ paletteId?: string;
105
+ resolutionNote?: string;
106
+ reviewedProposal: BrandProposalReviewSnapshot;
107
+ actionDigest: string;
108
+ decisionBinding: BrandDecisionBinding;
109
+ approvedBy: string;
110
+ approvedByKind: "human";
111
+ appliedBy: string;
112
+ appliedByKind: "human";
113
+ authorityRef: string;
114
+ authorityCapability: "brand.approve";
115
+ authorityConsumption: BrandHumanAuthorityConsumption;
116
+ createdAt: number;
117
+ receiptDigest: string;
118
+ }
119
+
120
+ /** Scalar values odla-db attrs and where-clauses accept. */
121
+ type BrandScalar = string | number | boolean | null;
122
+ /** Natural-key lookup ref for idempotent upserts (odla-db `Lookup` shape). */
123
+ interface BrandLookup {
124
+ ns: string;
125
+ attr: string;
126
+ value: BrandScalar;
127
+ }
128
+ /** How an op names its row: a raw entity id, or a natural-key lookup. */
129
+ type BrandEntityRef = string | BrandLookup;
130
+ /** Attr payload of one op. Typed `any` on purpose: the real odla-db
131
+ * `transact` constrains attrs to its own `Value` type, and `any` is the one
132
+ * shape assignable in both directions with no cast. */
133
+ type BrandAttrs = Record<string, any>;
134
+ /** One transact operation (update = attr-merge upsert; merge = deep-merge
135
+ * into a json attribute; retract = clear the named attributes, since a typed
136
+ * scalar can't store null). */
137
+ type BrandOp = {
138
+ t: "update";
139
+ ns: string;
140
+ id: BrandEntityRef;
141
+ attrs: BrandAttrs;
142
+ } | {
143
+ t: "merge";
144
+ ns: string;
145
+ id: BrandEntityRef;
146
+ attrs: BrandAttrs;
147
+ } | {
148
+ t: "retract";
149
+ ns: string;
150
+ id: BrandEntityRef;
151
+ attrs: string[];
152
+ } | {
153
+ t: "delete";
154
+ ns: string;
155
+ id: BrandEntityRef;
156
+ } | {
157
+ t: "link";
158
+ ns: string;
159
+ id: BrandEntityRef;
160
+ label: string;
161
+ target: BrandEntityRef;
162
+ } | {
163
+ t: "unlink";
164
+ ns: string;
165
+ id: BrandEntityRef;
166
+ label: string;
167
+ target: BrandEntityRef;
168
+ };
169
+ /** A row as odla-db returns it: hydrated id plus attrs. */
170
+ type BrandRow = {
171
+ id: string;
172
+ } & Record<string, unknown>;
173
+ /** Query result: namespace → rows. */
174
+ type BrandResult = Record<string, BrandRow[]>;
175
+ /** A brand book row: the auth roster (`memberIds`, including the bot agent
176
+ * id) plus the active palette and compiled-token cache. */
177
+ interface BrandBook {
178
+ id: string;
179
+ /** Monotonic worker-managed metadata revision. */
180
+ version: number;
181
+ slug: string;
182
+ name: string;
183
+ status: BookStatus;
184
+ ownerId: string;
185
+ /** Host authority that allowed this worker-created book. */
186
+ createdAuthorityRef: string;
187
+ rosterAuthorityRef?: string;
188
+ memberIds: string[];
189
+ channelId?: string;
190
+ activePaletteId?: string;
191
+ /** CAS counter advanced by every accepted palette activation. */
192
+ activationRevision: number;
193
+ tokens?: BrandTokensSnapshot;
194
+ summary?: string;
195
+ createdAt: number;
196
+ updatedAt: number;
197
+ }
198
+ /** A section row — one per (book, kind), upserted by its natural `key`. */
199
+ interface BrandSection {
200
+ id: string;
201
+ key: string;
202
+ bookId: string;
203
+ kind: SectionKind;
204
+ status: SectionStatus;
205
+ content: Record<string, unknown>;
206
+ audience: string[];
207
+ updatedBy: string;
208
+ updatedAt: number;
209
+ /** Present on approved sections and bound to the exact human decision. */
210
+ approvalReceiptId?: string;
211
+ approvalActionDigest?: string;
212
+ }
213
+ /** A palette row. Swatches are json ON the palette, not a namespace: the
214
+ * palette is the atomic proposal/approval unit and swatches are never
215
+ * queried across palettes. */
216
+ interface BrandPalette {
217
+ id: string;
218
+ bookId: string;
219
+ name: string;
220
+ status: PaletteStatus;
221
+ swatches: Swatch[];
222
+ seedHex?: string;
223
+ source: PaletteSource;
224
+ rationale?: string;
225
+ /** Accepted proposal whose exact reviewed payload materialized this row. */
226
+ proposalId: string;
227
+ approvalReceiptId: string;
228
+ approvalActionDigest: string;
229
+ audience: string[];
230
+ createdAt: number;
231
+ updatedAt: number;
232
+ }
233
+ /** An asset row mirroring one real uploaded file (worker-mediated; rules
234
+ * close the namespace). Delete is a tombstone (`deletedAt`), never a row
235
+ * delete, so analyses/proposals referencing it stay coherent. */
236
+ interface BrandAsset {
237
+ id: string;
238
+ bookId: string;
239
+ kind: AssetKind;
240
+ path: string;
241
+ storageObjectId: string;
242
+ contentDigest: string;
243
+ contentType: string;
244
+ size: number;
245
+ status: "live" | "deleting" | "deleted";
246
+ title?: string;
247
+ analysis?: AssetAnalysis;
248
+ analyzedAt?: number;
249
+ analysisRevision: number;
250
+ analysisDigest?: string;
251
+ analyzedBy?: string;
252
+ analyzedAuthorityRef?: string;
253
+ audience: string[];
254
+ uploadedBy: string;
255
+ uploadedAuthorityRef: string;
256
+ createdAt: number;
257
+ deletedAt?: number;
258
+ deletedBy?: string;
259
+ deletedAuthorityRef?: string;
260
+ }
261
+ /** What `db.storage.upload` resolves to (odla-db's file record shape). */
262
+ interface BrandFileRecord {
263
+ id: string;
264
+ path: string;
265
+ url: string;
266
+ size: number;
267
+ contentType: string;
268
+ }
269
+ /** Bodies `storage.upload` accepts — a practical subset of the platform's
270
+ * `BodyInit` (which has no ambient type under a DOM-less lib). The real
271
+ * @odla-ai/db client accepts a superset, so it still structurally satisfies
272
+ * {@link BrandStorage}. */
273
+ type BrandUploadBody = string | Blob | ArrayBuffer | Uint8Array | ReadableStream<Uint8Array>;
274
+ /** The injected file store — @odla-ai/db's `storage` API satisfies this. */
275
+ interface BrandStorage {
276
+ upload(path: string, data: BrandUploadBody, contentType?: string, opts?: {
277
+ private?: boolean;
278
+ }): Promise<BrandFileRecord>;
279
+ sign(path: string, ttlSeconds?: number): Promise<string>;
280
+ delete(path: string): Promise<void>;
281
+ }
282
+ /** One entity-state compare-and-swap condition, checked atomically with the
283
+ * transaction. Mirrors @odla-ai/db's structural guard contract. */
284
+ interface BrandTransactGuard {
285
+ ns: string;
286
+ id: string;
287
+ exists: boolean;
288
+ equals?: Record<string, unknown>;
289
+ }
290
+ /** Attribution, idempotency, and atomic preconditions for a brand write. */
291
+ interface BrandTransactOptions {
292
+ mutationId?: string;
293
+ guards?: BrandTransactGuard[];
294
+ asUser?: string;
295
+ asEmail?: string;
296
+ asPrincipalKind?: "human" | "agent" | "service";
297
+ }
298
+ /** The injected odla client (structural — a real @odla-ai/db `AdminDb`
299
+ * satisfies it). `transact` accepts flat op arrays; stable mutation ids give
300
+ * exactly-once application and guards bind reviewed state to its write. */
301
+ interface BrandDb {
302
+ query(q: Record<string, unknown>): Promise<Record<string, unknown[]>>;
303
+ transact(ops: unknown[], opts?: BrandTransactOptions): Promise<{
304
+ txId: number;
305
+ duplicate?: boolean;
306
+ }>;
307
+ storage: BrandStorage;
308
+ }
309
+ /** Who is acting: a human member or the book's bot agent. */
310
+ interface BrandActor {
311
+ id: string;
312
+ kind: "human" | "agent";
313
+ email?: string;
314
+ }
315
+
316
+ /** Canonical least-privilege runtime profile for a Brand collaborator agent. */
317
+ interface BrandAgentProfile {
318
+ version: 1;
319
+ projectCapabilities: readonly ["brand.read", "brand.edit"];
320
+ semanticOperations: readonly [
321
+ "brand.proposal.create",
322
+ "brand.asset.analysis.record",
323
+ "brand.asset.content.read"
324
+ ];
325
+ rawBrandWrites: false;
326
+ rawFileOperations: false;
327
+ approval: {
328
+ principalKind: "human";
329
+ projectCapability: "brand.approve";
330
+ capability: "brand.proposal.resolve";
331
+ exactAction: true;
332
+ };
333
+ }
334
+ /** Install-time contract: agents use semantic Brand operations; only a direct
335
+ * human may consume exact approval authority for a reviewed proposal. */
336
+ declare const BRAND_AGENT_PROFILE: BrandAgentProfile;
337
+
5
338
  /** Caller-fault error (bad hex, oversized payload, blocked transition…) — the
6
339
  * route layer maps it to a 400. `fields` carries per-field messages when the
7
340
  * failure came from input validation. */
@@ -13,6 +346,27 @@ declare class BrandInputError extends Error {
13
346
  declare class BrandNotFoundError extends Error {
14
347
  constructor(what: string);
15
348
  }
349
+ /** A once-valid central authority/resource is permanently unavailable. */
350
+ declare class BrandGoneError extends Error {
351
+ constructor(message?: string);
352
+ }
353
+ /** Authenticated principal lacks the required principal kind/capability. */
354
+ declare class BrandForbiddenError extends Error {
355
+ constructor(message?: string);
356
+ }
357
+ /** Reviewed state or an idempotent action no longer matches current state. */
358
+ declare class BrandConflictError extends Error {
359
+ constructor(message: string);
360
+ }
361
+ /**
362
+ * A proposal authority use was consumed, but the local guarded Brand write
363
+ * lost its compare-and-swap race. Clients must preserve the reviewed draft but
364
+ * rotate their idempotency key before a fresh human decision attempt.
365
+ */
366
+ declare class BrandReviewStateChangedError extends BrandConflictError {
367
+ readonly code = "brand_review_state_changed";
368
+ constructor(message?: string);
369
+ }
16
370
 
17
371
  /** What `fetchBytes` resolves to: raw bytes plus the served content type. */
18
372
  interface BrandFetchedBytes {
@@ -58,7 +412,7 @@ interface SerializedLinkEnd {
58
412
  has: "one" | "many";
59
413
  label: string;
60
414
  }
61
- /** A serialized schema link (unused by brand — audiences are denormalized). */
415
+ /** A serialized schema link used for current-book authorization. */
62
416
  interface SerializedLink {
63
417
  forward: SerializedLinkEnd;
64
418
  reverse: SerializedLinkEnd;
@@ -69,7 +423,7 @@ interface SerializedSchema {
69
423
  links: Record<string, SerializedLink>;
70
424
  }
71
425
  /**
72
- * The pre-serialized (wire-shape) odla-db schema for the five brand
426
+ * The pre-serialized (wire-shape) odla-db schema for the six brand
73
427
  * namespaces; POST it to `/app/:id/schema` as `{ schema: BRAND_SCHEMA }`.
74
428
  * Natural keys (`book.slug`, `section.key`) make provisioning and section
75
429
  * upserts idempotent; mirrored `id` attrs make rows addressable by
@@ -87,11 +441,11 @@ interface BrandRule {
87
441
  /** Namespace → rule set, as installed at `/app/:id/admin/rules`. */
88
442
  type BrandRules = Record<string, BrandRule>;
89
443
  /**
90
- * Default-deny CEL rules for the five brand namespaces; install at
444
+ * Default-deny CEL rules for the six brand namespaces; install at
91
445
  * `/app/:id/admin/rules`. Books gate on the `memberIds` roster (owner-only
92
- * writes); sections/palettes/proposals gate on their denormalized `audience`
93
- * and are never client-deletable (archive via `status` instead); assets are
94
- * fully worker-mediated. Use {@link brandRules} for a per-install copy.
446
+ * writes); child rows gate reads on current linked-book membership and all
447
+ * writes are worker-mediated. Use
448
+ * {@link brandRules} for a per-install copy.
95
449
  */
96
450
  declare const BRAND_RULES: BrandRules;
97
451
  /**
@@ -134,9 +488,8 @@ declare function assertSwatches(value: unknown): Swatch[];
134
488
  */
135
489
  declare function assertSectionContent(kind: string, content: unknown): Record<string, unknown>;
136
490
  /**
137
- * Sanitize an upload's file name for use in an R2 key: strips path
138
- * separators, control characters, and leading dots, then caps at 120
139
- * characters. Throws when nothing survives sanitizing.
491
+ * Validate an upload file name for an R2 key. Path/URL delimiters and control
492
+ * characters are rejected; leading dots are stripped and length is capped.
140
493
  */
141
494
  declare function safeFileName(name: unknown): string;
142
495
  /**
@@ -151,6 +504,64 @@ declare function assertAssetContentType(value: unknown): string;
151
504
  */
152
505
  declare function assertAnalysis(value: unknown): AssetAnalysis;
153
506
 
507
+ /** Stay materially below the server's whole-guards parser budget. */
508
+ declare function isBoundedBrandJson(root: unknown, limits?: {
509
+ maxDepth?: number;
510
+ maxNodes?: number;
511
+ maxBytes?: number;
512
+ }): boolean;
513
+ /** Deterministic JSON with recursively sorted object keys. */
514
+ declare function canonicalBrandJson(value: unknown): string;
515
+ /** `sha256:<hex>` over {@link canonicalBrandJson}. */
516
+ declare function brandJsonDigest(value: unknown): Promise<string>;
517
+
518
+ /** Stable local reference to one immutable central grant revision. */
519
+ declare function brandAuthorityRef(consumption: Pick<BrandHumanAuthorityConsumption, "grantId" | "grantVersion">): string;
520
+ /** Validate the exact direct-human central authority receipt shape. */
521
+ declare function isBrandHumanAuthorityConsumption(value: unknown): value is BrandHumanAuthorityConsumption;
522
+ /** Verify exact shape, cross-field bindings, and every local digest. This
523
+ * proves receipt self-consistency only; the host must authenticate the
524
+ * central consumption behind `authorityConsumption.id`. */
525
+ declare function verifyBrandApprovalReceipt(receipt: unknown): Promise<boolean>;
526
+
527
+ /** Brand resources that can be shared into a Discussion message. */
528
+ declare const BRAND_DISCUSSION_REFERENCE_KINDS: readonly ["brand:book", "brand:asset", "brand:palette", "brand:proposal", "brand:receipt"];
529
+ /** One Brand resource kind understood by the native Brand destination. */
530
+ type BrandDiscussionReferenceKind = (typeof BRAND_DISCUSSION_REFERENCE_KINDS)[number];
531
+ /** Canonical Brand destination target parsed from an `odla-ref` deep link. */
532
+ interface BrandDiscussionReferenceTarget {
533
+ kind: BrandDiscussionReferenceKind;
534
+ bookId: string;
535
+ resourceId?: string;
536
+ }
537
+ /** Product-owned projection returned to Discussion typeahead and exact lookup. */
538
+ interface BrandDiscussionReference {
539
+ /** Canonical Brand kind used in stored Discussion ref markup. */
540
+ kind: BrandDiscussionReferenceKind;
541
+ /** Opaque durable product id; never infer membership from its segments. */
542
+ id: string;
543
+ /** Product-authored primary display name. */
544
+ label: string;
545
+ /** Short product-authored secondary context for the picker. */
546
+ hint: string;
547
+ /** Bounded product-authored context safe to show an LLM or person. */
548
+ summary: string;
549
+ /** Current product status at inspection time. */
550
+ status: string;
551
+ /** Human-readable native surface the link opens. */
552
+ destination: string;
553
+ /** Same-origin native link; navigation is not mutation authority. */
554
+ href: string;
555
+ }
556
+ /** Durable ref id: a book id, or `bookId/resourceId` for a child resource. */
557
+ declare function brandDiscussionReferenceId(target: BrandDiscussionReferenceTarget): string;
558
+ /** Canonical value stored in the stable `odla-ref` query parameter. */
559
+ declare function formatBrandDiscussionReference(target: BrandDiscussionReferenceTarget): string;
560
+ /** Parse and validate a Brand `odla-ref`; malformed and cross-product refs fail closed. */
561
+ declare function parseBrandDiscussionReference(input: URL | string): BrandDiscussionReferenceTarget | null;
562
+ /** Build the native Brand deep link while preserving the deployed origin. */
563
+ declare function brandDiscussionReferenceHref(current: URL, target: BrandDiscussionReferenceTarget, basePath?: string): string;
564
+
154
565
  /** Input to {@link createBookOps}. `memberIds` is the full auth roster —
155
566
  * include the bot agent's id so it can pass the audience rules. */
156
567
  interface CreateBookInput {
@@ -158,6 +569,7 @@ interface CreateBookInput {
158
569
  slug: string;
159
570
  name: string;
160
571
  ownerId: string;
572
+ createdAuthorityRef: string;
161
573
  memberIds: string[];
162
574
  channelId?: string;
163
575
  now: number;
@@ -212,6 +624,8 @@ interface UpsertSectionInput {
212
624
  audience: string[];
213
625
  updatedBy: string;
214
626
  now: number;
627
+ approvalReceiptId?: string;
628
+ approvalActionDigest?: string;
215
629
  }
216
630
  /**
217
631
  * Ops to create-or-replace a book's section of one kind: a single `update`
@@ -220,6 +634,24 @@ interface UpsertSectionInput {
220
634
  * snapshot, and the author/timestamp.
221
635
  */
222
636
  declare function upsertSectionOps(input: UpsertSectionInput): BrandOp[];
637
+ /** Input for an agent-authored non-palette facet proposal. */
638
+ interface ProposeSectionInput {
639
+ id: string;
640
+ bookId: string;
641
+ kind: Exclude<SectionKind, "palette">;
642
+ content: Record<string, unknown>;
643
+ rationale: string;
644
+ audience: string[];
645
+ createdBy: string;
646
+ createdAuthorityRef: string;
647
+ sourceAsset?: BrandProposal["provenance"]["sourceAsset"];
648
+ messageId: string;
649
+ turnId: string;
650
+ taintLabels: string[];
651
+ now: number;
652
+ }
653
+ /** Validate a facet draft and park it as an immutable OPEN proposal. */
654
+ declare function proposeSectionOps(input: ProposeSectionInput): Promise<BrandOp[]>;
223
655
 
224
656
  /** Input to {@link proposePaletteOps}. `audience` is the book's roster
225
657
  * snapshot; `contrastReport` is stored verbatim in the payload for the
@@ -233,9 +665,12 @@ interface ProposePaletteInput {
233
665
  seedHex?: string;
234
666
  contrastReport?: unknown;
235
667
  createdBy: string;
668
+ createdAuthorityRef: string;
236
669
  audience: string[];
237
- sourceAssetId?: string;
238
- messageId?: string;
670
+ sourceAsset?: BrandProposal["provenance"]["sourceAsset"];
671
+ messageId: string;
672
+ turnId: string;
673
+ taintLabels: string[];
239
674
  now: number;
240
675
  }
241
676
  /**
@@ -243,13 +678,15 @@ interface ProposePaletteInput {
243
678
  * `kind: "palette"`, `status: "open"`, with the validated swatches (and
244
679
  * optional seed/contrast report) in `payload`.
245
680
  */
246
- declare function proposePaletteOps(input: ProposePaletteInput): BrandOp[];
681
+ declare function proposePaletteOps(input: ProposePaletteInput): Promise<BrandOp[]>;
247
682
  /** Input to {@link acceptProposalOps}: the proposal row as read back, the id
248
683
  * to mint the palette under, and who resolved it. */
249
684
  interface AcceptProposalInput {
250
685
  proposal: BrandProposal;
251
686
  paletteId: string;
252
687
  resolvedBy: string;
688
+ approvalReceiptId: string;
689
+ approvalActionDigest: string;
253
690
  now: number;
254
691
  resolutionNote?: string;
255
692
  }
@@ -279,16 +716,18 @@ interface RejectProposalInput {
279
716
  declare function rejectProposalOps(input: RejectProposalInput): BrandOp[];
280
717
 
281
718
  /** Input to {@link createAssetOps} — the storage upload's receipt fields
282
- * (`path`/`url`/`size`) plus the declared kind and the book's audience. */
719
+ * (`path`/`size`) plus the declared kind and the book's audience. */
283
720
  interface CreateAssetInput {
284
721
  id: string;
285
722
  bookId: string;
286
723
  kind: AssetKind;
287
724
  path: string;
288
- url: string;
725
+ storageObjectId: string;
726
+ contentDigest: string;
289
727
  contentType: string;
290
728
  size: number;
291
729
  uploadedBy: string;
730
+ uploadedAuthorityRef: string;
292
731
  audience: string[];
293
732
  title?: string;
294
733
  now: number;
@@ -304,12 +743,14 @@ declare function createAssetOps(input: CreateAssetInput): BrandOp[];
304
743
  * `deletedAt` in place. List reads exclude tombstoned rows; the row itself
305
744
  * stays for provenance.
306
745
  */
307
- declare function tombstoneAssetOps(assetId: BrandEntityRef, now: number): BrandOp[];
746
+ declare function beginAssetDeleteOps(assetId: BrandEntityRef, now: number, deletedBy: string, deletedAuthorityRef: string): BrandOp[];
747
+ /** Complete a previously authorized deletion after storage is tombstoned. */
748
+ declare function finishAssetDeleteOps(assetId: BrandEntityRef): BrandOp[];
308
749
  /**
309
750
  * Ops to record an agent's analysis of an asset: the validated + capped
310
751
  * analysis json plus `analyzedAt`. Replaces any prior analysis whole.
311
752
  */
312
- declare function recordAnalysisOps(assetId: BrandEntityRef, analysis: unknown, now: number): BrandOp[];
753
+ declare function recordAnalysisOps(assetId: BrandEntityRef, analysis: unknown, priorRevision: number, analyzedBy: string, analyzedAuthorityRef: string, now: number): Promise<BrandOp[]>;
313
754
 
314
755
  /** An sRGB color with channels as fractions in [0, 1]. */
315
756
  interface Rgb {
@@ -566,6 +1007,21 @@ interface DerivePaletteOptions {
566
1007
  */
567
1008
  declare function derivePalette(seedHex: string, opts?: DerivePaletteOptions): Swatch[];
568
1009
 
1010
+ /** Semantic Brand capability granted to one live agent principal. */
1011
+ type BrandCapability = "brand.read" | "brand.edit";
1012
+ /** Host-verified evidence that an agent currently holds one Brand capability. */
1013
+ interface BrandCapabilityAuthority {
1014
+ capability: BrandCapability;
1015
+ authorityRef: string;
1016
+ }
1017
+ /** Safe directory projection exposed to an agent for Brand attribution. */
1018
+ interface BrandPrincipalProjection {
1019
+ id: string;
1020
+ displayName: string;
1021
+ kind: "human" | "agent" | "service";
1022
+ managerDisplayName?: string;
1023
+ }
1024
+
569
1025
  /** The bot identity the skill writes as (`selfId` = the agent id carried in
570
1026
  * the book's `memberIds` roster and every audience snapshot). */
571
1027
  interface BrandSkillSelf {
@@ -573,6 +1029,32 @@ interface BrandSkillSelf {
573
1029
  kind: "bot";
574
1030
  displayName?: string;
575
1031
  }
1032
+ /** Server-enforced semantic bridge. Raw agent credentials must be denied all
1033
+ * Brand namespace writes and raw file operations. */
1034
+ interface BrandAgentBridge {
1035
+ createProposal(input: {
1036
+ jobId: string;
1037
+ bookId: string;
1038
+ mutationId: string;
1039
+ kind: ProposalKind;
1040
+ payload: Record<string, unknown>;
1041
+ rationale: string;
1042
+ sourceAssetId?: string;
1043
+ }): Promise<BrandProposal>;
1044
+ recordAssetAnalysis(input: {
1045
+ jobId: string;
1046
+ mutationId: string;
1047
+ bookId: string;
1048
+ assetId: string;
1049
+ analysis: AssetAnalysis;
1050
+ expectedAnalysisRevision: number;
1051
+ }): Promise<BrandAsset>;
1052
+ readAssetContent(input: {
1053
+ jobId: string;
1054
+ bookId: string;
1055
+ assetId: string;
1056
+ }): Promise<BrandFetchedBytes>;
1057
+ }
576
1058
  /** Options for {@link brandSkill}. */
577
1059
  interface BrandSkillOpts {
578
1060
  /** The injected odla client (a real @odla-ai/db AdminDb satisfies it). */
@@ -581,10 +1063,27 @@ interface BrandSkillOpts {
581
1063
  bookId: string;
582
1064
  /** The bot identity acting through these tools. */
583
1065
  self: BrandSkillSelf;
584
- /** Origin prefixed onto relative asset urls (`url` starting with `/`). */
585
- fileBaseUrl: string;
586
- /** Asset-byte fetcher override (default: global fetch via resolveDeps). */
587
- fetchBytes?: (url: string) => Promise<BrandFetchedBytes>;
1066
+ /** Host attestation for the rules-scoped credential behind `db`. */
1067
+ agentDbBinding: {
1068
+ principalId: string;
1069
+ credentialRef: string;
1070
+ };
1071
+ /** Active verified agent job; the bridge derives message/turn provenance. */
1072
+ agentJobId: string;
1073
+ agentBridge: BrandAgentBridge;
1074
+ /** Host verification against the live principal grant. Missing/denied hooks
1075
+ * fail closed; roster membership is visibility, not authority. */
1076
+ authorizeCapability: (input: {
1077
+ agentId: string;
1078
+ bookId: string;
1079
+ capability: BrandCapability;
1080
+ }) => Promise<BrandCapabilityAuthority | null> | BrandCapabilityAuthority | null;
1081
+ /** Bounded host directory projection for conversational display only. */
1082
+ resolvePrincipals: (input: {
1083
+ requesterAgentId: string;
1084
+ bookId: string;
1085
+ principalIds: string[];
1086
+ }) => Promise<BrandPrincipalProjection[]>;
588
1087
  /** False when the model cannot take image/document blocks inside a
589
1088
  * tool_result — view_asset then steers to the pre-turn attachment path. */
590
1089
  visionInToolResults?: boolean;
@@ -598,12 +1097,27 @@ interface BrandToolCtx {
598
1097
  db: BrandDb;
599
1098
  bookId: string;
600
1099
  self: BrandSkillSelf;
601
- fileBaseUrl: string;
602
- fetchBytes: (url: string) => Promise<BrandFetchedBytes>;
603
1100
  /** Whether image/document blocks may be returned inside tool results. */
604
1101
  visionInToolResults: boolean;
605
1102
  now: () => number;
606
1103
  newId: () => string;
1104
+ agentJobId: string;
1105
+ createProposal(input: {
1106
+ mutationId: string;
1107
+ kind: ProposalKind;
1108
+ payload: Record<string, unknown>;
1109
+ rationale: string;
1110
+ sourceAssetId?: string;
1111
+ }): Promise<BrandProposal>;
1112
+ recordAssetAnalysis(input: {
1113
+ mutationId: string;
1114
+ assetId: string;
1115
+ analysis: AssetAnalysis;
1116
+ expectedAnalysisRevision: number;
1117
+ }): Promise<BrandAsset>;
1118
+ readAssetContent(assetId: string): Promise<BrandFetchedBytes>;
1119
+ resolvePrincipals(ids: string[]): Promise<BrandPrincipalProjection[]>;
1120
+ authority(capability: BrandCapability): Promise<BrandCapabilityAuthority>;
607
1121
  /** Load the scoped book row; throws BrandNotFoundError when missing. */
608
1122
  loadBook(): Promise<BrandBook>;
609
1123
  /** Wrap a handler so Brand validation errors come back as actionable
@@ -638,17 +1152,13 @@ declare function base64FromBytes(bytes: Uint8Array): string;
638
1152
  */
639
1153
  declare function assetTools(ctx: BrandToolCtx): ToolDef[];
640
1154
 
641
- /**
642
- * The book tools: `update_section` (validated per-kind content, upserted by
643
- * natural key with the book's audience snapshot) and `compile_tokens`
644
- * (palette + typography → light/dark token cache on the book row).
645
- */
1155
+ /** `update_section` validates a draft and parks it as an OPEN proposal. */
646
1156
  declare function bookTools(ctx: BrandToolCtx): ToolDef[];
647
1157
 
648
1158
  /**
649
1159
  * The palette tools: `analyze_color`, `evaluate_contrast` (pure math),
650
1160
  * `propose_palette` (writes an OPEN proposal with an automatic contrast
651
- * report), and `resolve_proposal` (applies the human's explicit verdict).
1161
+ * report). Resolution is deliberately not an agent tool.
652
1162
  */
653
1163
  declare function paletteTools(ctx: BrandToolCtx): ToolDef[];
654
1164
 
@@ -699,15 +1209,71 @@ declare function supportsBrandVision(spec: BrandVisionSpec | null | undefined):
699
1209
  */
700
1210
  declare function readTools(ctx: BrandToolCtx): ToolDef[];
701
1211
 
1212
+ type BrandRouteCapability = "brand.edit" | "app.manage";
1213
+ type BrandRouteEffect = "internal" | "destructive";
1214
+ interface BrandRouteAuthority {
1215
+ authorityRef: string;
1216
+ actorPrincipalId: string;
1217
+ capability: BrandRouteCapability;
1218
+ effect: BrandRouteEffect;
1219
+ }
702
1220
  /** Everything {@link import("./index").createBrandRoutes} needs from the host worker. */
703
1221
  interface BrandRouteOpts {
704
1222
  /** The injected odla client (a real @odla-ai/db AdminDb satisfies it). */
705
1223
  db: BrandDb;
1224
+ /** Registry app that owns the book rows and central authority records. */
1225
+ appId: string;
706
1226
  /** Host-owned auth: resolve the request to an actor or null (→ 401). The
707
1227
  * tokens routes skip this only when `publicTokens` is true. */
708
1228
  authorize: (req: Request) => Promise<BrandActor | null> | BrandActor | null;
1229
+ /** Optional host-owned authority seam for read-only Discussion reference
1230
+ * lookup. Verify exact Brand product, brand.read capability, canonical
1231
+ * audience, principal, current app lifetime/environment, and agent grant
1232
+ * provenance here; when omitted, the ordinary request authorizer is used. */
1233
+ authorizeDiscussionReferences?: (req: Request) => Promise<BrandActor | null> | BrandActor | null;
1234
+ /** Live host verification for worker-mediated effects. The callback must
1235
+ * verify the direct human credential, current app owner/co-owner status,
1236
+ * exact capability/effect/resource, and return null on any uncertainty. */
1237
+ authorizeCapability: (input: {
1238
+ req: Request;
1239
+ actor: BrandActor;
1240
+ appId: string;
1241
+ bookId?: string;
1242
+ capability: BrandRouteCapability;
1243
+ effect: BrandRouteEffect;
1244
+ }) => Promise<BrandRouteAuthority | null> | BrandRouteAuthority | null;
1245
+ /** Consume or idempotently replay one registry `human_exact` authority use,
1246
+ * then reload and authenticate its immutable central receipt. Missing,
1247
+ * synthetic, cached, or unverifiable authority must return null. */
1248
+ consumeHumanExact: (input: {
1249
+ req: Request;
1250
+ actor: BrandActor;
1251
+ appId: string;
1252
+ capability: "brand.proposal.resolve";
1253
+ projectCapability: "brand.approve";
1254
+ effect: "internal";
1255
+ resource: {
1256
+ bookId: string;
1257
+ proposalId: string;
1258
+ };
1259
+ actionDigest: string;
1260
+ consumptionIdempotencyKey: string;
1261
+ }) => Promise<BrandHumanAuthorityConsumption | null> | BrandHumanAuthorityConsumption | null;
1262
+ /** Re-read the private object and authenticate the exact snapshot captured
1263
+ * by the agent bridge. This must verify path, ETag, size, and SHA-256 bytes;
1264
+ * returning false prevents authority consumption and the local effect. */
1265
+ verifySourceAssetSnapshot: (input: {
1266
+ req: Request;
1267
+ appId: string;
1268
+ bookId: string;
1269
+ assetId: string;
1270
+ path: string;
1271
+ snapshot: BrandSourceAssetSnapshot;
1272
+ }) => Promise<boolean> | boolean;
709
1273
  /** Mount point. Default "/api/brand". */
710
1274
  basePath?: string;
1275
+ /** Native UI mount used by returned Discussion deep links. Default "/". */
1276
+ discussionBasePath?: string;
711
1277
  /** Upload size cap in bytes (checked against `File.size`). Default 8 MiB. */
712
1278
  maxUploadBytes?: number;
713
1279
  /** Serve `GET /books/:id/tokens.css` and `tokens.json` without authorize —
@@ -721,12 +1287,20 @@ interface BrandRouteOpts {
721
1287
  /** Per-request context handed to the authorized route handlers. */
722
1288
  interface BrandRouteCtx {
723
1289
  db: BrandDb;
1290
+ appId: string;
724
1291
  actor: BrandActor;
1292
+ authorizeCapability: BrandRouteOpts["authorizeCapability"];
1293
+ consumeHumanExact: BrandRouteOpts["consumeHumanExact"];
1294
+ verifySourceAssetSnapshot: BrandRouteOpts["verifySourceAssetSnapshot"];
725
1295
  now: () => number;
726
1296
  newId: () => string;
727
1297
  maxUploadBytes: number;
1298
+ discussionBasePath: string;
728
1299
  }
729
1300
 
1301
+ /** Freeze the exact OPEN proposal fields a reviewer sees. */
1302
+ declare function proposalReviewSnapshot(proposal: BrandProposal): BrandProposalReviewSnapshot;
1303
+
730
1304
  /**
731
1305
  * Build the brand fetch handler. Returns `null` for requests outside
732
1306
  * `basePath` (default `/api/brand`) so the host worker falls through to its
@@ -737,11 +1311,13 @@ interface BrandRouteCtx {
737
1311
  */
738
1312
  declare function createBrandRoutes(options: BrandRouteOpts): (req: Request) => Promise<Response | null>;
739
1313
 
740
- /** The dispatch envelope odla-db's commit hook POSTs when a trigger fires —
741
- * the same wire shape chat-agent consumes (see the header provenance note). */
1314
+ /** Versioned, host-authenticated envelope for one Brand agent turn. */
742
1315
  interface BrandDispatchBody {
743
- v: number;
1316
+ v: 2;
744
1317
  appId: string;
1318
+ /** Exact Registry app lifetime admitted by the durable Server job. */
1319
+ appIncarnation: string;
1320
+ jobId: string;
745
1321
  trigger: {
746
1322
  id: string;
747
1323
  skill: string;
@@ -757,61 +1333,61 @@ interface BrandDispatchBody {
757
1333
  row: Record<string, unknown>;
758
1334
  };
759
1335
  }
760
- /**
761
- * Validate an untrusted dispatch body; null if malformed. SHAPE-only,
762
- * mirroring chat-agent's parseDispatch: it does NOT gate on `trigger.skill` —
763
- * routing on skill is the HOST's job (a worker serving several skills checks
764
- * `body.trigger.skill === "brand"` before calling {@link dispatchBrandTurn}),
765
- * so an absent skill parses as `""`, never silently defaulted to "brand".
766
- */
767
- declare function parseBrandDispatch(raw: unknown): BrandDispatchBody | null;
768
- /** The brand book bound to a chat channel (`brand_book.channelId`), or null
769
- * when the channel id is empty or no book claims it. */
770
- declare function bookForChannel(db: BrandDb, channelId: string): Promise<BrandBook | null>;
771
- /**
772
- * The agent-turn input for a dispatched message: a brand-flavored prompt
773
- * (mirrors chat-agent's `inputFor` tone, steering into the brand workflow),
774
- * and — when pre-turn `attachments` are supplied (the no-vision-in-tool-
775
- * results path) — an explicit block array with the images BEFORE the text.
776
- */
777
- declare function brandInputFor(body: BrandDispatchBody, attachments?: ImageBlock[]): string | OracleContentBlock[];
778
- /** Everything {@link dispatchBrandTurn} needs from the host worker. The
779
- * @odla-ai/ai pieces (`inference`, `runAgent`) are injected so this module
780
- * keeps the package's types-only relationship with the peer. */
1336
+ /** Trusted host seams required to run one capability-bound Brand agent turn. */
781
1337
  interface BrandDispatchDeps {
782
- /** The injected odla client (a real @odla-ai/db AdminDb satisfies it). */
1338
+ /** Service read client; never handed to agent tools. */
783
1339
  db: BrandDb;
784
- /** The @odla-ai/ai inference facade the turn runs on. */
1340
+ appId: string;
1341
+ /** Host-created runtime bound to this verified dispatch + exact agent. */
1342
+ agentRuntimeFor: (input: {
1343
+ appId: string;
1344
+ agentId: string;
1345
+ bookId: string;
1346
+ triggerId: string;
1347
+ eventId: string;
1348
+ jobId: string;
1349
+ }) => Promise<{
1350
+ db: BrandDb;
1351
+ credentialRef: string;
1352
+ jobId: string;
1353
+ bridge: BrandAgentBridge;
1354
+ }>;
1355
+ authorizeCapability: (input: {
1356
+ agentId: string;
1357
+ bookId: string;
1358
+ capability: "brand.read" | "brand.edit";
1359
+ }) => Promise<BrandCapabilityAuthority | null> | BrandCapabilityAuthority | null;
1360
+ resolvePrincipals: (input: {
1361
+ requesterAgentId: string;
1362
+ bookId: string;
1363
+ principalIds: string[];
1364
+ }) => Promise<BrandPrincipalProjection[]>;
785
1365
  inference: Inference;
786
- /** Canonical model id for the persona. */
787
1366
  model: string;
788
- /** The agent loop — pass @odla-ai/ai's `runAgent`. */
789
1367
  runAgent: (inference: Inference, persona: Persona, input: AgentRunInput) => Promise<{
790
1368
  finalText: string;
791
1369
  }>;
792
- /** Origin prefixed onto relative asset urls (skill + pre-turn attachments). */
793
- fileBaseUrl: string;
794
- /** Optional stable id factory for durable whole-turn retries. */
795
1370
  newId?: () => string;
796
- /** Optional chat-skill factory (e.g. wrapping @odla-ai/chat's chatSkill) so
797
- * the bot can reply in the triggering channel. */
798
1371
  chatSkillFor?: (channelId: string, self: BrandSkillSelf) => Skill;
799
- /** Model catalog slice (model id → capability spec) for the vision probe;
800
- * an absent catalog or unknown model fails safe to the pre-turn path. */
801
1372
  catalog?: Record<string, BrandVisionSpec>;
802
1373
  }
803
- /**
804
- * Run one brand-agent turn for a dispatched chat message: resolve the book
805
- * via the row's `channelId` (throws {@link BrandNotFoundError} when no book
806
- * claims the channel), probe `supportsBrandVision(catalog[model])`, build the
807
- * persona (brand skill + optional chat skill, bot identity from
808
- * `trigger.runAs`), and run the loop. When the model can NOT take blocks in
809
- * tool results, assets are attached PRE-TURN as URL image blocks v1 keeps
810
- * detection simple: only when the message row carries an `assetIds` array
811
- * (no body-text scraping), and only live image assets.
812
- */
1374
+
1375
+ /** Reload message attachment ids against the exact live linked Brand book. */
1376
+ declare function attachedBrandAssetIds(db: BrandDb, book: BrandBook, row: Record<string, unknown>): Promise<string[]>;
1377
+
1378
+ /** Strict-enough structural parse for the signed host dispatch envelope. */
1379
+ declare function parseBrandDispatch(raw: unknown): BrandDispatchBody | null;
1380
+ /** Channel ids are unique by schema, but ambiguity still fails closed if a
1381
+ * legacy/corrupt store returns more than one row. */
1382
+ declare function bookForChannel(db: BrandDb, channelId: string): Promise<BrandBook | null>;
1383
+ /** Assemble the conversational request. Attachments remain supported as a
1384
+ * pure helper, but secure dispatch does not pass signed/private URLs here. */
1385
+ declare function brandInputFor(body: BrandDispatchBody, attachments?: ImageBlock[], author?: BrandPrincipalProjection, attachedAssetIds?: readonly string[]): string | OracleContentBlock[];
1386
+ /** Preflight exact app/skill/channel/roster/live brand.read before the model
1387
+ * is invoked. Every tool revalidates its own read/edit capability as well. */
813
1388
  declare function dispatchBrandTurn(deps: BrandDispatchDeps, body: BrandDispatchBody): Promise<{
814
1389
  finalText: string;
1390
+ durableOutcome: boolean;
815
1391
  }>;
816
1392
 
817
1393
  /** The odla-db namespace chat messages live in.
@@ -903,6 +1479,8 @@ interface BrandIntegrationDescriptor {
903
1479
  rules: BrandRules;
904
1480
  /** Commit triggers to register at /app/:id/admin/triggers (per-bot; app-supplied). */
905
1481
  triggers: BrandTrigger[];
1482
+ /** Least-privilege agent capabilities and semantic-operation boundary. */
1483
+ agentProfile: BrandAgentProfile;
906
1484
  probes?: BrandIntegrationProbe[];
907
1485
  provision: IntegrationProvision;
908
1486
  }
@@ -935,4 +1513,4 @@ interface CreateBrandIntegrationOptions {
935
1513
  */
936
1514
  declare function createBrandIntegration(options?: CreateBrandIntegrationOptions): BrandIntegrationDescriptor;
937
1515
 
938
- export { ASSET_CONTENT_TYPES, type AcceptProposalInput, AssetAnalysis, AssetKind, type AttrType, type AudienceChildren, BRAND_INSTRUCTIONS, BRAND_RULES, BRAND_SCHEMA, BrandActor, BrandBook, type BrandBotTriggerOpts, BrandDb, type BrandDeps, type BrandDispatchBody, type BrandDispatchDeps, BrandEntityRef, type BrandFetchedBytes, BrandInputError, type BrandIntegrationDescriptor, type BrandIntegrationProbe, BrandNotFoundError, BrandOp, BrandProposal, type BrandRouteCtx, type BrandRouteOpts, type BrandRule, type BrandRules, type BrandSkillOpts, type BrandSkillSelf, type BrandToolCtx, type BrandTrigger, type BrandVisionCapabilities, type BrandVisionSpec, CHART_DELTA_MIN, CHAT_MESSAGE_NS, CSS_NAMED_COLORS, type ContrastKind, type CreateAssetInput, type CreateBookInput, type CreateBrandIntegrationOptions, type CreateBrandPersonaOpts, DEFAULT_BRAND_SYSTEM, type DeriveChartOptions, type DerivePaletteOptions, type Hsl, type IntegrationProvision, type IntegrationSecret, type IntegrationSetting, type LightnessDirection, MAX_SWATCHES, MAX_VIEW_BYTES, type NamedColor, type NearestNamedColor, type Oklab, type Oklch, PICK_TEXT_DEFAULT_CANDIDATES, type ProposePaletteInput, RAMP_L_MAX, RAMP_L_MIN, type RejectProposalInput, type ResolvedBrandDeps, type Rgb, SectionKind, SectionStatus, type SerializedAttr, type SerializedEntity, type SerializedLink, type SerializedLinkEnd, type SerializedSchema, Swatch, type UpsertSectionInput, acceptProposalOps, adjustLightnessUntil, analogous, assertAnalysis, assertAssetContentType, assertHex, assertSectionContent, assertSwatches, assetTools, audienceFanoutOps, base64FromBytes, bookForChannel, bookTools, brandBotTrigger, brandInputFor, brandIntegration, brandRules, brandSkill, capString, capStringArray, clamp01, clampToGamut, complementary, contrastRatio, createAssetOps, createBookOps, createBrandIntegration, createBrandPersona, createBrandRoutes, deltaEOK, deltaEOKLab, deriveChartColors, derivePalette, dispatchBrandTurn, hexToOklch, hslToRgb, inSrgbGamut, linearToSrgb, meetsAA, meetsAAA, monochrome, nearestNamedColor, normalizeHex, oklabToOklch, oklabToRgb, oklchToHex, oklchToOklab, paletteTools, parseBrandDispatch, parseHex, pickTextOn, proposePaletteOps, readTools, recordAnalysisOps, rejectProposalOps, relativeLuminance, resolveDeps, rgbToHsl, rgbToOklab, rotateHue, safeFileName, sectionKey, splitComplementary, srgbToLinear, supportsBrandVision, tetradic, tintShadeRamp, toHex, tombstoneAssetOps, triadic, updateBookOps, upsertSectionOps };
1516
+ export { ASSET_CONTENT_TYPES, type AcceptProposalInput, AssetAnalysis, AssetKind, type AttrType, type AudienceChildren, BRAND_AGENT_PROFILE, BRAND_DISCUSSION_REFERENCE_KINDS, BRAND_INSTRUCTIONS, BRAND_RULES, BRAND_SCHEMA, BookStatus, type BrandActor, type BrandAgentBridge, type BrandAgentProfile, type BrandApprovalReceipt, type BrandAsset, type BrandAttrs, type BrandBook, type BrandBotTriggerOpts, type BrandCapabilityAuthority, BrandConflictError, type BrandDb, type BrandDecisionBinding, type BrandDeps, type BrandDiscussionReference, type BrandDiscussionReferenceKind, type BrandDiscussionReferenceTarget, type BrandDispatchBody, type BrandDispatchDeps, type BrandEntityRef, type BrandFetchedBytes, type BrandFileRecord, BrandForbiddenError, BrandGoneError, type BrandHumanAuthorityConsumption, BrandInputError, type BrandIntegrationDescriptor, type BrandIntegrationProbe, type BrandLookup, BrandNotFoundError, type BrandOp, type BrandPalette, type BrandPrincipalProjection, type BrandProposal, type BrandProposalProvenance, type BrandProposalReviewSnapshot, type BrandResult, BrandReviewStateChangedError, type BrandRouteCtx, type BrandRouteOpts, type BrandRow, type BrandRule, type BrandRules, type BrandScalar, type BrandSection, type BrandSkillOpts, type BrandSkillSelf, type BrandSourceAssetSnapshot, type BrandStorage, BrandTokensSnapshot, type BrandToolCtx, type BrandTransactGuard, type BrandTransactOptions, type BrandTrigger, type BrandUploadBody, type BrandVisionCapabilities, type BrandVisionSpec, CHART_DELTA_MIN, CHAT_MESSAGE_NS, CSS_NAMED_COLORS, type ContrastKind, type CreateAssetInput, type CreateBookInput, type CreateBrandIntegrationOptions, type CreateBrandPersonaOpts, DEFAULT_BRAND_SYSTEM, type DeriveChartOptions, type DerivePaletteOptions, type Hsl, type IntegrationProvision, type IntegrationSecret, type IntegrationSetting, type LightnessDirection, MAX_SWATCHES, MAX_VIEW_BYTES, type NamedColor, type NearestNamedColor, type Oklab, type Oklch, PICK_TEXT_DEFAULT_CANDIDATES, PaletteSource, PaletteStatus, ProposalKind, ProposalStatus, type ProposePaletteInput, type ProposeSectionInput, RAMP_L_MAX, RAMP_L_MIN, type RejectProposalInput, type ResolvedBrandDeps, type Rgb, SectionKind, SectionStatus, type SerializedAttr, type SerializedEntity, type SerializedLink, type SerializedLinkEnd, type SerializedSchema, Swatch, type UpsertSectionInput, acceptProposalOps, adjustLightnessUntil, analogous, assertAnalysis, assertAssetContentType, assertHex, assertSectionContent, assertSwatches, assetTools, attachedBrandAssetIds, audienceFanoutOps, base64FromBytes, beginAssetDeleteOps, bookForChannel, bookTools, brandAuthorityRef, brandBotTrigger, brandDiscussionReferenceHref, brandDiscussionReferenceId, brandInputFor, brandIntegration, brandJsonDigest, brandRules, brandSkill, canonicalBrandJson, capString, capStringArray, clamp01, clampToGamut, complementary, contrastRatio, createAssetOps, createBookOps, createBrandIntegration, createBrandPersona, createBrandRoutes, deltaEOK, deltaEOKLab, deriveChartColors, derivePalette, dispatchBrandTurn, finishAssetDeleteOps, formatBrandDiscussionReference, hexToOklch, hslToRgb, inSrgbGamut, isBoundedBrandJson, isBrandHumanAuthorityConsumption, linearToSrgb, meetsAA, meetsAAA, monochrome, nearestNamedColor, normalizeHex, oklabToOklch, oklabToRgb, oklchToHex, oklchToOklab, paletteTools, parseBrandDiscussionReference, parseBrandDispatch, parseHex, pickTextOn, proposalReviewSnapshot, proposePaletteOps, proposeSectionOps, readTools, recordAnalysisOps, rejectProposalOps, relativeLuminance, resolveDeps, rgbToHsl, rgbToOklab, rotateHue, safeFileName, sectionKey, splitComplementary, srgbToLinear, supportsBrandVision, tetradic, tintShadeRamp, toHex, triadic, updateBookOps, upsertSectionOps, verifyBrandApprovalReceipt };