@contractspec/lib.personalization 6.1.0 → 6.2.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.
Files changed (49) hide show
  1. package/README.md +353 -3
  2. package/dist/adaptive-evolution.d.ts +40 -0
  3. package/dist/adaptive-evolution.js +2 -0
  4. package/dist/adaptive-experience-policy.test.d.ts +1 -0
  5. package/dist/adaptive-experience.d.ts +74 -0
  6. package/dist/adaptive-experience.js +2 -0
  7. package/dist/adaptive-experience.test.d.ts +1 -0
  8. package/dist/adaptive-onboarding-scores.d.ts +9 -0
  9. package/dist/adaptive-onboarding-scores.js +2 -0
  10. package/dist/adaptive-onboarding.d.ts +46 -0
  11. package/dist/adaptive-onboarding.js +2 -0
  12. package/dist/behavior-signals.d.ts +50 -0
  13. package/dist/behavior-signals.js +2 -0
  14. package/dist/behavior-support-preset-definitions.d.ts +22 -0
  15. package/dist/behavior-support-preset-definitions.js +2 -0
  16. package/dist/behavior-support-presets.d.ts +146 -0
  17. package/dist/behavior-support-presets.js +2 -0
  18. package/dist/behavior-support.d.ts +18 -0
  19. package/dist/behavior-support.js +2 -0
  20. package/dist/behavior-support.test.d.ts +1 -0
  21. package/dist/index.d.ts +5 -0
  22. package/dist/index.js +4 -4
  23. package/dist/node/adaptive-evolution.js +1 -0
  24. package/dist/node/adaptive-experience.js +1 -0
  25. package/dist/node/adaptive-onboarding-scores.js +1 -0
  26. package/dist/node/adaptive-onboarding.js +1 -0
  27. package/dist/node/behavior-signals.js +1 -0
  28. package/dist/node/behavior-support-preset-definitions.js +1 -0
  29. package/dist/node/behavior-support-presets.js +1 -0
  30. package/dist/node/behavior-support.js +1 -0
  31. package/dist/node/index.js +4 -4
  32. package/dist/node/preference-dimensions.js +1 -0
  33. package/dist/node/preference-evolution-types.js +0 -0
  34. package/dist/node/preference-evolution.js +1 -0
  35. package/dist/node/preference-onboarding.js +1 -0
  36. package/dist/node/preference-presets.js +1 -0
  37. package/dist/preference-dimensions.d.ts +8 -0
  38. package/dist/preference-dimensions.js +1 -0
  39. package/dist/preference-dimensions.test.d.ts +1 -0
  40. package/dist/preference-evolution-types.d.ts +49 -0
  41. package/dist/preference-evolution-types.js +1 -0
  42. package/dist/preference-evolution.d.ts +3 -0
  43. package/dist/preference-evolution.js +2 -0
  44. package/dist/preference-evolution.test.d.ts +1 -0
  45. package/dist/preference-onboarding.d.ts +24 -0
  46. package/dist/preference-onboarding.js +2 -0
  47. package/dist/preference-presets.d.ts +97 -0
  48. package/dist/preference-presets.js +2 -0
  49. package/package.json +150 -6
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @contractspec/lib.personalization
2
2
 
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.
3
+ `@contractspec/lib.personalization` tracks behavior events, summarizes them into actionable insights, and converts those insights into transparent personalization outputs such as overlay suggestions, preference recommendations, and runtime adaptive-experience decisions. It also defines the shared preference-dimensions model consumed by runtime layers.
4
4
 
5
5
  Website: https://contractspec.io
6
6
 
@@ -14,10 +14,11 @@ or
14
14
 
15
15
  ## What belongs here
16
16
 
17
- This package currently has two jobs:
17
+ This package currently has three jobs:
18
18
 
19
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.
20
+ - Shared adaptive contracts: `preference-dimensions`, behavior support, behavior signals, and runtime resolution define the generic adaptive-experience model consumed by runtime layers.
21
+ - Practical adoption: curated presets, onboarding recommendation, and safe evolution suggestions help applications offer a better starting point without creating rigid personas.
21
22
 
22
23
  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
 
@@ -186,19 +187,354 @@ Add DataView personalization for <screen>.
186
187
  ### Preference model contracts
187
188
 
188
189
  - `PreferenceDimensions`: the shared 7-dimension personalization model.
190
+ - `BehaviorSupportDimensions`: the support-strategy model for helping users act, recover, and review progress.
191
+ - `BehaviorSignalModel`: scoped behavior evidence used to explain adaptation suggestions without profiling users.
192
+ - `ResolvedAdaptiveExperience`: runtime-only result describing what the application should do now.
193
+ - Preset helpers: `PREFERENCE_DIMENSION_PRESETS`, `PREFERENCE_PRESET_DEFINITIONS`, `getPreferencePresetDimensions`, and `createPreferencePresetCatalog`.
194
+ - Behavior support preset helpers: `BEHAVIOR_SUPPORT_PRESETS`, `BEHAVIOR_SUPPORT_PRESET_DEFINITIONS`, and `getBehaviorSupportPresetDimensions`.
195
+ - Onboarding helpers: `recommendPreferencePreset`, `recommendBehaviorSupportPreset`, `recommendAdaptiveExperience`, and related recommendation types.
196
+ - Evolution helpers: `suggestPreferenceEvolution`, `suggestAdaptiveExperienceEvolution`, and related suggestion types.
189
197
  - `PreferenceScope`: source scope used when a preference value is resolved.
190
198
  - `ResolvedPreferenceProfile`: canonical resolved preferences plus source attribution and constraint notes.
191
199
  - `PreferenceResolutionContext`: minimal runtime context required to resolve a preference profile.
192
200
  - `BundlePreferenceAdapter`: contract for resolving and persisting preference patches in runtime consumers.
193
201
 
202
+ ## Adaptive experience toolkit
203
+
204
+ Use ContractSpec personalization to give builders a transparent adaptation layer. The package separates how software presents itself from how the system supports user action:
205
+
206
+ - `PreferenceDimensions` decide how the software adapts as a tool.
207
+ - `BehaviorSupportDimensions` decide how the system supports human action.
208
+ - `BehaviorSignalModel` records what evidence is strong enough to suggest a change.
209
+ - `ResolvedAdaptiveExperience` describes what should happen now, at runtime.
210
+
211
+ This is not a profiling engine, user-personality classifier, behavioral manipulation toolkit, analytics platform, or authorization system. It is a small set of contracts for saying: "The system noticed this scoped pattern and can adjust the experience in a way the user can inspect and override."
212
+
213
+ ### Interaction preferences
214
+
215
+ `PreferenceDimensions` describes how a person wants to experience an application across seven independent dimensions:
216
+
217
+ - `guidance`: how much help the interface offers.
218
+ - `density`: how much information appears at once.
219
+ - `dataDepth`: whether the app starts from summaries, details, or exhaustive evidence.
220
+ - `control`: how much configuration and direct manipulation is exposed.
221
+ - `media`: whether the experience prefers text, visuals, voice, or a hybrid.
222
+ - `pace`: whether interactions should feel deliberate, balanced, or rapid.
223
+ - `narrative`: whether content starts top-down, bottom-up, or adapts by context.
224
+
225
+ These dimensions are software interaction preferences, not behavior labels and not permissions. `control: "full"` never grants access to features a user is not authorized to use.
226
+
227
+ ### Behavior support dimensions
228
+
229
+ `BehaviorSupportDimensions` describes how the system supports action, momentum, recovery, and decision-making:
230
+
231
+ - `attention`: how the system helps the user notice what matters next.
232
+ - `activation`: how the system helps the user start.
233
+ - `actionScale`: how large the next useful action should be.
234
+ - `rhythm`: how work fits time, energy, urgency, or changing context.
235
+ - `environment`: what surrounding structure makes action easier.
236
+ - `challenge`: how much stretch or pressure is appropriate.
237
+ - `meaningFrame`: what makes the action feel worthwhile.
238
+ - `permission`: what helps the user begin, reduce, pause, or renegotiate.
239
+ - `selfAuthority`: how the system supports confidence, composure, structure, and follow-through.
240
+ - `accountability`: how much external structure or review the user wants.
241
+ - `recovery`: what should happen after skipped actions, misses, contradictions, or failed attempts.
242
+ - `reflection`: how much learning or review should happen after action.
243
+
244
+ This layer is support strategy, not identity. Use language such as "start support", "smaller first step", "repair first", "private review", or "brief reflection". Avoid moral, clinical, or manipulative labels such as "lazy", "avoidant", "low motivation", "approval-seeking", "low-value user", or "manipulable user".
245
+
246
+ ### Presets are starting points
247
+
248
+ The package exports a small interaction preset catalog that application builders can ship directly:
249
+
250
+ - `balanced`: safe default for general use.
251
+ - `guideMe`: slower, guided onboarding for new or uncertain users.
252
+ - `summaryFirst`: compact, fast, dashboard-style usage.
253
+ - `deepAnalyst`: data-rich, evidence-first investigation mode.
254
+ - `builder`: fast, configurable mode for creating and adjusting workflows.
255
+ - `opsWarRoom`: dense, visual, rapid mode for live operational surfaces.
256
+ - `auditReview`: deliberate, traceable, detail-heavy review mode.
257
+ - `minimalFocus`: low-noise, focused, simple experience.
258
+
259
+ Presets are not identities. Use labels such as "Summary-first" or "Minimal focus", not labels such as "manager mode" or "junior user".
260
+
261
+ ```ts
262
+ import {
263
+ getPreferencePresetDimensions,
264
+ PREFERENCE_PRESET_DEFINITIONS,
265
+ } from "@contractspec/lib.personalization";
266
+
267
+ const startingPreferences = getPreferencePresetDimensions("summaryFirst");
268
+ const presetIntent = PREFERENCE_PRESET_DEFINITIONS.summaryFirst.intent;
269
+ ```
270
+
271
+ Override or extend the catalog by merging your own named bundles of `PreferenceDimensions`:
272
+
273
+ ```ts
274
+ import {
275
+ createPreferencePresetCatalog,
276
+ PREFERENCE_PRESET_DEFINITIONS,
277
+ } from "@contractspec/lib.personalization";
278
+
279
+ const catalog = createPreferencePresetCatalog({
280
+ calmReview: {
281
+ id: "calmReview",
282
+ label: "Calm review",
283
+ intent: "A slower review flow with fewer visual interruptions.",
284
+ dimensions: {
285
+ ...PREFERENCE_PRESET_DEFINITIONS.auditReview.dimensions,
286
+ media: "text",
287
+ pace: "deliberate",
288
+ },
289
+ },
290
+ });
291
+ ```
292
+
293
+ Behavior support presets are also editable starting points, not user types:
294
+
295
+ - `steadyMomentum`: consistent progress with moderate support.
296
+ - `activationFirst`: reduce start friction and help users begin.
297
+ - `permissionFirst`: make smaller starts, pauses, or renegotiation easy.
298
+ - `deepWorkBuilder`: protect focus, mastery, and intentional work.
299
+ - `recoveryFirst`: help users resume after misses or interruptions.
300
+ - `identityBuilder`: connect action to user-defined values or commitments.
301
+ - `selfAuthorityBuilder`: build confidence, composure, structure, and follow-through.
302
+ - `socialMomentum`: support shared rhythm or review when explicitly wanted.
303
+ - `deadlineSprint`: support short-term urgency and focused execution.
304
+ - `minimalNudge`: keep support low-noise with minimal intervention.
305
+
306
+ Good UI wording: "Suggested support style: Recovery-first." Bad UI wording: "You are a recovery-first user."
307
+
308
+ ### Onboarding recommendation
309
+
310
+ Recommend first settings from intent and product questions, not role stereotypes. Ask simple questions such as:
311
+
312
+ - What kind of guidance do you prefer?
313
+ - Do you prefer summaries or details?
314
+ - Do you prefer simple controls or advanced controls?
315
+ - What helps you start?
316
+ - What action size feels easiest to trust?
317
+ - What should happen when something is missed?
318
+ - Do you want private progress, self-review, or shared review?
319
+ - What makes progress meaningful?
320
+
321
+ ```ts
322
+ import {
323
+ getPreferencePresetDimensions,
324
+ getBehaviorSupportPresetDimensions,
325
+ recommendAdaptiveExperience,
326
+ } from "@contractspec/lib.personalization";
327
+
328
+ const recommendation = recommendAdaptiveExperience({
329
+ interaction: {
330
+ primaryIntent: "reviewing",
331
+ detailPreference: "evidence",
332
+ controlPreference: "advanced",
333
+ role: "Manager", // recorded for context, not used for scoring
334
+ },
335
+ behaviorSupport: {
336
+ startSupport: "guided",
337
+ actionSize: "small",
338
+ recoveryPreference: "repair",
339
+ },
340
+ });
341
+
342
+ const preferences = getPreferencePresetDimensions(
343
+ recommendation.selectedInteractionPreset
344
+ );
345
+ const behaviorSupport = getBehaviorSupportPresetDimensions(
346
+ recommendation.selectedBehaviorSupportPreset
347
+ );
348
+
349
+ console.log(recommendation.reasons);
350
+ console.log(recommendation.alternativeInteractionPresets);
351
+ console.log(recommendation.alternativeBehaviorSupportPresets);
352
+ ```
353
+
354
+ The recommendation returns selected interaction and behavior support presets, confidence, human-readable reasons, alternatives, and editable dimension lists. Role text may be recorded as context, but it does not score presets because a job title should not decide the experience.
355
+
356
+ ### Behavior signals are evidence
357
+
358
+ `BehaviorSignalModel` records observations that may support an adaptation. A signal is not a conclusion about the user.
359
+
360
+ Safe examples:
361
+
362
+ - user repeatedly switches one table to a more detailed view
363
+ - user completes smaller actions more often than large ones
364
+ - user skips long reflections but completes short ones
365
+ - user dismisses social/accountability prompts
366
+ - user uses advanced controls often
367
+ - user repeatedly chooses repair over reset
368
+
369
+ Unsafe interpretations:
370
+
371
+ - user is lazy
372
+ - user lacks discipline
373
+ - user wants to be controlled
374
+ - user is unreliable
375
+ - user has a psychological condition
376
+ - user is low-performing
377
+
378
+ ```ts
379
+ import { createBehaviorSignalModel } from "@contractspec/lib.personalization";
380
+
381
+ const signal = createBehaviorSignalModel({
382
+ id: "brief-reflection-pattern",
383
+ kind: "repeated_pattern",
384
+ summary: "User completes brief reflections more often than long reflections.",
385
+ evidence: {
386
+ repeatedPattern: "Brief reflections completed in three sessions.",
387
+ timeWindow: { start: "2026-04-01T00:00:00Z" },
388
+ scope: { level: "workflow", id: "review" },
389
+ confidence: "high",
390
+ source: "system-observation",
391
+ userFeedback: "not-asked",
392
+ safetyLevel: "safe",
393
+ observations: [
394
+ "Completed brief reflection in session 1.",
395
+ "Completed brief reflection in session 2.",
396
+ "Completed brief reflection in session 3.",
397
+ ],
398
+ suggestedAdaptation: {
399
+ id: "brief-reflection-default",
400
+ label: "Use brief reflection",
401
+ description: "Use brief reflection by default for this workflow.",
402
+ target: "behaviorSupport",
403
+ dimension: "reflection",
404
+ value: "brief",
405
+ scope: { level: "workflow", id: "review" },
406
+ impact: "low",
407
+ },
408
+ },
409
+ });
410
+ ```
411
+
412
+ The helper rejects common unsafe labels so tests and logs stay observation-oriented.
413
+
414
+ ### Runtime resolution
415
+
416
+ `ResolvedAdaptiveExperience` combines preferences, behavior support, signals, current context, surface, intent, product constraints, permissions, policies, and explicit overrides. It answers: "What should the application do now?"
417
+
418
+ ```ts
419
+ import {
420
+ resolveAdaptiveExperience,
421
+ PREFERENCE_DIMENSION_PRESETS,
422
+ BEHAVIOR_SUPPORT_PRESETS,
423
+ } from "@contractspec/lib.personalization";
424
+
425
+ const resolved = resolveAdaptiveExperience({
426
+ preferences: PREFERENCE_DIMENSION_PRESETS.balanced,
427
+ behaviorSupport: BEHAVIOR_SUPPORT_PRESETS.steadyMomentum,
428
+ behaviorSignals: [signal],
429
+ context: { workflowId: "review" },
430
+ permissions: [
431
+ {
432
+ key: "advanced-controls",
433
+ allowed: false,
434
+ reason: "Advanced controls are not permitted.",
435
+ },
436
+ ],
437
+ });
438
+ ```
439
+
440
+ The resolved result is `runtime-only`. Do not persist it as a hidden user profile. Persist explicit choices, accepted suggestions, or scoped preference records instead.
441
+
442
+ ### Preference evolution
443
+
444
+ Evolution suggestions are deterministic and explainable. They do not mutate preferences by themselves.
445
+
446
+ Start with surface-level suggestions, then promote to workflow, workspace, or user scope only when behavior is consistent across multiple sessions and surfaces. Explicit user choices beat inferred behavior. Changes that affect `control`, `dataDepth`, `challenge`, `accountability`, or social exposure require confirmation because they can change perceived power, data exposure, pressure, or visibility.
447
+
448
+ ```ts
449
+ import { suggestAdaptiveExperienceEvolution } from "@contractspec/lib.personalization";
450
+
451
+ const result = suggestAdaptiveExperienceEvolution({
452
+ currentPreferences: preferences,
453
+ currentBehaviorSupport: behaviorSupport,
454
+ preferenceObservations: [
455
+ {
456
+ dimension: "density",
457
+ value: "detailed",
458
+ signal: "setting_changed",
459
+ surfaceId: "orders",
460
+ sessionId: "s1",
461
+ reason: "Changed orders density to detailed.",
462
+ },
463
+ {
464
+ dimension: "density",
465
+ value: "detailed",
466
+ signal: "setting_changed",
467
+ surfaceId: "orders",
468
+ sessionId: "s2",
469
+ },
470
+ {
471
+ dimension: "density",
472
+ value: "detailed",
473
+ signal: "setting_changed",
474
+ surfaceId: "orders",
475
+ sessionId: "s3",
476
+ },
477
+ ],
478
+ behaviorSignals: [signal],
479
+ });
480
+
481
+ console.log(result.preferenceSuggestions);
482
+ console.log(result.behaviorSupportSuggestions);
483
+ ```
484
+
485
+ Recommended UI wording:
486
+
487
+ - "You often switch this table to detailed mode. Remember detailed mode here?"
488
+ - "You complete more actions when they start small. Use smaller first steps for this workflow?"
489
+ - "You often choose repair instead of reset. Suggest repair first after missed actions?"
490
+ - "You often skip long reflections. Use brief reflection by default?"
491
+ - "You regularly dismiss shared review prompts. Keep accountability private by default?"
492
+
493
+ Avoid wording that implies an identity profile or hidden optimization.
494
+
495
+ ### Scope and examples
496
+
497
+ Adapt narrowly first. If a user repeatedly changes one table to detailed mode, do not make every product screen detailed. If a user repeatedly asks for smaller actions in one workflow, do not shrink every task globally. Promote from surface to workflow, workspace, or user scope only with stronger evidence and confirmation.
498
+
499
+ Generic integration examples:
500
+
501
+ - Adaptive dashboard: compact UI with detailed mode remembered for one table after repeated explicit switches.
502
+ - Guided onboarding: walkthrough interaction preset with activation-first support for the first setup flow.
503
+ - Review workflow: detailed audit mode with brief reflection and neutral recovery language.
504
+ - Focus workflow: minimal UI with protected focus blocks and self-review.
505
+ - Recovery after skipped action: suggest repair first, not shame or reset by default.
506
+ - Compact expert mode with gentle support: advanced controls stay visible, but first actions remain small and reversible.
507
+ - Detailed audit mode with minimal nudging: exhaustive data remains available while behavior support stays private and low-noise.
508
+
509
+ ### Safety boundaries
510
+
511
+ - Preferences do not grant authorization.
512
+ - Behavior support does not replace business rules or permissions.
513
+ - Behavior observations are evidence, not psychological explanations.
514
+ - Resolved adaptive experiences are runtime outputs, not stored identities.
515
+ - No black-box machine learning is used.
516
+ - High-impact changes require confirmation.
517
+ - Suggestions are reversible and scoped.
518
+ - Applications should log or display what changed, why it changed, what evidence supported it, whether it was automatic or suggested, and how to undo or disable adaptation.
519
+ - Adaptation should never silently increase pressure, accountability, challenge, or social exposure.
520
+
194
521
  ## Public entrypoints
195
522
 
196
523
  The root barrel at `src/index.ts` re-exports public symbols from:
197
524
 
198
525
  - `adapter`
526
+ - `adaptive-evolution`
527
+ - `adaptive-experience`
528
+ - `adaptive-onboarding`
199
529
  - `analyzer`
530
+ - `behavior-signals`
531
+ - `behavior-support`
200
532
  - `data-view-preferences`
201
533
  - `preference-dimensions`
534
+ - `preference-evolution`
535
+ - `preference-evolution-types`
536
+ - `preference-onboarding`
537
+ - `preference-presets`
202
538
  - `store`
203
539
  - `tracker`
204
540
  - `types`
@@ -207,13 +543,26 @@ Published subpaths from `package.json`:
207
543
 
208
544
  - `.`
209
545
  - `./adapter`
546
+ - `./adaptive-evolution`
547
+ - `./adaptive-experience`
548
+ - `./adaptive-onboarding`
549
+ - `./adaptive-onboarding-scores`
210
550
  - `./analyzer`
551
+ - `./behavior-signals`
552
+ - `./behavior-support`
553
+ - `./behavior-support-preset-definitions`
554
+ - `./behavior-support-presets`
211
555
  - `./data-view-preferences`
212
556
  - `./docs`
213
557
  - `./docs/behavior-tracking.docblock`
214
558
  - `./docs/overlay-engine.docblock`
215
559
  - `./docs/workflow-composition.docblock`
560
+ - `./personalization.feature`
216
561
  - `./preference-dimensions`
562
+ - `./preference-evolution`
563
+ - `./preference-evolution-types`
564
+ - `./preference-onboarding`
565
+ - `./preference-presets`
217
566
  - `./store`
218
567
  - `./tracker`
219
568
  - `./types`
@@ -230,6 +579,7 @@ For application code, prefer `.` or the focused subpaths above. The `./docs*` su
230
579
  - `insightsToOverlaySuggestion()` currently emits only `hideField` and `reorderFields` modifications.
231
580
  - `layoutPreference` is still inferred from field-count thresholds. Data-view-specific preferred modes are derived from `data_view_interaction` events when those events include a valid collection `viewMode`.
232
581
  - `PreferenceDimensions` and related types are contracts. Durable persistence and runtime resolution live elsewhere.
582
+ - Preset recommendation and preference evolution helpers are deterministic utilities. They return explainable data for applications to display, log, confirm, or ignore.
233
583
 
234
584
  ## When not to use this package
235
585
 
@@ -0,0 +1,40 @@
1
+ import type { BehaviorSignalModel } from './behavior-signals';
2
+ import type { BehaviorSupportDimension, BehaviorSupportDimensions, BehaviorSupportDimensionValue } from './behavior-support';
3
+ import type { PreferenceDimensions } from './preference-dimensions';
4
+ import { type PreferenceEvolutionInput, type PreferenceEvolutionSuggestion } from './preference-evolution';
5
+ export interface AdaptiveExperienceEvolutionInput {
6
+ currentPreferences: PreferenceDimensions;
7
+ currentBehaviorSupport: BehaviorSupportDimensions;
8
+ preferenceObservations?: PreferenceEvolutionInput['observations'];
9
+ behaviorSignals?: BehaviorSignalModel[];
10
+ preferredScope?: PreferenceEvolutionInput['preferredScope'];
11
+ }
12
+ export interface BehaviorSupportEvolutionEvidence {
13
+ signalIds: string[];
14
+ confidence: 'low' | 'medium' | 'high';
15
+ observations: string[];
16
+ }
17
+ export interface BehaviorSupportEvolutionSuggestion {
18
+ id: string;
19
+ dimension: BehaviorSupportDimension;
20
+ from: BehaviorSupportDimensionValue;
21
+ to: BehaviorSupportDimensionValue;
22
+ scope: 'surface' | 'workflow' | 'workspace' | 'user';
23
+ requiresConfirmation: boolean;
24
+ reversible: true;
25
+ automatic: false;
26
+ reasons: string[];
27
+ evidence: BehaviorSupportEvolutionEvidence;
28
+ patch: Partial<BehaviorSupportDimensions>;
29
+ }
30
+ export interface SuppressedAdaptiveEvolutionSuggestion {
31
+ id: string;
32
+ reason: string;
33
+ signalIds: string[];
34
+ }
35
+ export interface AdaptiveExperienceEvolutionResult {
36
+ preferenceSuggestions: PreferenceEvolutionSuggestion[];
37
+ behaviorSupportSuggestions: BehaviorSupportEvolutionSuggestion[];
38
+ suppressedSuggestions: SuppressedAdaptiveEvolutionSuggestion[];
39
+ }
40
+ export declare function suggestAdaptiveExperienceEvolution({ currentPreferences, currentBehaviorSupport, preferenceObservations, behaviorSignals, preferredScope, }: AdaptiveExperienceEvolutionInput): AdaptiveExperienceEvolutionResult;
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ var f=new Set(["control","dataDepth"]);function l({current:e,observations:r,preferredScope:n="surface",minimumEvidenceCount:i=3,minimumSessionCount:o=2,minimumSurfaceCountForGlobal:t=2}){let u=new Set(r.filter((c)=>c.explicit===!0).map((c)=>c.dimension));return v(r).filter((c)=>c.value!==e[c.dimension]).filter((c)=>!u.has(c.dimension)||c.explicit).map((c)=>P(c,e,{minimumEvidenceCount:i,minimumSessionCount:o,minimumSurfaceCountForGlobal:t,preferredScope:n})).filter((c)=>c!==void 0)}function v(e){let r=new Map;for(let n of e){if(!S(n.dimension,n.value))continue;let i=[n.dimension,n.value,n.signal,n.explicit?"explicit":"inferred"].join(":"),o=r.get(i);if(o)o.events.push(n);else r.set(i,{dimension:n.dimension,value:n.value,signal:n.signal,explicit:n.explicit===!0,events:[n]})}return Array.from(r.values())}function P(e,r,n){let i=a(e.events,e.signal);if(!e.explicit&&i.count<n.minimumEvidenceCount)return;if(!e.explicit&&i.sessionCount<n.minimumSessionCount)return;let o=d(e,i,n),t=!e.explicit||o!=="surface"||f.has(e.dimension);return{id:["preference-evolution",o,e.dimension,String(e.value)].join(":"),dimension:e.dimension,from:r[e.dimension],to:e.value,scope:o,requiresConfirmation:t,reversible:!0,reasons:C(e,i,o),evidence:i,patch:{[e.dimension]:e.value}}}function d(e,r,n){if(e.explicit)return n.preferredScope;if(n.preferredScope==="surface")return"surface";return r.surfaceCount>=n.minimumSurfaceCountForGlobal?n.preferredScope:"surface"}function a(e,r){let n=new Set(e.map((o)=>o.sessionId).filter(Boolean)),i=new Set(e.map((o)=>o.surfaceId).filter(Boolean));return{signal:r,count:e.reduce((o,t)=>o+(t.count??1),0),sessionCount:n.size||1,surfaceCount:i.size||1,reasons:Array.from(new Set(e.flatMap((o)=>o.reason?[o.reason]:[])))}}function C(e,r,n){let i=[`Observed ${r.count} ${e.signal.replaceAll("_"," ")} signals across ${r.sessionCount} session(s).`,`Suggested as a ${n} preference change, not a hidden global mutation.`];if(e.explicit)i.push("Explicit user choices take priority over inferred behavior.");if(f.has(e.dimension))i.push("This dimension can affect control or data exposure, so confirmation is required.");return[...i,...r.reasons]}var p={guidance:"|none|hints|tooltips|walkthrough|wizard|",density:"|minimal|compact|standard|detailed|dense|",dataDepth:"|summary|standard|detailed|exhaustive|",control:"|restricted|standard|advanced|full|",media:"|text|visual|voice|hybrid|",pace:"|deliberate|balanced|rapid|",narrative:"|top-down|bottom-up|adaptive|"};function S(e,r){return p[e].includes(`|${r}|`)}var m=new Set(["challenge","accountability","environment"]);function U({currentPreferences:e,currentBehaviorSupport:r,preferenceObservations:n=[],behaviorSignals:i=[],preferredScope:o="surface"}){let t=l({current:e,observations:n,preferredScope:o}),u=D({currentBehaviorSupport:r,behaviorSignals:i});return{preferenceSuggestions:t,behaviorSupportSuggestions:u.suggestions,suppressedSuggestions:u.suppressed}}function D({currentBehaviorSupport:e,behaviorSignals:r}){let n=[],i=[];for(let o of r??[]){let t=o.evidence.suggestedAdaptation;if(!t||t.target!=="behaviorSupport")continue;let u=t.dimension;if(!M(u)){i.push({id:t.id,reason:"Suggested behavior support dimension is not recognized.",signalIds:[o.id]});continue}if(!g(u,t.value)){i.push({id:t.id,reason:"Suggested behavior support value does not match the dimension.",signalIds:[o.id]});continue}let s=t.value;if(s===e[u])continue;let c=(t.requiresConfirmation??t.impact!=="low")||m.has(u);n.push({id:t.id,dimension:u,from:e[u],to:s,scope:t.scope.level,requiresConfirmation:c,reversible:!0,automatic:!1,reasons:I(o,u),evidence:{signalIds:[o.id],confidence:o.evidence.confidence,observations:o.evidence.observations},patch:{[u]:s}})}return{suggestions:n,suppressed:i}}function I(e,r){let n=["Behavior support changes are suggestions, not silent mutations.","The signal describes scoped observed behavior, not a user identity.","The suggestion is reversible and should be explainable in the UI."];if(m.has(r))n.push("Changes to challenge, accountability, or social exposure require confirmation.");if(e.evidence.userFeedback)n.push(`User feedback state: ${e.evidence.userFeedback}.`);return n}var E={attention:["ambient","next-step","priority","review"],activation:["self-start","prompted","guided-start","ritual"],actionScale:["tiny","small","standard","large"],rhythm:["flexible","steady","time-boxed","deadline-driven"],environment:["open","structured","focused","collaborative"],challenge:["low","moderate","stretch","high"],meaningFrame:["progress","mastery","impact","relief","belonging","agency"],permission:["proceed","start-smaller","pause","renegotiate"],selfAuthority:["light","structured","confidence-building","high-autonomy"],accountability:["private","self-review","peer-review","external-review"],recovery:["resume","repair","reset","renegotiate"],reflection:["none","brief","standard","deep"]};function M(e){return Object.prototype.hasOwnProperty.call(E,e)}function g(e,r){return r?E[e].includes(r):!1}export{U as suggestAdaptiveExperienceEvolution};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ import type { AdaptiveScope, BehaviorSignalModel, BehaviorSignalSafetyLevel } from './behavior-signals';
2
+ import type { BehaviorSupportDimensions } from './behavior-support';
3
+ import type { PreferenceDimensions } from './preference-dimensions';
4
+ export interface AdaptiveExperienceContext {
5
+ surfaceId?: string;
6
+ workflowId?: string;
7
+ workspaceId?: string;
8
+ userIntent?: string;
9
+ currentSurface?: string;
10
+ timestamp?: string;
11
+ }
12
+ export interface AdaptiveExperiencePermission {
13
+ key: string;
14
+ allowed: boolean;
15
+ reason?: string;
16
+ }
17
+ export interface AdaptiveExperienceConstraint {
18
+ id: string;
19
+ reason: string;
20
+ target?: string;
21
+ blocksAdaptation?: boolean;
22
+ }
23
+ export interface AdaptiveExperiencePolicy {
24
+ id: string;
25
+ effect: 'allow' | 'constrain' | 'block' | 'require-confirmation';
26
+ reason: string;
27
+ target?: string;
28
+ }
29
+ export interface AdaptiveExperienceOverride {
30
+ target: 'preference' | 'behaviorSupport' | 'runtimeAction';
31
+ key: string;
32
+ value: unknown;
33
+ reason?: string;
34
+ }
35
+ export interface AdaptiveExperienceAction {
36
+ id: string;
37
+ kind: 'ui' | 'guidance' | 'next-action' | 'recovery' | 'focus' | 'reflection';
38
+ scope: AdaptiveScope;
39
+ description: string;
40
+ requiresConfirmation: boolean;
41
+ reversible: boolean;
42
+ evidenceIds: string[];
43
+ safetyLevel: BehaviorSignalSafetyLevel;
44
+ }
45
+ export interface SuppressedAdaptiveExperienceAction extends AdaptiveExperienceAction {
46
+ suppressedReason: string;
47
+ }
48
+ export interface ResolveAdaptiveExperienceInput {
49
+ preferences: PreferenceDimensions;
50
+ behaviorSupport: BehaviorSupportDimensions;
51
+ behaviorSignals?: BehaviorSignalModel[];
52
+ context?: AdaptiveExperienceContext;
53
+ permissions?: AdaptiveExperiencePermission[];
54
+ constraints?: AdaptiveExperienceConstraint[];
55
+ policies?: AdaptiveExperiencePolicy[];
56
+ overrides?: AdaptiveExperienceOverride[];
57
+ }
58
+ export interface ResolvedAdaptiveExperience {
59
+ interaction: PreferenceDimensions;
60
+ behaviorSupport: BehaviorSupportDimensions;
61
+ context: AdaptiveExperienceContext;
62
+ appliedAdaptations: AdaptiveExperienceAction[];
63
+ suppressedAdaptations: SuppressedAdaptiveExperienceAction[];
64
+ reasons: string[];
65
+ evidenceIds: string[];
66
+ constraints: AdaptiveExperienceConstraint[];
67
+ permissions: AdaptiveExperiencePermission[];
68
+ policies: AdaptiveExperiencePolicy[];
69
+ overrides: AdaptiveExperienceOverride[];
70
+ persistence: 'runtime-only';
71
+ canUndo: boolean;
72
+ userFacingSummary: string;
73
+ }
74
+ export declare function resolveAdaptiveExperience({ preferences, behaviorSupport, behaviorSignals, context, permissions, constraints, policies, overrides, }: ResolveAdaptiveExperienceInput): ResolvedAdaptiveExperience;
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ function y({preferences:e,behaviorSupport:i,behaviorSignals:s=[],context:c={},permissions:a=[],constraints:r=[],policies:p=[],overrides:o=[]}){let d=s.flatMap(g),n=[],u=[];for(let t of d){let v=h(t,p,o),l=E(v,a,r,p,o);if(l)u.push({...v,suppressedReason:l});else n.push(v)}let A=s.map((t)=>t.id),x=b({appliedAdaptations:n,suppressedAdaptations:u,overrides:o});return{interaction:{...e},behaviorSupport:{...i},context:{...c},appliedAdaptations:n,suppressedAdaptations:u,reasons:x,evidenceIds:A,constraints:r.map((t)=>({...t})),permissions:a.map((t)=>({...t})),policies:p.map((t)=>({...t})),overrides:o.map((t)=>({...t})),persistence:"runtime-only",canUndo:!0,userFacingSummary:"This runtime result explains what changed, why it changed, and how it can be undone."}}function g(e){let i=e.evidence.suggestedAdaptation;if(!i)return[];return[{id:i.id,kind:m(i.target,i.dimension),scope:i.scope,description:i.description,requiresConfirmation:(i.requiresConfirmation??i.impact!=="low")||e.evidence.safetyLevel!=="safe",reversible:!0,evidenceIds:[e.id],safetyLevel:e.evidence.safetyLevel}]}function m(e,i){if(e==="preference")return"ui";if(i==="recovery")return"recovery";if(i==="reflection")return"reflection";if(i==="environment")return"focus";if(e==="behaviorSupport")return"next-action";return"guidance"}function E(e,i,s,c,a){let r=a.find((n)=>n.target==="runtimeAction"&&f(e,n.key)&&n.value===!1);if(r)return r.reason??"Explicit override disabled this action.";let p=i.find((n)=>!n.allowed&&e.id.includes(n.key));if(p)return p.reason??"Permission denied.";let o=s.find((n)=>n.blocksAdaptation&&(!n.target||e.id.includes(n.target)));if(o)return o.reason;let d=c.find((n)=>n.effect==="block"&&(!n.target||e.id.includes(n.target)));if(d)return d.reason;return}function h(e,i,s){let c=i.some((r)=>(r.effect==="require-confirmation"||r.effect==="constrain")&&(!r.target||f(e,r.target))),a=s.some((r)=>r.target==="runtimeAction"&&f(e,r.key)&&(r.value==="require-confirmation"||r.value==="confirm"));if(!c&&!a)return e;return{...e,requiresConfirmation:!0}}function f(e,i){return e.id.includes(i)||e.kind===i}function b(e){let i=["Resolved adaptive experience is runtime-only and should not be stored as a hidden user profile.","Permissions, constraints, policy, and explicit overrides bound all adaptation."];if(e.appliedAdaptations.length>0)i.push("Scoped behavior evidence produced explainable runtime actions.");if(e.suppressedAdaptations.length>0)i.push("Some suggested adaptations were suppressed by safety boundaries.");if(e.overrides.length>0)i.push("Explicit overrides were preserved as higher priority context.");return i}export{y as resolveAdaptiveExperience};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { BehaviorSupportOnboardingSignals } from './adaptive-onboarding';
2
+ import { type BehaviorSupportPresetId } from './behavior-support';
3
+ export type BehaviorSupportPresetScores = Record<BehaviorSupportPresetId, number>;
4
+ export declare function scoreBehaviorSupportSignals(signals: BehaviorSupportOnboardingSignals): {
5
+ scores: BehaviorSupportPresetScores;
6
+ reasons: string[];
7
+ signalCount: number;
8
+ };
9
+ export declare function calculateBehaviorRecommendationConfidence(score: number, nextScore: number, signalCount: number): number;
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ var s=["steadyMomentum","activationFirst","permissionFirst","deepWorkBuilder","recoveryFirst","identityBuilder","selfAuthorityBuilder","socialMomentum","deadlineSprint","minimalNudge"],a={steadyMomentum:{attention:"next-step",activation:"prompted",actionScale:"standard",rhythm:"steady",environment:"structured",challenge:"moderate",meaningFrame:"progress",permission:"proceed",selfAuthority:"structured",accountability:"self-review",recovery:"resume",reflection:"brief"},activationFirst:{attention:"next-step",activation:"guided-start",actionScale:"small",rhythm:"flexible",environment:"structured",challenge:"low",meaningFrame:"relief",permission:"start-smaller",selfAuthority:"confidence-building",accountability:"private",recovery:"resume",reflection:"brief"},permissionFirst:{attention:"ambient",activation:"prompted",actionScale:"small",rhythm:"flexible",environment:"open",challenge:"low",meaningFrame:"agency",permission:"renegotiate",selfAuthority:"confidence-building",accountability:"private",recovery:"renegotiate",reflection:"brief"},deepWorkBuilder:{attention:"priority",activation:"ritual",actionScale:"standard",rhythm:"time-boxed",environment:"focused",challenge:"stretch",meaningFrame:"mastery",permission:"proceed",selfAuthority:"high-autonomy",accountability:"self-review",recovery:"repair",reflection:"standard"},recoveryFirst:{attention:"next-step",activation:"guided-start",actionScale:"small",rhythm:"flexible",environment:"structured",challenge:"low",meaningFrame:"relief",permission:"renegotiate",selfAuthority:"confidence-building",accountability:"private",recovery:"repair",reflection:"brief"},identityBuilder:{attention:"review",activation:"ritual",actionScale:"standard",rhythm:"steady",environment:"structured",challenge:"moderate",meaningFrame:"agency",permission:"proceed",selfAuthority:"structured",accountability:"self-review",recovery:"repair",reflection:"standard"},selfAuthorityBuilder:{attention:"priority",activation:"prompted",actionScale:"standard",rhythm:"steady",environment:"structured",challenge:"moderate",meaningFrame:"agency",permission:"proceed",selfAuthority:"confidence-building",accountability:"self-review",recovery:"repair",reflection:"standard"},socialMomentum:{attention:"priority",activation:"prompted",actionScale:"standard",rhythm:"steady",environment:"collaborative",challenge:"moderate",meaningFrame:"belonging",permission:"proceed",selfAuthority:"structured",accountability:"peer-review",recovery:"repair",reflection:"brief"},deadlineSprint:{attention:"priority",activation:"prompted",actionScale:"small",rhythm:"deadline-driven",environment:"focused",challenge:"stretch",meaningFrame:"impact",permission:"proceed",selfAuthority:"structured",accountability:"self-review",recovery:"resume",reflection:"brief"},minimalNudge:{attention:"ambient",activation:"self-start",actionScale:"standard",rhythm:"flexible",environment:"open",challenge:"moderate",meaningFrame:"progress",permission:"proceed",selfAuthority:"high-autonomy",accountability:"private",recovery:"resume",reflection:"none"}};function b(e){return{...a[e]}}var u={steadyMomentum:i("steadyMomentum","Steady momentum","Consistent progress with moderate support."),activationFirst:i("activationFirst","Activation-first","Reduces start friction and makes the first useful action easier."),permissionFirst:i("permissionFirst","Permission-first","Helps users start smaller, pause, or renegotiate without friction."),deepWorkBuilder:i("deepWorkBuilder","Deep work builder","Protects focus, mastery, and intentional work."),recoveryFirst:i("recoveryFirst","Recovery-first","Makes repair and resumption easier after misses or interruptions."),identityBuilder:i("identityBuilder","Identity builder","Connects action to user-defined values or commitments."),selfAuthorityBuilder:i("selfAuthorityBuilder","Self-authority builder","Builds confidence, composure, structure, and follow-through."),socialMomentum:i("socialMomentum","Social momentum","Uses shared rhythm, collaboration, or review when explicitly wanted."),deadlineSprint:i("deadlineSprint","Deadline sprint","Supports short-term urgency and focused execution."),minimalNudge:i("minimalNudge","Minimal nudge","Keeps behavior support low-noise with minimal intervention.")};function A(e){let r=u[e];return{...r,dimensions:{...r.dimensions}}}function i(e,r,o){return{id:e,label:r,intent:o,dimensions:a[e]}}function k(e){let r=f(),o=[],t=0,n=(m,p,c)=>{if(r[m]+=p,c)o.push(c)};if(e.startSupport)t+=1,l(e.startSupport,n);if(e.actionSize)t+=1,d(e.actionSize,n);if(e.recoveryPreference)t+=1,y(e.recoveryPreference,n);if(e.accountabilityPreference)t+=1,h(e.accountabilityPreference,n);if(e.rhythmPreference)t+=1,v(e.rhythmPreference,n);if(e.meaningPreference)t+=1,S(e.meaningPreference,n);if(e.reflectionPreference)t+=1,g(e.reflectionPreference,n);if(e.role)o.push("Role text was recorded for context but did not score support presets.");return{scores:r,reasons:o,signalCount:t}}function I(e,r,o){if(o===0)return 0.35;let t=0.45+Math.min(e/(o*4),0.4)+Math.min((e-r)*0.05,0.15);return Math.round(Math.min(t,0.95)*100)/100}function f(){return s.reduce((e,r)=>({...e,[r]:r==="steadyMomentum"?1:0}),{})}function l(e,r){if(e==="self-start")r("minimalNudge",4,"You prefer low-noise starts.");if(e==="prompt")r("steadyMomentum",3,"You prefer a clear prompt to begin.");if(e==="guided")r("activationFirst",4,"You prefer guided start support.");if(e==="ritual")r("deepWorkBuilder",4,"You prefer a repeatable start ritual.")}function d(e,r){if(e==="tiny")r("activationFirst",3,"Tiny first steps feel easier to trust.");if(e==="small")r("permissionFirst",3,"Small first steps feel easier to trust.");if(e==="standard")r("steadyMomentum",2,"Standard next actions fit you.");if(e==="large")r("deepWorkBuilder",2,"You prefer substantial action blocks.")}function y(e,r){if(e==="repair")r("recoveryFirst",5,"Repair should be easy after a miss.");if(e==="renegotiate")r("permissionFirst",4,"Renegotiation should stay available.");if(e==="resume")r("steadyMomentum",2,"You prefer to resume without a reset.");if(e==="reset")r("activationFirst",2,"A clean restart can be useful.")}function h(e,r){if(e==="private")r("minimalNudge",3,"You prefer private progress.");if(e==="self-review")r("selfAuthorityBuilder",3,"You prefer self-review.");if(e==="shared-review")r("socialMomentum",4,"You prefer shared review.")}function v(e,r){if(e==="flexible")r("permissionFirst",2);if(e==="steady")r("steadyMomentum",3);if(e==="focus-block")r("deepWorkBuilder",4);if(e==="deadline")r("deadlineSprint",4)}function S(e,r){if(e==="mastery")r("deepWorkBuilder",3);if(e==="impact")r("deadlineSprint",2);if(e==="relief")r("recoveryFirst",3);if(e==="agency")r("identityBuilder",3);if(e==="progress")r("steadyMomentum",2)}function g(e,r){if(e==="none")r("minimalNudge",3);if(e==="brief")r("steadyMomentum",2);if(e==="standard")r("selfAuthorityBuilder",2);if(e==="deep")r("deepWorkBuilder",3)}export{k as scoreBehaviorSupportSignals,I as calculateBehaviorRecommendationConfidence};
@@ -0,0 +1,46 @@
1
+ import type { BehaviorSupportDimension } from './behavior-support';
2
+ import { type BehaviorSupportPresetId } from './behavior-support';
3
+ import type { PreferenceDimensions } from './preference-dimensions';
4
+ import { type PreferenceOnboardingSignals, type PreferencePresetAlternative } from './preference-onboarding';
5
+ import type { PreferencePresetId } from './preference-presets';
6
+ export interface BehaviorSupportOnboardingSignals {
7
+ startSupport?: 'self-start' | 'prompt' | 'guided' | 'ritual';
8
+ actionSize?: 'tiny' | 'small' | 'standard' | 'large';
9
+ recoveryPreference?: 'resume' | 'repair' | 'reset' | 'renegotiate';
10
+ accountabilityPreference?: 'private' | 'self-review' | 'shared-review';
11
+ rhythmPreference?: 'flexible' | 'steady' | 'focus-block' | 'deadline';
12
+ meaningPreference?: 'progress' | 'mastery' | 'impact' | 'relief' | 'agency';
13
+ reflectionPreference?: 'none' | 'brief' | 'standard' | 'deep';
14
+ /** Weak context only. Role text must not score behavior support presets. */
15
+ role?: string;
16
+ }
17
+ export interface BehaviorSupportPresetAlternative {
18
+ preset: BehaviorSupportPresetId;
19
+ confidence: number;
20
+ reason: string;
21
+ }
22
+ export interface BehaviorSupportPresetRecommendation {
23
+ selectedPreset: BehaviorSupportPresetId;
24
+ confidence: number;
25
+ reasons: string[];
26
+ alternatives: BehaviorSupportPresetAlternative[];
27
+ editableDimensions: BehaviorSupportDimension[];
28
+ }
29
+ export interface AdaptiveExperienceOnboardingSignals {
30
+ interaction?: PreferenceOnboardingSignals;
31
+ behaviorSupport?: BehaviorSupportOnboardingSignals;
32
+ }
33
+ export interface AdaptiveExperienceRecommendation {
34
+ selectedInteractionPreset: PreferencePresetId;
35
+ selectedBehaviorSupportPreset: BehaviorSupportPresetId;
36
+ confidence: number;
37
+ reasons: string[];
38
+ alternativeInteractionPresets: PreferencePresetAlternative[];
39
+ alternativeBehaviorSupportPresets: BehaviorSupportPresetAlternative[];
40
+ editableDimensions: {
41
+ interaction: (keyof PreferenceDimensions)[];
42
+ behaviorSupport: BehaviorSupportDimension[];
43
+ };
44
+ }
45
+ export declare function recommendAdaptiveExperience(signals: AdaptiveExperienceOnboardingSignals): AdaptiveExperienceRecommendation;
46
+ export declare function recommendBehaviorSupportPreset(signals: BehaviorSupportOnboardingSignals): BehaviorSupportPresetRecommendation;