@contractspec/lib.personalization 6.0.16 → 6.0.18

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/README.md CHANGED
@@ -1,79 +1,177 @@
1
1
  # @contractspec/lib.personalization
2
2
 
3
- Website: https://contractspec.io
4
-
5
- **Behavior tracking, analysis, and adaptation helpers for ContractSpec personalization.**
3
+ `@contractspec/lib.personalization` tracks behavior events, summarizes them into actionable insights, and converts those insights into personalization outputs such as overlay suggestions. It also defines the shared preference-dimensions model consumed by runtime layers.
6
4
 
7
- ## What It Provides
8
-
9
- - **Layer**: lib.
10
- - **Consumers**: bundles, example apps.
11
- - `src/docs/` contains docblocks and documentation-facing exports.
12
- - Related ContractSpec packages include `@contractspec/lib.bus`, `@contractspec/lib.contracts-spec`, `@contractspec/lib.knowledge`, `@contractspec/lib.overlay-engine`, `@contractspec/lib.schema`, `@contractspec/lib.surface-runtime`, ...
13
- - `src/docs/` contains docblocks and documentation-facing exports.
5
+ Website: https://contractspec.io
14
6
 
15
7
  ## Installation
16
8
 
17
- `npm install @contractspec/lib.personalization`
9
+ `bun add @contractspec/lib.personalization`
18
10
 
19
11
  or
20
12
 
21
- `bun add @contractspec/lib.personalization`
13
+ `npm install @contractspec/lib.personalization`
22
14
 
23
- ## Usage
24
-
25
- Import the root entrypoint from `@contractspec/lib.personalization`, or choose a documented subpath when you only need one part of the package surface.
26
-
27
- ## Architecture
28
-
29
- - `src/adapter.ts` is part of the package's public or composition surface.
30
- - `src/analyzer.ts` is part of the package's public or composition surface.
31
- - `src/docs/` contains docblocks and documentation-facing exports.
32
- - `src/index.ts` is the root public barrel and package entrypoint.
33
- - `src/preference-dimensions.ts` is part of the package's public or composition surface.
34
- - `src/store.ts` is part of the package's public or composition surface.
35
- - `src/tracker.ts` is part of the package's public or composition surface.
36
- - `src/types.ts` is shared public type definitions.
37
-
38
- ## Public Entry Points
39
-
40
- - Export `.` resolves through `./src/index.ts`.
41
- - Export `./adapter` resolves through `./src/adapter.ts`.
42
- - Export `./analyzer` resolves through `./src/analyzer.ts`.
43
- - Export `./docs` resolves through `./src/docs/index.ts`.
44
- - Export `./docs/behavior-tracking.docblock` resolves through `./src/docs/behavior-tracking.docblock.ts`.
45
- - Export `./docs/overlay-engine.docblock` resolves through `./src/docs/overlay-engine.docblock.ts`.
46
- - Export `./docs/workflow-composition.docblock` resolves through `./src/docs/workflow-composition.docblock.ts`.
47
- - Export `./preference-dimensions` resolves through `./src/preference-dimensions.ts`.
48
- - Export `./store` resolves through `./src/store.ts`.
49
- - Export `./tracker` resolves through `./src/tracker.ts`.
50
- - The package publishes 11 total export subpaths; keep docs aligned with `package.json`.
51
-
52
- ## Local Commands
53
-
54
- - `bun run dev` — contractspec-bun-build dev
55
- - `bun run build` — bun run prebuild && bun run build:bundle && bun run build:types
56
- - `bun run test` — bun test --pass-with-no-tests
57
- - `bun run lint` — bun lint:fix
58
- - `bun run lint:check` — biome check .
59
- - `bun run lint:fix` — biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .
60
- - `bun run typecheck` — tsc --noEmit
61
- - `bun run publish:pkg` — bun publish --tolerate-republish --ignore-scripts --verbose
62
- - `bun run publish:pkg:canary` — bun publish:pkg --tag canary
63
- - `bun run clean` — rimraf dist .turbo
64
- - `bun run build:bundle` — contractspec-bun-build transpile
65
- - `bun run build:types` — contractspec-bun-build types
66
- - `bun run prebuild` — contractspec-bun-build prebuild
67
-
68
- ## Recent Updates
69
-
70
- - Replace eslint+prettier by biomejs to optimize speed.
71
- - Vercel AI SDK parity + surface-runtime i18n and bundle alignment.
72
- - Bundle spec alignment, i18n support, PM workbench pilot.
73
- - Upgrade dependencies.
74
-
75
- ## Notes
76
-
77
- - Tracker interface is the adapter boundary — implementation details must not leak.
78
- - Behavior data schema must stay backward-compatible; older events must remain parseable.
79
- - Depends on bus, overlay-engine, and knowledge — coordinate cross-lib changes.
15
+ ## What belongs here
16
+
17
+ This package currently has two jobs:
18
+
19
+ - Behavior telemetry and analysis: `tracker`, `store`, `analyzer`, `adapter`, and `types` handle event capture, storage, summarization, and conversion into adaptation hints.
20
+ - Shared preference contracts: `preference-dimensions` defines the 7-dimension personalization model and the adapter types used by runtime consumers.
21
+
22
+ Use this package when you need a thin personalization layer inside ContractSpec. Do not use it as a general analytics platform or as the full overlay runtime.
23
+
24
+ ## Core workflow
25
+
26
+ ```ts
27
+ import {
28
+ BehaviorAnalyzer,
29
+ createBehaviorTracker,
30
+ insightsToOverlaySuggestion,
31
+ InMemoryBehaviorStore,
32
+ } from "@contractspec/lib.personalization";
33
+
34
+ const store = new InMemoryBehaviorStore();
35
+
36
+ const tracker = createBehaviorTracker({
37
+ store,
38
+ context: {
39
+ tenantId: "acme",
40
+ userId: "user-123",
41
+ role: "manager",
42
+ },
43
+ autoFlushIntervalMs: 5000,
44
+ });
45
+
46
+ tracker.trackFieldAccess({
47
+ operation: "billing.createOrder",
48
+ field: "internalNotes",
49
+ });
50
+ tracker.trackFieldAccess({
51
+ operation: "billing.createOrder",
52
+ field: "customerReference",
53
+ });
54
+ tracker.trackFeatureUsage({
55
+ feature: "workflow-editor",
56
+ action: "opened",
57
+ });
58
+ tracker.trackWorkflowStep({
59
+ workflow: "invoice-approval",
60
+ step: "review",
61
+ status: "entered",
62
+ });
63
+
64
+ await tracker.flush();
65
+ await tracker.dispose();
66
+
67
+ const analyzer = new BehaviorAnalyzer(store, {
68
+ fieldInactivityThreshold: 2,
69
+ });
70
+
71
+ const insights = await analyzer.analyze({
72
+ tenantId: "acme",
73
+ userId: "user-123",
74
+ windowMs: 7 * 24 * 60 * 60 * 1000,
75
+ });
76
+
77
+ const overlay = insightsToOverlaySuggestion(insights, {
78
+ overlayId: "acme-order-form",
79
+ tenantId: "acme",
80
+ capability: "billing.createOrder",
81
+ });
82
+ ```
83
+
84
+ Typical flow:
85
+
86
+ 1. Record behavior events through `BehaviorTracker`.
87
+ 2. Persist and summarize those events through a `BehaviorStore`.
88
+ 3. Analyze the summary with `BehaviorAnalyzer`.
89
+ 4. Convert insights into an `OverlaySpec` suggestion or workflow adaptation hints.
90
+
91
+ ## API map
92
+
93
+ ### Main runtime APIs
94
+
95
+ - `BehaviorStore`: persistence boundary for recording, querying, and summarizing `BehaviorEvent` data.
96
+ - `InMemoryBehaviorStore`: simple in-memory implementation for tests, demos, and local composition.
97
+ - `BehaviorTracker` and `createBehaviorTracker`: buffered event capture with tenant/user context and OpenTelemetry instrumentation.
98
+ - `BehaviorAnalyzer`: converts `BehaviorSummary` data into `BehaviorInsights`.
99
+ - `insightsToOverlaySuggestion`: turns analysis output into an overlay-engine `OverlaySpec`.
100
+ - `insightsToWorkflowAdaptations`: turns workflow bottlenecks into lightweight adaptation notes.
101
+
102
+ ### Core data contracts
103
+
104
+ - `BehaviorEvent`: discriminated union with three event kinds: `field_access`, `feature_usage`, and `workflow_step`.
105
+ - `BehaviorQuery`: filter shape used by `BehaviorStore.query()` and `BehaviorStore.summarize()`.
106
+ - `BehaviorSummary`: aggregated counts returned by store summarization.
107
+ - `BehaviorInsights`: analyzer output including hidden-field candidates, bottlenecks, and layout preference hints.
108
+ - `BehaviorAnalyzerOptions`: tuning knobs for inactivity threshold and minimum workflow sample size.
109
+ - `OverlaySuggestionOptions`: metadata required to build an overlay suggestion.
110
+ - `WorkflowAdaptation`: workflow, step, and note triple derived from bottlenecks.
111
+
112
+ ### Preference model contracts
113
+
114
+ - `PreferenceDimensions`: the shared 7-dimension personalization model.
115
+ - `PreferenceScope`: source scope used when a preference value is resolved.
116
+ - `ResolvedPreferenceProfile`: canonical resolved preferences plus source attribution and constraint notes.
117
+ - `PreferenceResolutionContext`: minimal runtime context required to resolve a preference profile.
118
+ - `BundlePreferenceAdapter`: contract for resolving and persisting preference patches in runtime consumers.
119
+
120
+ ## Public entrypoints
121
+
122
+ The root barrel at `src/index.ts` re-exports public symbols from:
123
+
124
+ - `adapter`
125
+ - `analyzer`
126
+ - `preference-dimensions`
127
+ - `store`
128
+ - `tracker`
129
+ - `types`
130
+
131
+ Published subpaths from `package.json`:
132
+
133
+ - `.`
134
+ - `./adapter`
135
+ - `./analyzer`
136
+ - `./docs`
137
+ - `./docs/behavior-tracking.docblock`
138
+ - `./docs/overlay-engine.docblock`
139
+ - `./docs/workflow-composition.docblock`
140
+ - `./preference-dimensions`
141
+ - `./store`
142
+ - `./tracker`
143
+ - `./types`
144
+
145
+ For application code, prefer `.` or the focused subpaths above. The `./docs*` subpaths exist for docblock registration and documentation surfaces.
146
+
147
+ ## Operational semantics and gotchas
148
+
149
+ - `BehaviorTracker` buffers events in memory and flushes when the buffer reaches the configured size or when `autoFlushIntervalMs` is enabled.
150
+ - `flush()` persists the current buffer with `BehaviorStore.bulkRecord()`.
151
+ - `dispose()` clears the interval timer, then flushes any remaining buffered events.
152
+ - Each enqueue also emits OpenTelemetry metrics and tracing through `@opentelemetry/api`.
153
+ - `BehaviorAnalyzer` uses deterministic threshold heuristics. It does not do ranking, learning, or probabilistic inference.
154
+ - `insightsToOverlaySuggestion()` currently emits only `hideField` and `reorderFields` modifications.
155
+ - `layoutPreference` is inferred from field-count thresholds, not from UI render telemetry.
156
+ - `PreferenceDimensions` and related types are contracts. Durable persistence and runtime resolution live elsewhere.
157
+
158
+ ## When not to use this package
159
+
160
+ - Do not use it as a full analytics warehouse or reporting system.
161
+ - Do not use it as the durable preference persistence layer.
162
+ - Do not use it as the overlay runtime or overlay registry implementation.
163
+ - Do not use it when you need workflow composition itself; this package only emits adaptation hints.
164
+
165
+ ## Related packages
166
+
167
+ - `@contractspec/lib.overlay-engine`: runtime for registering, validating, and applying overlays.
168
+ - `@contractspec/lib.surface-runtime`: runtime consumer of preference resolution and adaptive surface behavior.
169
+ - `@contractspec/lib.workflow-composer`: workflow extension and composition runtime.
170
+ - `@contractspec/lib.contracts-spec`: shared spec and docblock contracts used across ContractSpec.
171
+
172
+ ## Local commands
173
+
174
+ - `bun run lint:check`
175
+ - `bun run typecheck`
176
+ - `bun run test`
177
+ - `bun run build`
package/dist/adapter.js CHANGED
@@ -1,47 +1,2 @@
1
1
  // @bun
2
- // src/adapter.ts
3
- function insightsToOverlaySuggestion(insights, options) {
4
- const modifications = [];
5
- insights.suggestedHiddenFields.forEach((field) => {
6
- modifications.push({
7
- type: "hideField",
8
- field,
9
- reason: "Automatically hidden because usage is near zero"
10
- });
11
- });
12
- if (insights.frequentlyUsedFields.length) {
13
- modifications.push({
14
- type: "reorderFields",
15
- fields: insights.frequentlyUsedFields
16
- });
17
- }
18
- if (!modifications.length) {
19
- return null;
20
- }
21
- return {
22
- overlayId: options.overlayId,
23
- version: options.version ?? "1.0.0",
24
- appliesTo: {
25
- tenantId: options.tenantId,
26
- capability: options.capability,
27
- userId: options.userId,
28
- role: options.role
29
- },
30
- modifications,
31
- metadata: {
32
- generatedAt: new Date().toISOString(),
33
- automated: true
34
- }
35
- };
36
- }
37
- function insightsToWorkflowAdaptations(insights) {
38
- return insights.workflowBottlenecks.map((bottleneck) => ({
39
- workflow: bottleneck.workflow,
40
- step: bottleneck.step,
41
- note: `High drop rate (${Math.round(bottleneck.dropRate * 100)}%) detected`
42
- }));
43
- }
44
- export {
45
- insightsToWorkflowAdaptations,
46
- insightsToOverlaySuggestion
47
- };
2
+ function o(t,e){let r=[];if(t.suggestedHiddenFields.forEach((i)=>{r.push({type:"hideField",field:i,reason:"Automatically hidden because usage is near zero"})}),t.frequentlyUsedFields.length)r.push({type:"reorderFields",fields:t.frequentlyUsedFields});if(!r.length)return null;return{overlayId:e.overlayId,version:e.version??"1.0.0",appliesTo:{tenantId:e.tenantId,capability:e.capability,userId:e.userId,role:e.role},modifications:r,metadata:{generatedAt:new Date().toISOString(),automated:!0}}}function n(t){return t.workflowBottlenecks.map((e)=>({workflow:e.workflow,step:e.step,note:`High drop rate (${Math.round(e.dropRate*100)}%) detected`}))}export{n as insightsToWorkflowAdaptations,o as insightsToOverlaySuggestion};
package/dist/analyzer.js CHANGED
@@ -1,73 +1,2 @@
1
1
  // @bun
2
- // src/analyzer.ts
3
- var DEFAULT_THRESHOLD = 3;
4
-
5
- class BehaviorAnalyzer {
6
- store;
7
- options;
8
- constructor(store, options = {}) {
9
- this.store = store;
10
- this.options = options;
11
- }
12
- async analyze(params) {
13
- const query = {
14
- tenantId: params.tenantId,
15
- userId: params.userId,
16
- role: params.role
17
- };
18
- if (params.windowMs) {
19
- query.since = Date.now() - params.windowMs;
20
- }
21
- const summary = await this.store.summarize(query);
22
- return buildInsights(summary, this.options);
23
- }
24
- }
25
- function buildInsights(summary, options) {
26
- const threshold = options.fieldInactivityThreshold ?? DEFAULT_THRESHOLD;
27
- const minSamples = options.minSamples ?? 10;
28
- const ignoredFields = [];
29
- const frequentlyUsedFields = [];
30
- for (const [field, count] of Object.entries(summary.fieldCounts)) {
31
- if (count <= threshold) {
32
- ignoredFields.push(field);
33
- }
34
- if (count >= threshold * 4) {
35
- frequentlyUsedFields.push(field);
36
- }
37
- }
38
- const workflowBottlenecks = Object.entries(summary.workflowStepCounts).flatMap(([workflow, steps]) => {
39
- const total = Object.values(steps).reduce((acc, value) => acc + value, 0);
40
- if (!total || total < minSamples) {
41
- return [];
42
- }
43
- return Object.entries(steps).filter(([, count]) => count / total < 0.4).map(([step, count]) => ({
44
- workflow,
45
- step,
46
- dropRate: 1 - count / total
47
- }));
48
- });
49
- const layoutPreference = detectLayout(summary);
50
- return {
51
- unusedFields: ignoredFields,
52
- suggestedHiddenFields: ignoredFields.slice(0, 5),
53
- frequentlyUsedFields: frequentlyUsedFields.slice(0, 10),
54
- workflowBottlenecks,
55
- layoutPreference
56
- };
57
- }
58
- function detectLayout(summary) {
59
- const fieldCount = Object.keys(summary.fieldCounts).length;
60
- if (!fieldCount) {
61
- return;
62
- }
63
- if (fieldCount >= 15) {
64
- return "table";
65
- }
66
- if (fieldCount >= 8) {
67
- return "grid";
68
- }
69
- return "form";
70
- }
71
- export {
72
- BehaviorAnalyzer
73
- };
2
+ class h{store;options;constructor(e,t={}){this.store=e;this.options=t}async analyze(e){let t={tenantId:e.tenantId,userId:e.userId,role:e.role};if(e.windowMs)t.since=Date.now()-e.windowMs;let i=await this.store.summarize(t);return y(i,this.options)}}function y(e,t){let i=t.fieldInactivityThreshold??3,d=t.minSamples??10,a=[],u=[];for(let[o,r]of Object.entries(e.fieldCounts)){if(r<=i)a.push(o);if(r>=i*4)u.push(o)}let c=Object.entries(e.workflowStepCounts).flatMap(([o,r])=>{let s=Object.values(r).reduce((n,l)=>n+l,0);if(!s||s<d)return[];return Object.entries(r).filter(([,n])=>n/s<0.4).map(([n,l])=>({workflow:o,step:n,dropRate:1-l/s}))}),f=m(e);return{unusedFields:a,suggestedHiddenFields:a.slice(0,5),frequentlyUsedFields:u.slice(0,10),workflowBottlenecks:c,layoutPreference:f}}function m(e){let t=Object.keys(e.fieldCounts).length;if(!t)return;if(t>=15)return"table";if(t>=8)return"grid";return"form"}export{h as BehaviorAnalyzer};
@@ -1,46 +1 @@
1
- // src/adapter.ts
2
- function insightsToOverlaySuggestion(insights, options) {
3
- const modifications = [];
4
- insights.suggestedHiddenFields.forEach((field) => {
5
- modifications.push({
6
- type: "hideField",
7
- field,
8
- reason: "Automatically hidden because usage is near zero"
9
- });
10
- });
11
- if (insights.frequentlyUsedFields.length) {
12
- modifications.push({
13
- type: "reorderFields",
14
- fields: insights.frequentlyUsedFields
15
- });
16
- }
17
- if (!modifications.length) {
18
- return null;
19
- }
20
- return {
21
- overlayId: options.overlayId,
22
- version: options.version ?? "1.0.0",
23
- appliesTo: {
24
- tenantId: options.tenantId,
25
- capability: options.capability,
26
- userId: options.userId,
27
- role: options.role
28
- },
29
- modifications,
30
- metadata: {
31
- generatedAt: new Date().toISOString(),
32
- automated: true
33
- }
34
- };
35
- }
36
- function insightsToWorkflowAdaptations(insights) {
37
- return insights.workflowBottlenecks.map((bottleneck) => ({
38
- workflow: bottleneck.workflow,
39
- step: bottleneck.step,
40
- note: `High drop rate (${Math.round(bottleneck.dropRate * 100)}%) detected`
41
- }));
42
- }
43
- export {
44
- insightsToWorkflowAdaptations,
45
- insightsToOverlaySuggestion
46
- };
1
+ function o(t,e){let r=[];if(t.suggestedHiddenFields.forEach((i)=>{r.push({type:"hideField",field:i,reason:"Automatically hidden because usage is near zero"})}),t.frequentlyUsedFields.length)r.push({type:"reorderFields",fields:t.frequentlyUsedFields});if(!r.length)return null;return{overlayId:e.overlayId,version:e.version??"1.0.0",appliesTo:{tenantId:e.tenantId,capability:e.capability,userId:e.userId,role:e.role},modifications:r,metadata:{generatedAt:new Date().toISOString(),automated:!0}}}function n(t){return t.workflowBottlenecks.map((e)=>({workflow:e.workflow,step:e.step,note:`High drop rate (${Math.round(e.dropRate*100)}%) detected`}))}export{n as insightsToWorkflowAdaptations,o as insightsToOverlaySuggestion};
@@ -1,72 +1 @@
1
- // src/analyzer.ts
2
- var DEFAULT_THRESHOLD = 3;
3
-
4
- class BehaviorAnalyzer {
5
- store;
6
- options;
7
- constructor(store, options = {}) {
8
- this.store = store;
9
- this.options = options;
10
- }
11
- async analyze(params) {
12
- const query = {
13
- tenantId: params.tenantId,
14
- userId: params.userId,
15
- role: params.role
16
- };
17
- if (params.windowMs) {
18
- query.since = Date.now() - params.windowMs;
19
- }
20
- const summary = await this.store.summarize(query);
21
- return buildInsights(summary, this.options);
22
- }
23
- }
24
- function buildInsights(summary, options) {
25
- const threshold = options.fieldInactivityThreshold ?? DEFAULT_THRESHOLD;
26
- const minSamples = options.minSamples ?? 10;
27
- const ignoredFields = [];
28
- const frequentlyUsedFields = [];
29
- for (const [field, count] of Object.entries(summary.fieldCounts)) {
30
- if (count <= threshold) {
31
- ignoredFields.push(field);
32
- }
33
- if (count >= threshold * 4) {
34
- frequentlyUsedFields.push(field);
35
- }
36
- }
37
- const workflowBottlenecks = Object.entries(summary.workflowStepCounts).flatMap(([workflow, steps]) => {
38
- const total = Object.values(steps).reduce((acc, value) => acc + value, 0);
39
- if (!total || total < minSamples) {
40
- return [];
41
- }
42
- return Object.entries(steps).filter(([, count]) => count / total < 0.4).map(([step, count]) => ({
43
- workflow,
44
- step,
45
- dropRate: 1 - count / total
46
- }));
47
- });
48
- const layoutPreference = detectLayout(summary);
49
- return {
50
- unusedFields: ignoredFields,
51
- suggestedHiddenFields: ignoredFields.slice(0, 5),
52
- frequentlyUsedFields: frequentlyUsedFields.slice(0, 10),
53
- workflowBottlenecks,
54
- layoutPreference
55
- };
56
- }
57
- function detectLayout(summary) {
58
- const fieldCount = Object.keys(summary.fieldCounts).length;
59
- if (!fieldCount) {
60
- return;
61
- }
62
- if (fieldCount >= 15) {
63
- return "table";
64
- }
65
- if (fieldCount >= 8) {
66
- return "grid";
67
- }
68
- return "form";
69
- }
70
- export {
71
- BehaviorAnalyzer
72
- };
1
+ class h{store;options;constructor(e,t={}){this.store=e;this.options=t}async analyze(e){let t={tenantId:e.tenantId,userId:e.userId,role:e.role};if(e.windowMs)t.since=Date.now()-e.windowMs;let i=await this.store.summarize(t);return y(i,this.options)}}function y(e,t){let i=t.fieldInactivityThreshold??3,d=t.minSamples??10,a=[],u=[];for(let[o,r]of Object.entries(e.fieldCounts)){if(r<=i)a.push(o);if(r>=i*4)u.push(o)}let c=Object.entries(e.workflowStepCounts).flatMap(([o,r])=>{let s=Object.values(r).reduce((n,l)=>n+l,0);if(!s||s<d)return[];return Object.entries(r).filter(([,n])=>n/s<0.4).map(([n,l])=>({workflow:o,step:n,dropRate:1-l/s}))}),f=m(e);return{unusedFields:a,suggestedHiddenFields:a.slice(0,5),frequentlyUsedFields:u.slice(0,10),workflowBottlenecks:c,layoutPreference:f}}function m(e){let t=Object.keys(e.fieldCounts).length;if(!t)return;if(t>=15)return"table";if(t>=8)return"grid";return"form"}export{h as BehaviorAnalyzer};
@@ -1,15 +1,4 @@
1
- // src/docs/behavior-tracking.docblock.ts
2
- import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
3
- var personalization_behavior_tracking_DocBlocks = [
4
- {
5
- id: "docs.personalization.behavior-tracking",
6
- title: "Behavior Tracking",
7
- summary: "`@contractspec/lib.personalization` provides primitives to observe how tenants/users interact with specs and turn that telemetry into personalization insights.",
8
- kind: "reference",
9
- visibility: "public",
10
- route: "/docs/personalization/behavior-tracking",
11
- tags: ["personalization", "behavior-tracking"],
12
- body: `# Behavior Tracking
1
+ import{registerDocBlocks as d}from"@contractspec/lib.contracts-spec/docs";var f=[{id:"docs.personalization.behavior-tracking",title:"Behavior Tracking",summary:"`@contractspec/lib.personalization` provides primitives to observe how tenants/users interact with specs and turn that telemetry into personalization insights.",kind:"reference",visibility:"public",route:"/docs/personalization/behavior-tracking",tags:["personalization","behavior-tracking"],body:`# Behavior Tracking
13
2
 
14
3
  \`@contractspec/lib.personalization\` provides primitives to observe how tenants/users interact with specs and turn that telemetry into personalization insights.
15
4
 
@@ -88,10 +77,4 @@ When the adapter returns an overlay spec, pass it to the overlay engine to regis
88
77
 
89
78
 
90
79
 
91
- `
92
- }
93
- ];
94
- registerDocBlocks(personalization_behavior_tracking_DocBlocks);
95
- export {
96
- personalization_behavior_tracking_DocBlocks
97
- };
80
+ `}];d(f);export{f as personalization_behavior_tracking_DocBlocks};
@@ -1,15 +1,4 @@
1
- // src/docs/behavior-tracking.docblock.ts
2
- import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
3
- var personalization_behavior_tracking_DocBlocks = [
4
- {
5
- id: "docs.personalization.behavior-tracking",
6
- title: "Behavior Tracking",
7
- summary: "`@contractspec/lib.personalization` provides primitives to observe how tenants/users interact with specs and turn that telemetry into personalization insights.",
8
- kind: "reference",
9
- visibility: "public",
10
- route: "/docs/personalization/behavior-tracking",
11
- tags: ["personalization", "behavior-tracking"],
12
- body: `# Behavior Tracking
1
+ import{registerDocBlocks as m}from"@contractspec/lib.contracts-spec/docs";var d=[{id:"docs.personalization.behavior-tracking",title:"Behavior Tracking",summary:"`@contractspec/lib.personalization` provides primitives to observe how tenants/users interact with specs and turn that telemetry into personalization insights.",kind:"reference",visibility:"public",route:"/docs/personalization/behavior-tracking",tags:["personalization","behavior-tracking"],body:`# Behavior Tracking
13
2
 
14
3
  \`@contractspec/lib.personalization\` provides primitives to observe how tenants/users interact with specs and turn that telemetry into personalization insights.
15
4
 
@@ -88,23 +77,7 @@ When the adapter returns an overlay spec, pass it to the overlay engine to regis
88
77
 
89
78
 
90
79
 
91
- `
92
- }
93
- ];
94
- registerDocBlocks(personalization_behavior_tracking_DocBlocks);
95
-
96
- // src/docs/overlay-engine.docblock.ts
97
- import { registerDocBlocks as registerDocBlocks2 } from "@contractspec/lib.contracts-spec/docs";
98
- var personalization_overlay_engine_DocBlocks = [
99
- {
100
- id: "docs.personalization.overlay-engine",
101
- title: "Overlay Engine",
102
- summary: "`@contractspec/lib.overlay-engine` is the canonical runtime for OverlaySpecs. It validates specs, tracks scope precedence, and exposes hooks for React renderers.",
103
- kind: "reference",
104
- visibility: "public",
105
- route: "/docs/personalization/overlay-engine",
106
- tags: ["personalization", "overlay-engine"],
107
- body: `# Overlay Engine
80
+ `}];m(d);import{registerDocBlocks as j}from"@contractspec/lib.contracts-spec/docs";var q=[{id:"docs.personalization.overlay-engine",title:"Overlay Engine",summary:"`@contractspec/lib.overlay-engine` is the canonical runtime for OverlaySpecs. It validates specs, tracks scope precedence, and exposes hooks for React renderers.",kind:"reference",visibility:"public",route:"/docs/personalization/overlay-engine",tags:["personalization","overlay-engine"],body:`# Overlay Engine
108
81
 
109
82
  \`@contractspec/lib.overlay-engine\` is the canonical runtime for OverlaySpecs. It validates specs, tracks scope precedence, and exposes hooks for React renderers.
110
83
 
@@ -184,23 +157,7 @@ const result = engine.apply({
184
157
 
185
158
 
186
159
 
187
- `
188
- }
189
- ];
190
- registerDocBlocks2(personalization_overlay_engine_DocBlocks);
191
-
192
- // src/docs/workflow-composition.docblock.ts
193
- import { registerDocBlocks as registerDocBlocks3 } from "@contractspec/lib.contracts-spec/docs";
194
- var personalization_workflow_composition_DocBlocks = [
195
- {
196
- id: "docs.personalization.workflow-composition",
197
- title: "Workflow Composition",
198
- summary: "`@contractspec/lib.workflow-composer` composes base WorkflowSpecs with tenant/role/device-specific extensions, strict validation, deterministic merge ordering, metadata/annotation overlays, and orphan-graph protection for hidden-step rewrites.",
199
- kind: "reference",
200
- visibility: "public",
201
- route: "/docs/personalization/workflow-composition",
202
- tags: ["personalization", "workflow-composition"],
203
- body: `# Workflow Composition
160
+ `}];j(q);import{registerDocBlocks as u}from"@contractspec/lib.contracts-spec/docs";var x=[{id:"docs.personalization.workflow-composition",title:"Workflow Composition",summary:"`@contractspec/lib.workflow-composer` composes base WorkflowSpecs with tenant/role/device-specific extensions, strict validation, deterministic merge ordering, metadata/annotation overlays, and orphan-graph protection for hidden-step rewrites.",kind:"reference",visibility:"public",route:"/docs/personalization/workflow-composition",tags:["personalization","workflow-composition"],body:`# Workflow Composition
204
161
 
205
162
  \`@contractspec/lib.workflow-composer\` composes base WorkflowSpecs with tenant/role/device-specific extensions.
206
163
 
@@ -252,7 +209,4 @@ workflowRunner.execute(runtimeSpec, ctx);
252
209
  - \`metadata\` and \`annotations\` overlays are merged into the composed runtime workflow for downstream observability and rollout tracing.
253
210
 
254
211
  This keeps tenant overlays additive, auditable, and replay-safe.
255
- `
256
- }
257
- ];
258
- registerDocBlocks3(personalization_workflow_composition_DocBlocks);
212
+ `}];u(x);
@@ -1,15 +1,4 @@
1
- // src/docs/overlay-engine.docblock.ts
2
- import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
3
- var personalization_overlay_engine_DocBlocks = [
4
- {
5
- id: "docs.personalization.overlay-engine",
6
- title: "Overlay Engine",
7
- summary: "`@contractspec/lib.overlay-engine` is the canonical runtime for OverlaySpecs. It validates specs, tracks scope precedence, and exposes hooks for React renderers.",
8
- kind: "reference",
9
- visibility: "public",
10
- route: "/docs/personalization/overlay-engine",
11
- tags: ["personalization", "overlay-engine"],
12
- body: `# Overlay Engine
1
+ import{registerDocBlocks as b}from"@contractspec/lib.contracts-spec/docs";var d=[{id:"docs.personalization.overlay-engine",title:"Overlay Engine",summary:"`@contractspec/lib.overlay-engine` is the canonical runtime for OverlaySpecs. It validates specs, tracks scope precedence, and exposes hooks for React renderers.",kind:"reference",visibility:"public",route:"/docs/personalization/overlay-engine",tags:["personalization","overlay-engine"],body:`# Overlay Engine
13
2
 
14
3
  \`@contractspec/lib.overlay-engine\` is the canonical runtime for OverlaySpecs. It validates specs, tracks scope precedence, and exposes hooks for React renderers.
15
4
 
@@ -89,10 +78,4 @@ const result = engine.apply({
89
78
 
90
79
 
91
80
 
92
- `
93
- }
94
- ];
95
- registerDocBlocks(personalization_overlay_engine_DocBlocks);
96
- export {
97
- personalization_overlay_engine_DocBlocks
98
- };
81
+ `}];b(d);export{d as personalization_overlay_engine_DocBlocks};
@@ -1,15 +1,4 @@
1
- // src/docs/workflow-composition.docblock.ts
2
- import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
3
- var personalization_workflow_composition_DocBlocks = [
4
- {
5
- id: "docs.personalization.workflow-composition",
6
- title: "Workflow Composition",
7
- summary: "`@contractspec/lib.workflow-composer` composes base WorkflowSpecs with tenant/role/device-specific extensions, strict validation, deterministic merge ordering, metadata/annotation overlays, and orphan-graph protection for hidden-step rewrites.",
8
- kind: "reference",
9
- visibility: "public",
10
- route: "/docs/personalization/workflow-composition",
11
- tags: ["personalization", "workflow-composition"],
12
- body: `# Workflow Composition
1
+ import{registerDocBlocks as b}from"@contractspec/lib.contracts-spec/docs";var d=[{id:"docs.personalization.workflow-composition",title:"Workflow Composition",summary:"`@contractspec/lib.workflow-composer` composes base WorkflowSpecs with tenant/role/device-specific extensions, strict validation, deterministic merge ordering, metadata/annotation overlays, and orphan-graph protection for hidden-step rewrites.",kind:"reference",visibility:"public",route:"/docs/personalization/workflow-composition",tags:["personalization","workflow-composition"],body:`# Workflow Composition
13
2
 
14
3
  \`@contractspec/lib.workflow-composer\` composes base WorkflowSpecs with tenant/role/device-specific extensions.
15
4
 
@@ -61,10 +50,4 @@ workflowRunner.execute(runtimeSpec, ctx);
61
50
  - \`metadata\` and \`annotations\` overlays are merged into the composed runtime workflow for downstream observability and rollout tracing.
62
51
 
63
52
  This keeps tenant overlays additive, auditable, and replay-safe.
64
- `
65
- }
66
- ];
67
- registerDocBlocks(personalization_workflow_composition_DocBlocks);
68
- export {
69
- personalization_workflow_composition_DocBlocks
70
- };
53
+ `}];b(d);export{d as personalization_workflow_composition_DocBlocks};