@bitcobblers/wod-wiki-core 0.44.2159 → 0.45.2166

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
@@ -1117,6 +1117,28 @@ interface WorkoutResults {
1117
1117
  completed: boolean;
1118
1118
  }
1119
1119
 
1120
+ /**
1121
+ * Feed identity — the source-side vocabulary.
1122
+ *
1123
+ * A **feed** is one published directory the app subscribes to and syncs as a
1124
+ * unit (the glossary's *Feed*). The word "seed" no longer names a source:
1125
+ * a registered source is a feed, its id is a feed id, and the artifact it
1126
+ * serves is a **Seed** (see `SeedManifest` in the engine's seed contract).
1127
+ *
1128
+ * A registered feed has ONE id — the registry id, `FeedSource.id` — and
1129
+ * that id is also the note's `feedSourceId` and the suffix of the import
1130
+ * checkpoint key (`seed:<id>`, whose `seed:` prefix is a persisted wire
1131
+ * format, not a source name).
1132
+ */
1133
+ /** A feed identifier — the id of one registered feed source. */
1134
+ type FeedId = string;
1135
+ /**
1136
+ * How a record came to be: delivered by a feed (`'feed'`), or authored and
1137
+ * owned by the user (`'user'`). The feed-side twin of the artifact-side
1138
+ * `seedOrigin` (`'seed' | 'user'`) — the two agree on every imported note.
1139
+ */
1140
+ type FeedOrigin = 'feed' | 'user';
1141
+
1120
1142
  type NoteBlockKind = 'wod' | 'query' | 'widget' | 'embed';
1121
1143
  interface NoteBlock {
1122
1144
  id: string;
@@ -1138,7 +1160,7 @@ interface BlockRevision {
1138
1160
  dialect?: 'time' | 'log';
1139
1161
  sport?: string;
1140
1162
  }
1141
- type NoteKind = 'journal' | 'template' | 'playground' | 'feed' | 'dashboard' | 'page' | (string & {});
1163
+ type NoteKind = 'journal' | 'playground' | 'dashboard' | 'page' | 'note' | (string & {});
1142
1164
  interface Note {
1143
1165
  id: string;
1144
1166
  title: string;
@@ -1149,14 +1171,22 @@ interface Note {
1149
1171
  createdAt: number;
1150
1172
  type?: NoteKind;
1151
1173
  sourceId?: string;
1152
- catalog?: string;
1153
1174
  /** Canonical notebook identifier ('notebook/{slug}', e.g. 'notebook/journal', 'notebook/playground', 'notebook/guides'). */
1154
1175
  notebookId?: string;
1155
1176
  tags?: string[];
1177
+ /** Artifact provenance — which published bundle this note came from.
1178
+ * Persisted field names; the artifact they describe is a **Seed**. */
1156
1179
  seedOrigin?: 'seed' | 'user';
1157
1180
  seedVersion?: number;
1158
1181
  seedChunkId?: string;
1159
- /** Authored seed path used for deterministic identity and routing. */
1182
+ /** Feed provenance — 'feed' for a note a feed delivered, 'user' for one the
1183
+ * user owns. The two agree: a feed-delivered note is seed-delivered, and
1184
+ * vice versa. */
1185
+ feedOrigin?: FeedOrigin;
1186
+ /** The registered feed that delivered this note (the feed's own id).
1187
+ * Read from here alone — never from the seed stamps. */
1188
+ feedSourceId?: FeedId;
1189
+ /** Authored corpus path used for deterministic identity and routing. */
1160
1190
  sourcePath?: string;
1161
1191
  /** Git commit hash in which this note was published or changed. */
1162
1192
  seedCommit?: string;
@@ -1175,7 +1205,7 @@ interface PageNote {
1175
1205
  position?: number;
1176
1206
  createdAt: number;
1177
1207
  }
1178
- type TagType = 'template' | 'playground' | 'qualification' | 'notebook' | 'general' | (string & {});
1208
+ type TagType = 'playground' | 'qualification' | 'notebook' | 'general' | (string & {});
1179
1209
  interface TagTypeRecord {
1180
1210
  id: string;
1181
1211
  name: string;
@@ -1496,6 +1526,92 @@ interface Membership {
1496
1526
  updatedAt?: number;
1497
1527
  }
1498
1528
 
1529
+ /**
1530
+ * Page placement — the resolved form of one `page_notes` junction row.
1531
+ *
1532
+ * Placement is many-to-many: a note may sit on several pages (a calendar
1533
+ * day, a named collection, …) and a page may hold several notes. The
1534
+ * junction row is the only membership record; a note carries no page
1535
+ * reference of its own.
1536
+ *
1537
+ * One ordering decides everything placement-related — the **canonical
1538
+ * placement order**: explicit `position` first (smaller first, a row
1539
+ * without one last), then creation time, then the row id. It reads a
1540
+ * page's notes in order and picks the *primary* placement when only one
1541
+ * page may be shown.
1542
+ */
1543
+
1544
+ /** One placement of a note on a page. */
1545
+ interface NotePlacement {
1546
+ /** The page the note is placed on. */
1547
+ pageId: string;
1548
+ /** The note that is placed on the page. */
1549
+ noteId: string;
1550
+ /** Ordinal within the page, when the placement carries one. */
1551
+ position?: number;
1552
+ /** When the placement was created — the second ordering tie-breaker. */
1553
+ createdAt: number;
1554
+ /** Calendar date of the page, when the page is a date page. */
1555
+ date?: string;
1556
+ /** Route slug of the page, when the page is a named page. */
1557
+ slug?: string;
1558
+ /** Display title of the page, when it has one. */
1559
+ title?: string;
1560
+ }
1561
+ /**
1562
+ * A page addressed by its public identity — a calendar date (`date`) or a
1563
+ * named route (`slug`). A page row may carry both; either one resolves it.
1564
+ */
1565
+ interface PageTarget {
1566
+ /** YYYY-MM-DD — the calendar page for that day. */
1567
+ date?: string;
1568
+ /** Route slug — the named page for that route. */
1569
+ slug?: string;
1570
+ }
1571
+ /**
1572
+ * Canonical placement order: explicit position first (smaller first, a
1573
+ * row without a position last), then creation time, then the row id.
1574
+ *
1575
+ * A placement written without an explicit position therefore lands after
1576
+ * every positioned row — appending is the default.
1577
+ */
1578
+ declare function comparePlacements(a: PageNote, b: PageNote): number;
1579
+ /** The canonical placement order of a note's junction rows. */
1580
+ declare function orderPlacements(links: readonly PageNote[]): PageNote[];
1581
+ /**
1582
+ * Resolve junction rows into placements, in canonical order. Rows whose
1583
+ * page is missing are dropped — a placement without a page addresses
1584
+ * nothing.
1585
+ */
1586
+ declare function resolvePlacements(links: readonly PageNote[], pages: readonly Page[]): NotePlacement[];
1587
+ /**
1588
+ * The single-page projections of a note's placements.
1589
+ *
1590
+ * A note may sit on several pages, so `pageId`, `journalDate` and
1591
+ * `pageSlug` are projections — never the membership itself. The rule is
1592
+ * deterministic:
1593
+ *
1594
+ * - `pageId` — the page of the **primary placement**: the first placement
1595
+ * in the canonical placement order.
1596
+ * - `journalDate` — the date of the first calendar placement in that order.
1597
+ * - `pageSlug` — the slug of the first named placement (a page with a slug
1598
+ * and no date) in that order.
1599
+ *
1600
+ * A note placed on several pages keeps every placement; only these three
1601
+ * fields are narrowed, and they always name the same placements for the
1602
+ * same inputs.
1603
+ */
1604
+ interface PlacementProjection {
1605
+ /** The page id of the primary placement. */
1606
+ pageId?: string;
1607
+ /** The calendar date of the first calendar placement. */
1608
+ journalDate?: string;
1609
+ /** The route slug of the first named placement. */
1610
+ pageSlug?: string;
1611
+ }
1612
+ /** Project a note's placements onto the single-page fields. */
1613
+ declare function projectPlacements(placements: readonly NotePlacement[]): PlacementProjection;
1614
+
1499
1615
  /**
1500
1616
  * State of a WOD block
1501
1617
  */
@@ -1616,19 +1732,43 @@ interface SectionDocument {
1616
1732
  * (including the predefined default notebooks `notebook/journal`,
1617
1733
  * `notebook/playground`, and `notebook/guides`).
1618
1734
  */
1735
+
1619
1736
  /** Predefined default notebook slugs always present in the application. */
1620
- declare const DEFAULT_NOTEBOOK_SLUGS: readonly ["journal", "playground", "guides"];
1737
+ declare const DEFAULT_NOTEBOOK_SLUGS: readonly ["journal", "playground", "defaults", "guides"];
1621
1738
  type DefaultNotebookSlug = (typeof DEFAULT_NOTEBOOK_SLUGS)[number];
1622
1739
  type NotebookId = `notebook/${string}`;
1623
- type NotebookOrigin = 'default' | 'user' | 'seed';
1740
+ /** Where a notebook comes from. 'feed' = delivered by a feed (the feed that
1741
+ * delivers it is named by `feedEntryId`); 'user' = the user owns it;
1742
+ * 'default' = one of the predefined notebooks. */
1743
+ type NotebookOrigin = 'default' | 'user' | 'feed';
1624
1744
  /** Extract the bare slug from a `notebook/{slug}` or `notebook:{slug}` or bare identifier. */
1625
1745
  declare function notebookSlugFromId(slugOrId: string): string;
1626
1746
  /** Normalize any notebook slug or id to the canonical `notebook/{slug}` form. */
1627
1747
  declare function toNotebookId(slugOrId: string): NotebookId;
1628
- /** Application-level editability rule: only user-created notes (`seedOrigin !== 'seed'`) are editable. */
1748
+ /** Application-level editability rule (ticket 05): a note is editable when
1749
+ * its NOTEBOOK is user-owned. `notebookOrigin` is the origin of the note's
1750
+ * resolved notebook (`notebookOfItem` + the notebook registry) — feed-delivered
1751
+ * notebooks are read-only, and a note cloned into a user-owned notebook
1752
+ * (e.g. `notebook/defaults`) is editable even though it keeps its seed/feed
1753
+ * provenance stamps. Without a resolved notebook origin the decision falls
1754
+ * back to the note's own stamps, which match the registry answer for every
1755
+ * importer-written row. */
1629
1756
  declare function isNoteEditable(note: {
1630
1757
  seedOrigin?: string | null;
1631
- }): boolean;
1758
+ feedOrigin?: string | null;
1759
+ }, notebookOrigin?: NotebookOrigin): boolean;
1760
+ interface BuiltinNotebookSpec {
1761
+ slug: string;
1762
+ notebookId: NotebookId;
1763
+ name: string;
1764
+ description: string;
1765
+ icon: string;
1766
+ href: string;
1767
+ feedEntryId?: FeedId;
1768
+ seedChunkId?: string;
1769
+ }
1770
+ /** Single source of truth for always-present built-in and core reference notebooks. */
1771
+ declare const BUILTIN_NOTEBOOKS: readonly BuiltinNotebookSpec[];
1632
1772
  interface Notebook {
1633
1773
  /** Canonical `notebook/{slug}` identifier. */
1634
1774
  id: NotebookId | string;
@@ -1640,18 +1780,11 @@ interface Notebook {
1640
1780
  description: string;
1641
1781
  icon: string;
1642
1782
  origin: NotebookOrigin;
1643
- /** Registered seed source entry id where the source is pulled from. */
1644
- sourceEntryId?: string;
1645
- /** Seed package id when delivered by a named package slice. */
1646
- packageId?: string;
1647
- /** Seed directory URL where the source is pulled from. */
1648
- sourceUrl?: string;
1649
- /** Published Git repository URL when declared by the source entry. */
1650
- repositoryUrl?: string;
1783
+ /** Registered feed entry id — the feed that publishes this notebook. */
1784
+ feedEntryId?: FeedId;
1651
1785
  /** Seed manifest chunk id when delivered by a seed. */
1652
1786
  seedChunkId?: string;
1653
1787
  createdAt: number;
1654
- lastEditedAt: number;
1655
1788
  }
1656
1789
  declare const NOTEBOOK_TAG_PREFIX = "notebook:";
1657
1790
  declare const toNotebookTag: (notebookId: string) => string;
@@ -1759,13 +1892,13 @@ declare function patchFrontmatterProperty(raw: string, path: readonly string[],
1759
1892
  * Auto-generated build version metadata.
1760
1893
  * Do not edit directly; updated by scripts/stamp-version.ts
1761
1894
  */
1762
- declare const VERSION = "0.44.2159";
1763
- declare const GIT_SHA = "30e43c7";
1764
- declare const BUILD_TIME = "2026-10-24T23:07:22.311Z";
1895
+ declare const VERSION = "0.45.2166";
1896
+ declare const GIT_SHA = "32bda10";
1897
+ declare const BUILD_TIME = "2026-10-26T20:01:09.868Z";
1765
1898
  declare const SEMVER: {
1766
- readonly version: "0.44.2159";
1767
- readonly gitSha: "30e43c7";
1768
- readonly buildTime: "2026-10-24T23:07:22.311Z";
1899
+ readonly version: "0.45.2166";
1900
+ readonly gitSha: "32bda10";
1901
+ readonly buildTime: "2026-10-26T20:01:09.868Z";
1769
1902
  };
1770
1903
 
1771
- export { type AnalyticsDataPoint, type AnalyticsGraphConfig, type AnalyticsGroup, type Attachment, BUILD_TIME, type BlockEffort, type BlockEquipment, type BlockIndexRow, BlockKey, type BlockRevision, type CatalogBackfillState, CodeMetadata, CodeStatement, DEFAULT_NOTEBOOK_SLUGS, type DefaultNotebookSlug, type DialectAnalysis, type DimensionKey, type DisplayStatus, type EventGrain, type EventRecord, type FenceDialect, type FieldCatalogEntry, type FieldContribution, type FieldLeaf, type FieldRef, type FieldSourceRecord, type FieldValueKind, type FieldValueRecord, type FrontMatterSubtype, type FrontmatterPatchValue, GIT_SHA, type IBlockKey, type ICodeMetadata, type ICodeStatement, type IDialect, type IDialectTagDescriptor, type IMetric, type IMetricOwnershipResolver, type IMetricSource, type IOutputStatement, type IScript, type ITagSource, KNOWN_OUTPUT_TYPES, KNOWN_SECTION_WIDGETS, LEGACY_ORIGIN_TO_OWNERSHIP_LAYER, METRIC_OWNERSHIP_LAYER_CHAIN, type Membership, Metric, type MetricAction, MetricContainer, type MetricFilter, type MetricOrigin, type MetricOwnershipLayer, type MetricOwnershipLedger, type MetricOwnershipOutcome, type MetricOwnershipPromotionCandidate, type MetricOwnershipQuery, type MetricOwnershipResolvedContribution, type MetricOwnershipTypeExplanation, type MetricTemporal, MetricType, type MetricWithOptionalOwnershipLayer, NOTEBOOK_TAG_PREFIX, type Note, type NoteBlock, type NoteBlockChange, type NoteBlockKind, type NoteKind, type NoteTag, type Notebook, type NotebookId, type NotebookOrigin, type NullValueKind, type Origin, OutputStatement, type OutputStatementOptions, type OutputStatementType, OwnershipResolver, type Page, type PageNote, type ParseError, ParsedCodeStatement, REFERENCE_METADATA_KEY, type ReconcileNoteBlocksOptions, type ReducerStats, type ReferenceDiagnostic, type ReferenceDiagnosticReason, type ReferenceKind, type ReferenceMatchKind, type ReferenceMetadata, type ReferenceRef, type ResultOrigin, SEMVER, SYSTEM_DEFAULT_OUTPUT_UNIT, type ScriptBlock, type ScriptBlockState, type Section, type SectionDocument, type SectionRecognitionOptions, type SectionType, type Segment, type Session, type StoredOutputStatement, type SummaryCoverage, TAG_REFERENCE_METADATA_KEY, type Tag, type TagContribution, type TagDefinition, type TagFunctionContribution, type TagIndex, type TagMetricContribution, type TagReferenceMetadata, type TagTagContribution, type TagType, type TagTypeRecord, type TimeSpan, UNIT_CATALOG, UnitConversionError, type UnitDefinition, type UnitErrorCode, VALID_FENCE_DIALECTS, VERSION, type VisualizerFilter, type VisualizerSize, type WorkoutResults, type WorkoutSectionType, actionableSectionKind, blockContentId, buildRawContent, calculateTotalLines, convertViaCatalog, createMetricOwnershipLedger, createTagIndex, detectScriptBlocks, dimensionKeyOf, extractBlockContent, fieldRefFromKey, fieldRefKey, findBlockAtLine, flattenFieldLeaves, fromNotebookTag, getMetricOwnershipLayer, getReferenceMetadata, getTagReference, isNoteEditable, isNotebookTag, isWorkoutSectionType, lookupUnit, mapNoteBlockChanges, matchDialectFence, normalizeFieldComponent, normalizeFieldPath, notebookSlugFromId, ownershipRank, parseDocumentSections, patchFrontmatterProperty, reconcileNoteBlocks, resolveLayer, runAffordance, systemDefaultUnit, toNotebookId, toNotebookTag, validateNoteBlocks, valueKindOf };
1904
+ export { type AnalyticsDataPoint, type AnalyticsGraphConfig, type AnalyticsGroup, type Attachment, BUILD_TIME, BUILTIN_NOTEBOOKS, type BlockEffort, type BlockEquipment, type BlockIndexRow, BlockKey, type BlockRevision, type BuiltinNotebookSpec, type CatalogBackfillState, CodeMetadata, CodeStatement, DEFAULT_NOTEBOOK_SLUGS, type DefaultNotebookSlug, type DialectAnalysis, type DimensionKey, type DisplayStatus, type EventGrain, type EventRecord, type FeedId, type FeedOrigin, type FenceDialect, type FieldCatalogEntry, type FieldContribution, type FieldLeaf, type FieldRef, type FieldSourceRecord, type FieldValueKind, type FieldValueRecord, type FrontMatterSubtype, type FrontmatterPatchValue, GIT_SHA, type IBlockKey, type ICodeMetadata, type ICodeStatement, type IDialect, type IDialectTagDescriptor, type IMetric, type IMetricOwnershipResolver, type IMetricSource, type IOutputStatement, type IScript, type ITagSource, KNOWN_OUTPUT_TYPES, KNOWN_SECTION_WIDGETS, LEGACY_ORIGIN_TO_OWNERSHIP_LAYER, METRIC_OWNERSHIP_LAYER_CHAIN, type Membership, Metric, type MetricAction, MetricContainer, type MetricFilter, type MetricOrigin, type MetricOwnershipLayer, type MetricOwnershipLedger, type MetricOwnershipOutcome, type MetricOwnershipPromotionCandidate, type MetricOwnershipQuery, type MetricOwnershipResolvedContribution, type MetricOwnershipTypeExplanation, type MetricTemporal, MetricType, type MetricWithOptionalOwnershipLayer, NOTEBOOK_TAG_PREFIX, type Note, type NoteBlock, type NoteBlockChange, type NoteBlockKind, type NoteKind, type NotePlacement, type NoteTag, type Notebook, type NotebookId, type NotebookOrigin, type NullValueKind, type Origin, OutputStatement, type OutputStatementOptions, type OutputStatementType, OwnershipResolver, type Page, type PageNote, type PageTarget, type ParseError, ParsedCodeStatement, type PlacementProjection, REFERENCE_METADATA_KEY, type ReconcileNoteBlocksOptions, type ReducerStats, type ReferenceDiagnostic, type ReferenceDiagnosticReason, type ReferenceKind, type ReferenceMatchKind, type ReferenceMetadata, type ReferenceRef, type ResultOrigin, SEMVER, SYSTEM_DEFAULT_OUTPUT_UNIT, type ScriptBlock, type ScriptBlockState, type Section, type SectionDocument, type SectionRecognitionOptions, type SectionType, type Segment, type Session, type StoredOutputStatement, type SummaryCoverage, TAG_REFERENCE_METADATA_KEY, type Tag, type TagContribution, type TagDefinition, type TagFunctionContribution, type TagIndex, type TagMetricContribution, type TagReferenceMetadata, type TagTagContribution, type TagType, type TagTypeRecord, type TimeSpan, UNIT_CATALOG, UnitConversionError, type UnitDefinition, type UnitErrorCode, VALID_FENCE_DIALECTS, VERSION, type VisualizerFilter, type VisualizerSize, type WorkoutResults, type WorkoutSectionType, actionableSectionKind, blockContentId, buildRawContent, calculateTotalLines, comparePlacements, convertViaCatalog, createMetricOwnershipLedger, createTagIndex, detectScriptBlocks, dimensionKeyOf, extractBlockContent, fieldRefFromKey, fieldRefKey, findBlockAtLine, flattenFieldLeaves, fromNotebookTag, getMetricOwnershipLayer, getReferenceMetadata, getTagReference, isNoteEditable, isNotebookTag, isWorkoutSectionType, lookupUnit, mapNoteBlockChanges, matchDialectFence, normalizeFieldComponent, normalizeFieldPath, notebookSlugFromId, orderPlacements, ownershipRank, parseDocumentSections, patchFrontmatterProperty, projectPlacements, reconcileNoteBlocks, resolveLayer, resolvePlacements, runAffordance, systemDefaultUnit, toNotebookId, toNotebookTag, validateNoteBlocks, valueKindOf };
package/dist/index.d.ts CHANGED
@@ -1117,6 +1117,28 @@ interface WorkoutResults {
1117
1117
  completed: boolean;
1118
1118
  }
1119
1119
 
1120
+ /**
1121
+ * Feed identity — the source-side vocabulary.
1122
+ *
1123
+ * A **feed** is one published directory the app subscribes to and syncs as a
1124
+ * unit (the glossary's *Feed*). The word "seed" no longer names a source:
1125
+ * a registered source is a feed, its id is a feed id, and the artifact it
1126
+ * serves is a **Seed** (see `SeedManifest` in the engine's seed contract).
1127
+ *
1128
+ * A registered feed has ONE id — the registry id, `FeedSource.id` — and
1129
+ * that id is also the note's `feedSourceId` and the suffix of the import
1130
+ * checkpoint key (`seed:<id>`, whose `seed:` prefix is a persisted wire
1131
+ * format, not a source name).
1132
+ */
1133
+ /** A feed identifier — the id of one registered feed source. */
1134
+ type FeedId = string;
1135
+ /**
1136
+ * How a record came to be: delivered by a feed (`'feed'`), or authored and
1137
+ * owned by the user (`'user'`). The feed-side twin of the artifact-side
1138
+ * `seedOrigin` (`'seed' | 'user'`) — the two agree on every imported note.
1139
+ */
1140
+ type FeedOrigin = 'feed' | 'user';
1141
+
1120
1142
  type NoteBlockKind = 'wod' | 'query' | 'widget' | 'embed';
1121
1143
  interface NoteBlock {
1122
1144
  id: string;
@@ -1138,7 +1160,7 @@ interface BlockRevision {
1138
1160
  dialect?: 'time' | 'log';
1139
1161
  sport?: string;
1140
1162
  }
1141
- type NoteKind = 'journal' | 'template' | 'playground' | 'feed' | 'dashboard' | 'page' | (string & {});
1163
+ type NoteKind = 'journal' | 'playground' | 'dashboard' | 'page' | 'note' | (string & {});
1142
1164
  interface Note {
1143
1165
  id: string;
1144
1166
  title: string;
@@ -1149,14 +1171,22 @@ interface Note {
1149
1171
  createdAt: number;
1150
1172
  type?: NoteKind;
1151
1173
  sourceId?: string;
1152
- catalog?: string;
1153
1174
  /** Canonical notebook identifier ('notebook/{slug}', e.g. 'notebook/journal', 'notebook/playground', 'notebook/guides'). */
1154
1175
  notebookId?: string;
1155
1176
  tags?: string[];
1177
+ /** Artifact provenance — which published bundle this note came from.
1178
+ * Persisted field names; the artifact they describe is a **Seed**. */
1156
1179
  seedOrigin?: 'seed' | 'user';
1157
1180
  seedVersion?: number;
1158
1181
  seedChunkId?: string;
1159
- /** Authored seed path used for deterministic identity and routing. */
1182
+ /** Feed provenance — 'feed' for a note a feed delivered, 'user' for one the
1183
+ * user owns. The two agree: a feed-delivered note is seed-delivered, and
1184
+ * vice versa. */
1185
+ feedOrigin?: FeedOrigin;
1186
+ /** The registered feed that delivered this note (the feed's own id).
1187
+ * Read from here alone — never from the seed stamps. */
1188
+ feedSourceId?: FeedId;
1189
+ /** Authored corpus path used for deterministic identity and routing. */
1160
1190
  sourcePath?: string;
1161
1191
  /** Git commit hash in which this note was published or changed. */
1162
1192
  seedCommit?: string;
@@ -1175,7 +1205,7 @@ interface PageNote {
1175
1205
  position?: number;
1176
1206
  createdAt: number;
1177
1207
  }
1178
- type TagType = 'template' | 'playground' | 'qualification' | 'notebook' | 'general' | (string & {});
1208
+ type TagType = 'playground' | 'qualification' | 'notebook' | 'general' | (string & {});
1179
1209
  interface TagTypeRecord {
1180
1210
  id: string;
1181
1211
  name: string;
@@ -1496,6 +1526,92 @@ interface Membership {
1496
1526
  updatedAt?: number;
1497
1527
  }
1498
1528
 
1529
+ /**
1530
+ * Page placement — the resolved form of one `page_notes` junction row.
1531
+ *
1532
+ * Placement is many-to-many: a note may sit on several pages (a calendar
1533
+ * day, a named collection, …) and a page may hold several notes. The
1534
+ * junction row is the only membership record; a note carries no page
1535
+ * reference of its own.
1536
+ *
1537
+ * One ordering decides everything placement-related — the **canonical
1538
+ * placement order**: explicit `position` first (smaller first, a row
1539
+ * without one last), then creation time, then the row id. It reads a
1540
+ * page's notes in order and picks the *primary* placement when only one
1541
+ * page may be shown.
1542
+ */
1543
+
1544
+ /** One placement of a note on a page. */
1545
+ interface NotePlacement {
1546
+ /** The page the note is placed on. */
1547
+ pageId: string;
1548
+ /** The note that is placed on the page. */
1549
+ noteId: string;
1550
+ /** Ordinal within the page, when the placement carries one. */
1551
+ position?: number;
1552
+ /** When the placement was created — the second ordering tie-breaker. */
1553
+ createdAt: number;
1554
+ /** Calendar date of the page, when the page is a date page. */
1555
+ date?: string;
1556
+ /** Route slug of the page, when the page is a named page. */
1557
+ slug?: string;
1558
+ /** Display title of the page, when it has one. */
1559
+ title?: string;
1560
+ }
1561
+ /**
1562
+ * A page addressed by its public identity — a calendar date (`date`) or a
1563
+ * named route (`slug`). A page row may carry both; either one resolves it.
1564
+ */
1565
+ interface PageTarget {
1566
+ /** YYYY-MM-DD — the calendar page for that day. */
1567
+ date?: string;
1568
+ /** Route slug — the named page for that route. */
1569
+ slug?: string;
1570
+ }
1571
+ /**
1572
+ * Canonical placement order: explicit position first (smaller first, a
1573
+ * row without a position last), then creation time, then the row id.
1574
+ *
1575
+ * A placement written without an explicit position therefore lands after
1576
+ * every positioned row — appending is the default.
1577
+ */
1578
+ declare function comparePlacements(a: PageNote, b: PageNote): number;
1579
+ /** The canonical placement order of a note's junction rows. */
1580
+ declare function orderPlacements(links: readonly PageNote[]): PageNote[];
1581
+ /**
1582
+ * Resolve junction rows into placements, in canonical order. Rows whose
1583
+ * page is missing are dropped — a placement without a page addresses
1584
+ * nothing.
1585
+ */
1586
+ declare function resolvePlacements(links: readonly PageNote[], pages: readonly Page[]): NotePlacement[];
1587
+ /**
1588
+ * The single-page projections of a note's placements.
1589
+ *
1590
+ * A note may sit on several pages, so `pageId`, `journalDate` and
1591
+ * `pageSlug` are projections — never the membership itself. The rule is
1592
+ * deterministic:
1593
+ *
1594
+ * - `pageId` — the page of the **primary placement**: the first placement
1595
+ * in the canonical placement order.
1596
+ * - `journalDate` — the date of the first calendar placement in that order.
1597
+ * - `pageSlug` — the slug of the first named placement (a page with a slug
1598
+ * and no date) in that order.
1599
+ *
1600
+ * A note placed on several pages keeps every placement; only these three
1601
+ * fields are narrowed, and they always name the same placements for the
1602
+ * same inputs.
1603
+ */
1604
+ interface PlacementProjection {
1605
+ /** The page id of the primary placement. */
1606
+ pageId?: string;
1607
+ /** The calendar date of the first calendar placement. */
1608
+ journalDate?: string;
1609
+ /** The route slug of the first named placement. */
1610
+ pageSlug?: string;
1611
+ }
1612
+ /** Project a note's placements onto the single-page fields. */
1613
+ declare function projectPlacements(placements: readonly NotePlacement[]): PlacementProjection;
1614
+
1499
1615
  /**
1500
1616
  * State of a WOD block
1501
1617
  */
@@ -1616,19 +1732,43 @@ interface SectionDocument {
1616
1732
  * (including the predefined default notebooks `notebook/journal`,
1617
1733
  * `notebook/playground`, and `notebook/guides`).
1618
1734
  */
1735
+
1619
1736
  /** Predefined default notebook slugs always present in the application. */
1620
- declare const DEFAULT_NOTEBOOK_SLUGS: readonly ["journal", "playground", "guides"];
1737
+ declare const DEFAULT_NOTEBOOK_SLUGS: readonly ["journal", "playground", "defaults", "guides"];
1621
1738
  type DefaultNotebookSlug = (typeof DEFAULT_NOTEBOOK_SLUGS)[number];
1622
1739
  type NotebookId = `notebook/${string}`;
1623
- type NotebookOrigin = 'default' | 'user' | 'seed';
1740
+ /** Where a notebook comes from. 'feed' = delivered by a feed (the feed that
1741
+ * delivers it is named by `feedEntryId`); 'user' = the user owns it;
1742
+ * 'default' = one of the predefined notebooks. */
1743
+ type NotebookOrigin = 'default' | 'user' | 'feed';
1624
1744
  /** Extract the bare slug from a `notebook/{slug}` or `notebook:{slug}` or bare identifier. */
1625
1745
  declare function notebookSlugFromId(slugOrId: string): string;
1626
1746
  /** Normalize any notebook slug or id to the canonical `notebook/{slug}` form. */
1627
1747
  declare function toNotebookId(slugOrId: string): NotebookId;
1628
- /** Application-level editability rule: only user-created notes (`seedOrigin !== 'seed'`) are editable. */
1748
+ /** Application-level editability rule (ticket 05): a note is editable when
1749
+ * its NOTEBOOK is user-owned. `notebookOrigin` is the origin of the note's
1750
+ * resolved notebook (`notebookOfItem` + the notebook registry) — feed-delivered
1751
+ * notebooks are read-only, and a note cloned into a user-owned notebook
1752
+ * (e.g. `notebook/defaults`) is editable even though it keeps its seed/feed
1753
+ * provenance stamps. Without a resolved notebook origin the decision falls
1754
+ * back to the note's own stamps, which match the registry answer for every
1755
+ * importer-written row. */
1629
1756
  declare function isNoteEditable(note: {
1630
1757
  seedOrigin?: string | null;
1631
- }): boolean;
1758
+ feedOrigin?: string | null;
1759
+ }, notebookOrigin?: NotebookOrigin): boolean;
1760
+ interface BuiltinNotebookSpec {
1761
+ slug: string;
1762
+ notebookId: NotebookId;
1763
+ name: string;
1764
+ description: string;
1765
+ icon: string;
1766
+ href: string;
1767
+ feedEntryId?: FeedId;
1768
+ seedChunkId?: string;
1769
+ }
1770
+ /** Single source of truth for always-present built-in and core reference notebooks. */
1771
+ declare const BUILTIN_NOTEBOOKS: readonly BuiltinNotebookSpec[];
1632
1772
  interface Notebook {
1633
1773
  /** Canonical `notebook/{slug}` identifier. */
1634
1774
  id: NotebookId | string;
@@ -1640,18 +1780,11 @@ interface Notebook {
1640
1780
  description: string;
1641
1781
  icon: string;
1642
1782
  origin: NotebookOrigin;
1643
- /** Registered seed source entry id where the source is pulled from. */
1644
- sourceEntryId?: string;
1645
- /** Seed package id when delivered by a named package slice. */
1646
- packageId?: string;
1647
- /** Seed directory URL where the source is pulled from. */
1648
- sourceUrl?: string;
1649
- /** Published Git repository URL when declared by the source entry. */
1650
- repositoryUrl?: string;
1783
+ /** Registered feed entry id — the feed that publishes this notebook. */
1784
+ feedEntryId?: FeedId;
1651
1785
  /** Seed manifest chunk id when delivered by a seed. */
1652
1786
  seedChunkId?: string;
1653
1787
  createdAt: number;
1654
- lastEditedAt: number;
1655
1788
  }
1656
1789
  declare const NOTEBOOK_TAG_PREFIX = "notebook:";
1657
1790
  declare const toNotebookTag: (notebookId: string) => string;
@@ -1759,13 +1892,13 @@ declare function patchFrontmatterProperty(raw: string, path: readonly string[],
1759
1892
  * Auto-generated build version metadata.
1760
1893
  * Do not edit directly; updated by scripts/stamp-version.ts
1761
1894
  */
1762
- declare const VERSION = "0.44.2159";
1763
- declare const GIT_SHA = "30e43c7";
1764
- declare const BUILD_TIME = "2026-10-24T23:07:22.311Z";
1895
+ declare const VERSION = "0.45.2166";
1896
+ declare const GIT_SHA = "32bda10";
1897
+ declare const BUILD_TIME = "2026-10-26T20:01:09.868Z";
1765
1898
  declare const SEMVER: {
1766
- readonly version: "0.44.2159";
1767
- readonly gitSha: "30e43c7";
1768
- readonly buildTime: "2026-10-24T23:07:22.311Z";
1899
+ readonly version: "0.45.2166";
1900
+ readonly gitSha: "32bda10";
1901
+ readonly buildTime: "2026-10-26T20:01:09.868Z";
1769
1902
  };
1770
1903
 
1771
- export { type AnalyticsDataPoint, type AnalyticsGraphConfig, type AnalyticsGroup, type Attachment, BUILD_TIME, type BlockEffort, type BlockEquipment, type BlockIndexRow, BlockKey, type BlockRevision, type CatalogBackfillState, CodeMetadata, CodeStatement, DEFAULT_NOTEBOOK_SLUGS, type DefaultNotebookSlug, type DialectAnalysis, type DimensionKey, type DisplayStatus, type EventGrain, type EventRecord, type FenceDialect, type FieldCatalogEntry, type FieldContribution, type FieldLeaf, type FieldRef, type FieldSourceRecord, type FieldValueKind, type FieldValueRecord, type FrontMatterSubtype, type FrontmatterPatchValue, GIT_SHA, type IBlockKey, type ICodeMetadata, type ICodeStatement, type IDialect, type IDialectTagDescriptor, type IMetric, type IMetricOwnershipResolver, type IMetricSource, type IOutputStatement, type IScript, type ITagSource, KNOWN_OUTPUT_TYPES, KNOWN_SECTION_WIDGETS, LEGACY_ORIGIN_TO_OWNERSHIP_LAYER, METRIC_OWNERSHIP_LAYER_CHAIN, type Membership, Metric, type MetricAction, MetricContainer, type MetricFilter, type MetricOrigin, type MetricOwnershipLayer, type MetricOwnershipLedger, type MetricOwnershipOutcome, type MetricOwnershipPromotionCandidate, type MetricOwnershipQuery, type MetricOwnershipResolvedContribution, type MetricOwnershipTypeExplanation, type MetricTemporal, MetricType, type MetricWithOptionalOwnershipLayer, NOTEBOOK_TAG_PREFIX, type Note, type NoteBlock, type NoteBlockChange, type NoteBlockKind, type NoteKind, type NoteTag, type Notebook, type NotebookId, type NotebookOrigin, type NullValueKind, type Origin, OutputStatement, type OutputStatementOptions, type OutputStatementType, OwnershipResolver, type Page, type PageNote, type ParseError, ParsedCodeStatement, REFERENCE_METADATA_KEY, type ReconcileNoteBlocksOptions, type ReducerStats, type ReferenceDiagnostic, type ReferenceDiagnosticReason, type ReferenceKind, type ReferenceMatchKind, type ReferenceMetadata, type ReferenceRef, type ResultOrigin, SEMVER, SYSTEM_DEFAULT_OUTPUT_UNIT, type ScriptBlock, type ScriptBlockState, type Section, type SectionDocument, type SectionRecognitionOptions, type SectionType, type Segment, type Session, type StoredOutputStatement, type SummaryCoverage, TAG_REFERENCE_METADATA_KEY, type Tag, type TagContribution, type TagDefinition, type TagFunctionContribution, type TagIndex, type TagMetricContribution, type TagReferenceMetadata, type TagTagContribution, type TagType, type TagTypeRecord, type TimeSpan, UNIT_CATALOG, UnitConversionError, type UnitDefinition, type UnitErrorCode, VALID_FENCE_DIALECTS, VERSION, type VisualizerFilter, type VisualizerSize, type WorkoutResults, type WorkoutSectionType, actionableSectionKind, blockContentId, buildRawContent, calculateTotalLines, convertViaCatalog, createMetricOwnershipLedger, createTagIndex, detectScriptBlocks, dimensionKeyOf, extractBlockContent, fieldRefFromKey, fieldRefKey, findBlockAtLine, flattenFieldLeaves, fromNotebookTag, getMetricOwnershipLayer, getReferenceMetadata, getTagReference, isNoteEditable, isNotebookTag, isWorkoutSectionType, lookupUnit, mapNoteBlockChanges, matchDialectFence, normalizeFieldComponent, normalizeFieldPath, notebookSlugFromId, ownershipRank, parseDocumentSections, patchFrontmatterProperty, reconcileNoteBlocks, resolveLayer, runAffordance, systemDefaultUnit, toNotebookId, toNotebookTag, validateNoteBlocks, valueKindOf };
1904
+ export { type AnalyticsDataPoint, type AnalyticsGraphConfig, type AnalyticsGroup, type Attachment, BUILD_TIME, BUILTIN_NOTEBOOKS, type BlockEffort, type BlockEquipment, type BlockIndexRow, BlockKey, type BlockRevision, type BuiltinNotebookSpec, type CatalogBackfillState, CodeMetadata, CodeStatement, DEFAULT_NOTEBOOK_SLUGS, type DefaultNotebookSlug, type DialectAnalysis, type DimensionKey, type DisplayStatus, type EventGrain, type EventRecord, type FeedId, type FeedOrigin, type FenceDialect, type FieldCatalogEntry, type FieldContribution, type FieldLeaf, type FieldRef, type FieldSourceRecord, type FieldValueKind, type FieldValueRecord, type FrontMatterSubtype, type FrontmatterPatchValue, GIT_SHA, type IBlockKey, type ICodeMetadata, type ICodeStatement, type IDialect, type IDialectTagDescriptor, type IMetric, type IMetricOwnershipResolver, type IMetricSource, type IOutputStatement, type IScript, type ITagSource, KNOWN_OUTPUT_TYPES, KNOWN_SECTION_WIDGETS, LEGACY_ORIGIN_TO_OWNERSHIP_LAYER, METRIC_OWNERSHIP_LAYER_CHAIN, type Membership, Metric, type MetricAction, MetricContainer, type MetricFilter, type MetricOrigin, type MetricOwnershipLayer, type MetricOwnershipLedger, type MetricOwnershipOutcome, type MetricOwnershipPromotionCandidate, type MetricOwnershipQuery, type MetricOwnershipResolvedContribution, type MetricOwnershipTypeExplanation, type MetricTemporal, MetricType, type MetricWithOptionalOwnershipLayer, NOTEBOOK_TAG_PREFIX, type Note, type NoteBlock, type NoteBlockChange, type NoteBlockKind, type NoteKind, type NotePlacement, type NoteTag, type Notebook, type NotebookId, type NotebookOrigin, type NullValueKind, type Origin, OutputStatement, type OutputStatementOptions, type OutputStatementType, OwnershipResolver, type Page, type PageNote, type PageTarget, type ParseError, ParsedCodeStatement, type PlacementProjection, REFERENCE_METADATA_KEY, type ReconcileNoteBlocksOptions, type ReducerStats, type ReferenceDiagnostic, type ReferenceDiagnosticReason, type ReferenceKind, type ReferenceMatchKind, type ReferenceMetadata, type ReferenceRef, type ResultOrigin, SEMVER, SYSTEM_DEFAULT_OUTPUT_UNIT, type ScriptBlock, type ScriptBlockState, type Section, type SectionDocument, type SectionRecognitionOptions, type SectionType, type Segment, type Session, type StoredOutputStatement, type SummaryCoverage, TAG_REFERENCE_METADATA_KEY, type Tag, type TagContribution, type TagDefinition, type TagFunctionContribution, type TagIndex, type TagMetricContribution, type TagReferenceMetadata, type TagTagContribution, type TagType, type TagTypeRecord, type TimeSpan, UNIT_CATALOG, UnitConversionError, type UnitDefinition, type UnitErrorCode, VALID_FENCE_DIALECTS, VERSION, type VisualizerFilter, type VisualizerSize, type WorkoutResults, type WorkoutSectionType, actionableSectionKind, blockContentId, buildRawContent, calculateTotalLines, comparePlacements, convertViaCatalog, createMetricOwnershipLedger, createTagIndex, detectScriptBlocks, dimensionKeyOf, extractBlockContent, fieldRefFromKey, fieldRefKey, findBlockAtLine, flattenFieldLeaves, fromNotebookTag, getMetricOwnershipLayer, getReferenceMetadata, getTagReference, isNoteEditable, isNotebookTag, isWorkoutSectionType, lookupUnit, mapNoteBlockChanges, matchDialectFence, normalizeFieldComponent, normalizeFieldPath, notebookSlugFromId, orderPlacements, ownershipRank, parseDocumentSections, patchFrontmatterProperty, projectPlacements, reconcileNoteBlocks, resolveLayer, resolvePlacements, runAffordance, systemDefaultUnit, toNotebookId, toNotebookTag, validateNoteBlocks, valueKindOf };