@odla-ai/brand 0.8.1 → 0.8.3

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
@@ -650,7 +650,15 @@ declare function assertAnalysis(value: unknown): AssetAnalysis;
650
650
  * and the `createdAt` beside it disagreed at all.
651
651
  */
652
652
  declare function rowAsWritten<T>(ns: string, row: T): T;
653
- /** A stored approval receipt in the shape it was written. */
653
+ /** A stored approval receipt in the shape it was written.
654
+ *
655
+ * The store adds `$createdAt`, `$createdBy`, `$updatedAt`, and `$updatedBy` to
656
+ * every row after Brand has computed the immutable receipt digest. Those
657
+ * provenance attrs are trustworthy store metadata, but they are not part of
658
+ * the receipt that was signed and must not be fed to its exact-shape verifier
659
+ * or digest. Strip every reserved `$` attr here so both dependency reads and
660
+ * mutation-id replays verify the same bytes Brand originally wrote.
661
+ */
654
662
  declare function receiptAsWritten<T>(row: T): T;
655
663
  /** A stored proposal in the shape it was written, so `reviewDigest` matches. */
656
664
  declare function proposalAsWritten<T>(row: T): T;
package/dist/index.d.ts CHANGED
@@ -650,7 +650,15 @@ declare function assertAnalysis(value: unknown): AssetAnalysis;
650
650
  * and the `createdAt` beside it disagreed at all.
651
651
  */
652
652
  declare function rowAsWritten<T>(ns: string, row: T): T;
653
- /** A stored approval receipt in the shape it was written. */
653
+ /** A stored approval receipt in the shape it was written.
654
+ *
655
+ * The store adds `$createdAt`, `$createdBy`, `$updatedAt`, and `$updatedBy` to
656
+ * every row after Brand has computed the immutable receipt digest. Those
657
+ * provenance attrs are trustworthy store metadata, but they are not part of
658
+ * the receipt that was signed and must not be fed to its exact-shape verifier
659
+ * or digest. Strip every reserved `$` attr here so both dependency reads and
660
+ * mutation-id replays verify the same bytes Brand originally wrote.
661
+ */
654
662
  declare function receiptAsWritten<T>(row: T): T;
655
663
  /** A stored proposal in the shape it was written, so `reviewDigest` matches. */
656
664
  declare function proposalAsWritten<T>(row: T): T;
package/dist/index.js CHANGED
@@ -366,7 +366,13 @@ function rowAsWritten(ns, row) {
366
366
  return changed ? out : row;
367
367
  }
368
368
  function receiptAsWritten(row) {
369
- return rowAsWritten(BRAND_NS.approvalReceipt, row);
369
+ const normalized = rowAsWritten(BRAND_NS.approvalReceipt, row);
370
+ if (!record(normalized)) return normalized;
371
+ const systemAttrs = Object.keys(normalized).filter((key) => key.startsWith("$"));
372
+ if (systemAttrs.length === 0) return normalized;
373
+ const out = { ...normalized };
374
+ for (const key of systemAttrs) delete out[key];
375
+ return out;
370
376
  }
371
377
  function proposalAsWritten(row) {
372
378
  return rowAsWritten(BRAND_NS.proposal, row);
@@ -3291,7 +3297,10 @@ async function activePalette(ctx, book) {
3291
3297
  book: {}
3292
3298
  }
3293
3299
  });
3294
- const palette = (result[BRAND_NS.palette] ?? [])[0];
3300
+ const palette = rowAsWritten(
3301
+ BRAND_NS.palette,
3302
+ (result[BRAND_NS.palette] ?? [])[0]
3303
+ );
3295
3304
  if (!palette || palette.bookId !== book.id || palette.status !== "active" || !palette.proposalId || !palette.approvalReceiptId || !palette.approvalActionDigest || !hasExactOneLink(palette.book, book.id)) throw new BrandConflictError(
3296
3305
  "active palette is missing valid approval provenance"
3297
3306
  );
@@ -3339,7 +3348,10 @@ async function approvedTypography(ctx, book) {
3339
3348
  book: {}
3340
3349
  }
3341
3350
  });
3342
- const section = (result[BRAND_NS.section] ?? [])[0];
3351
+ const section = rowAsWritten(
3352
+ BRAND_NS.section,
3353
+ (result[BRAND_NS.section] ?? [])[0]
3354
+ );
3343
3355
  if (!section || section.status !== "approved") return {};
3344
3356
  if (section.bookId !== book.id || section.kind !== "typography" || !section.approvalReceiptId || !section.approvalActionDigest || !hasExactOneLink(section.book, book.id)) throw new BrandConflictError(
3345
3357
  "approved typography is missing valid approval provenance"