@almadar/std 16.217.0 → 16.218.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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "$generated": "2026-09-15T07:17:39.933Z",
2
+ "$generated": "2026-09-15T15:18:01.053Z",
3
3
  "$source": "tools/almadar-pattern-sync/behaviors",
4
4
  "$package": "@almadar/std",
5
5
  "totalBehaviors": 467,
@@ -2936,6 +2936,7 @@
2936
2936
  "std-ml-infer",
2937
2937
  "std-ml-lookup",
2938
2938
  "std-ml-similarity",
2939
+ "std-notification-preferences",
2939
2940
  "std-physics-diagram",
2940
2941
  "std-physics-field-3d",
2941
2942
  "std-physics-orbit-3d",
@@ -8665,7 +8666,7 @@
8665
8666
  "topic": "infra",
8666
8667
  "family": "infra",
8667
8668
  "layer": "UI Patterns",
8668
- "description": "std-data-import — staged CSV import run, source-agnostic: upload → staged review → confirm → handoff. UPLOAD_CSV opens a run and persists an ImportBatch row (status uploaded, fieldMappingJson recorded verbatim for provenance); the host's file UI parses the CSV and answers with STAGE_ROWS, one JSON string per raw row, which the atom bulk-persists into import_rows against the batch id and presents as a staged review (row/error counts + Confirm/Discard). CONFIRM_IMPORT marks the batch confirmed and emits IMPORT_CONFIRMED { batchId, sourceName, rowCount } — the mapping+persist half is the CONSUMER organism's: it listens for IMPORT_CONFIRMED, fetches import_rows where batchId matches, maps each rowJson through its own field mapping, and persists into its own target entity (cross-atom persist into a consumer's entity is not expressible from here). This is deliberately the CSV-file path: the atom never calls a source service — sourceName/fieldMappingJson/targetEntity/historyWindowDays are declarative consumer configs, and any persist failure lands in failed with IMPORT_FAILED, never a silent swallow. Compose with std-import for the file-picker menu.",
8669
+ "description": "std-data-import — staged CSV import run, source-agnostic: upload → staged review → confirm → handoff. UPLOAD_CSV opens a run and persists an ImportBatch row (status uploaded, fieldMappingJson recorded verbatim for provenance); the host's file UI parses the CSV and answers with STAGE_ROWS, one JSON string per raw row, which the atom bulk-persists into import_rows against the batch id and presents as a staged review (row/error counts + Confirm/Discard). CONFIRM_IMPORT marks the batch confirmed and emits IMPORT_CONFIRMED { batchId, sourceName, rowCount } — the mapping+persist half is the CONSUMER organism's: it listens for IMPORT_CONFIRMED, fetches import_rows where batchId matches, maps each rowJson through its own field mapping, and persists into its own target entity (cross-atom persist into a consumer's entity is not expressible from here). This is deliberately the CSV-file path: the atom never calls a source service — sourceName/fieldMappingJson/targetEntity/historyWindowDays are declarative consumer configs, and any persist failure marks the batch row failed and fires IMPORT_FAILED, never a silent swallow. Compose with std-import for the file-picker menu.",
8669
8670
  "defaultOrbitalName": "DataImportOrbital",
8670
8671
  "statePattern": "confirmed, failed, idle, staged, uploaded",
8671
8672
  "complexity": {
@@ -8998,7 +8999,7 @@
8998
8999
  {
8999
9000
  "name": "BATCH_CREATED",
9000
9001
  "direction": "emit",
9001
- "description": "import_batches persist-create success — the payload carries the created row's id, captured onto the trait entity so staged rows can reference batchId",
9002
+ "description": "import_batches persist-create success — rebinds @entity.id to the server-issued id, the fallback for when the host didn't mint a client-side batchId on UPLOAD_CSV",
9002
9003
  "tier": "secondary"
9003
9004
  },
9004
9005
  {
@@ -9010,7 +9011,7 @@
9010
9011
  {
9011
9012
  "name": "IMPORT_PERSIST_FAILED",
9012
9013
  "direction": "emit",
9013
- "description": "Any import_batches / import_rows persist failure — lands the run in failed, never a silent swallow",
9014
+ "description": "Any import_batches / import_rows persist failure — the batch row is updated to failed and IMPORT_FAILED emitted, never a silent swallow; the trait stays put so the user can retry or discard",
9014
9015
  "tier": "secondary"
9015
9016
  },
9016
9017
  {
@@ -9034,7 +9035,7 @@
9034
9035
  {
9035
9036
  "name": "UPLOAD_CSV",
9036
9037
  "direction": "listen",
9037
- "description": "Starts an import run for a CSV file upload. The host's file UI (e.g. a sibling std-import menu) only announces the upload — parsing is host work and arrives as STAGE_ROWS.",
9038
+ "description": "Starts an import run for a CSV file upload. batchId is the client-minted batch id (idempotent upload — the host generates it so a retry never double-creates a batch); when omitted, the server-issued id is bound on BATCH_CREATED instead. The host's file UI (e.g. a sibling std-import menu) only announces the upload — parsing is host work and arrives as STAGE_ROWS.",
9038
9039
  "synonyms": "upload csv, import csv, start import, import file, bulk import",
9039
9040
  "tier": "domain"
9040
9041
  },
@@ -9285,7 +9286,7 @@
9285
9286
  "complexity": {
9286
9287
  "states": 2,
9287
9288
  "events": 8,
9288
- "transitions": 8
9289
+ "transitions": 7
9289
9290
  },
9290
9291
  "defaultEntity": {
9291
9292
  "name": "SearchQuery",
@@ -9647,7 +9648,7 @@
9647
9648
  {
9648
9649
  "name": "FAN_OUT_STEP",
9649
9650
  "direction": "emit",
9650
- "description": "Internal sentinel draining the module queue, one MODULE_SEARCH_REQUESTED per pass",
9651
+ "description": "Internal sentinel draining the module queue, one MODULE_SEARCH_REQUESTED per pass; `remaining` is the queue length after the last seed/drop",
9651
9652
  "tier": "internal"
9652
9653
  },
9653
9654
  {
@@ -11758,13 +11759,13 @@
11758
11759
  "topic": "infra",
11759
11760
  "family": "infra",
11760
11761
  "layer": "UI Patterns",
11761
- "description": "std-notification-preferences — per-person notification preference store plus a consultable gate. Owns NotificationPreference rows (one per person + event key: channel override in_app/email/push/slack, mode instant/digest, quiet-hours window 'HH:MM-HH:MM' such as 22:00-07:00). The PreferencesManage trait is standard CRUD over the store (list / create / update / delete, persisted, success/failure cascade arms). The PreferenceGate trait is the consult half other notify traits call: emit CHECK_PREFERENCE { personId, eventKey } and the gate fetches the matching row (a row whose eventKey is blank applies to every event) and answers PREFERENCE_RESOLVED { personId, eventKey, channel, mode, suppressed } — suppressed is true only when the row's quietHours window covers the current hour; mode 'digest' rides on the verdict for the caller to defer. Default policy: no matching row — or a failed lookup — resolves fail-open to { channel: in_app, mode: instant, suppressed: false }; the absence of a preference never silences a notification.",
11762
+ "description": "std-notification-preferences — per-person notification preference store plus a consultable gate. Owns NotificationPreference rows (one per person + event key: channel override in_app/email/push/slack, mode instant/digest, quiet-hours window 'HH:MM-HH:MM' such as 22:00-07:00). The PreferencesManage trait is standard CRUD over the store (list / create / update / delete, persisted, success/failure cascade arms): a data-grid browse plus ModalRecordModal create/edit forms whose SAVE carries the full row payload (std-list daisy-chain idiom). The PreferenceGate trait is the consult half other notify traits call: emit CHECK_PREFERENCE { personId, eventKey } and the gate fetches the matching row (a row whose eventKey is blank applies to every event) and answers PREFERENCE_RESOLVED { personId, eventKey, channel, mode, suppressed } — suppressed is true only when the row's quietHours window covers the current hour; mode 'digest' rides on the verdict for the caller to defer. Default policy: no matching row — or a failed lookup — resolves fail-open to { channel: in_app, mode: instant, suppressed: false }; the absence of a preference never silences a notification.",
11762
11763
  "defaultOrbitalName": "NotificationPreferencesOrbital",
11763
- "statePattern": "browsing, creating, editing, error, loading",
11764
+ "statePattern": "browsing, error, loading",
11764
11765
  "complexity": {
11765
- "states": 5,
11766
- "events": 16,
11767
- "transitions": 26
11766
+ "states": 3,
11767
+ "events": 12,
11768
+ "transitions": 13
11768
11769
  },
11769
11770
  "defaultEntity": {
11770
11771
  "name": "NotificationPreference",
@@ -11819,50 +11820,89 @@
11819
11820
  },
11820
11821
  "defaultIcons": [],
11821
11822
  "composableWith": [
11823
+ "std-accounting",
11824
+ "std-agent-builder",
11825
+ "std-alummaalraqamia",
11822
11826
  "std-anim-tick",
11827
+ "std-api-gateway",
11828
+ "std-applicant-form",
11823
11829
  "std-application",
11824
11830
  "std-approval-gate",
11825
11831
  "std-approval-request",
11826
- "std-arcade-board-3d",
11832
+ "std-ats-recruiting",
11827
11833
  "std-audit-capture",
11834
+ "std-booking-system",
11828
11835
  "std-broadcast-builder",
11829
11836
  "std-browse",
11830
11837
  "std-builder",
11831
11838
  "std-cache-aside",
11839
+ "std-calendar",
11832
11840
  "std-calendar-sync",
11833
11841
  "std-cascade-on-delete",
11842
+ "std-cicd-pipeline",
11834
11843
  "std-circuit-breaker",
11835
- "std-confirmation",
11844
+ "std-construction-pm",
11845
+ "std-contract",
11836
11846
  "std-cooldown",
11837
- "std-crew-board-2d",
11847
+ "std-crm",
11838
11848
  "std-cross-reference",
11849
+ "std-customer-success",
11839
11850
  "std-data-erasure",
11840
11851
  "std-data-import",
11841
- "std-event",
11842
- "std-form-advanced",
11852
+ "std-devops-dashboard",
11853
+ "std-document-mgmt",
11854
+ "std-ecommerce",
11855
+ "std-esign-flow",
11856
+ "std-event-ticketing",
11857
+ "std-field-service",
11858
+ "std-finance-tracker",
11859
+ "std-fitness-studio",
11860
+ "std-fleet-mgmt",
11861
+ "std-form-builder",
11862
+ "std-forum",
11843
11863
  "std-game-clock",
11844
11864
  "std-global-search",
11865
+ "std-healthcare",
11866
+ "std-helpdesk",
11867
+ "std-hr-portal",
11845
11868
  "std-image-upload-multi",
11869
+ "std-inspection-system",
11846
11870
  "std-integration-settings",
11871
+ "std-learn-arrangement",
11872
+ "std-learn-classify",
11873
+ "std-learn-estimate",
11874
+ "std-learn-hotspot",
11875
+ "std-learn-predict",
11876
+ "std-learn-speed-drill",
11877
+ "std-ledger-entry-form",
11878
+ "std-legal-case",
11847
11879
  "std-lifecycle",
11880
+ "std-ling-phonology",
11848
11881
  "std-list",
11849
- "std-market-board-3d",
11882
+ "std-listings",
11883
+ "std-lms",
11884
+ "std-logic-fallacy",
11885
+ "std-marketing-campaign",
11886
+ "std-marketplace",
11850
11887
  "std-menu",
11851
11888
  "std-migration-job",
11852
11889
  "std-mod-queue",
11853
- "std-modal",
11854
- "std-modal-editor",
11855
11890
  "std-modifier-group",
11891
+ "std-nonprofit-donations",
11856
11892
  "std-notification-center",
11857
11893
  "std-notify-on-event",
11858
- "std-objective-board-3d",
11859
11894
  "std-permission-matrix",
11860
- "std-purchase-order",
11895
+ "std-property-mgmt",
11896
+ "std-public-help-center",
11861
11897
  "std-rate-limiter",
11862
11898
  "std-record-detail",
11899
+ "std-related",
11863
11900
  "std-reminder-scheduler",
11901
+ "std-restaurant-pos",
11902
+ "std-retail-pos",
11864
11903
  "std-row-access-control",
11865
11904
  "std-saved-search",
11905
+ "std-selection",
11866
11906
  "std-service-accounting",
11867
11907
  "std-service-arxiv",
11868
11908
  "std-service-banking",
@@ -11896,37 +11936,31 @@
11896
11936
  "std-service-webhook",
11897
11937
  "std-service-wikimedia",
11898
11938
  "std-service-youtube",
11939
+ "std-soc-deviance",
11940
+ "std-social-feed",
11899
11941
  "std-status-lifecycle",
11900
11942
  "std-status-lifecycle-control",
11901
- "std-survival-board-3d",
11902
- "std-tactics-board-2d",
11903
- "std-tactics-board-3d",
11904
- "std-trade-order",
11905
- "std-vendor-onboarding",
11906
- "std-waitlist",
11907
- "std-wizard",
11908
- "std-work-order",
11909
- "studio-canvas",
11910
- "ui-code-block",
11911
- "ui-minigolf-board-3d",
11912
- "ui-pirate-board"
11943
+ "std-stock-adjustment",
11944
+ "std-subscription-billing",
11945
+ "std-survey",
11946
+ "std-time-tracking",
11947
+ "std-timeline",
11948
+ "std-trading-dashboard",
11949
+ "std-tree",
11950
+ "std-winning-11"
11913
11951
  ],
11914
11952
  "connectableEvents": [
11915
11953
  "PreferencesLoaded",
11916
11954
  "PreferencesLoadFailed",
11917
- "NEW",
11918
- "EDIT",
11919
11955
  "DELETE",
11956
+ "DO_CREATE",
11957
+ "DO_UPDATE",
11920
11958
  "PreferenceSaved",
11921
11959
  "PreferenceDeleted",
11922
11960
  "PreferenceSaveFailed",
11923
- "SET_PERSON_ID",
11924
- "SET_EVENT_KEY",
11925
- "SET_CHANNEL",
11926
- "SET_MODE",
11927
- "SET_QUIET_HOURS",
11928
- "SAVE",
11929
- "CANCEL"
11961
+ "RETRY",
11962
+ "CREATE",
11963
+ "EDIT"
11930
11964
  ],
11931
11965
  "eventPayloads": {},
11932
11966
  "exposure": "both",
@@ -11937,23 +11971,19 @@
11937
11971
  "orbital": "NotificationPreferencesOrbital",
11938
11972
  "role": "renderer",
11939
11973
  "emittedEvents": [
11940
- "NEW",
11974
+ "CREATE",
11941
11975
  "EDIT",
11942
11976
  "DELETE",
11943
- "SAVE",
11944
- "CANCEL",
11945
- "SET_PERSON_ID",
11946
- "SET_EVENT_KEY",
11947
- "SET_CHANNEL",
11948
- "SET_MODE",
11949
- "SET_QUIET_HOURS",
11950
11977
  "PreferencesLoaded",
11951
11978
  "PreferencesLoadFailed",
11952
11979
  "PreferenceSaved",
11953
11980
  "PreferenceSaveFailed",
11954
11981
  "PreferenceDeleted"
11955
11982
  ],
11956
- "listenedEvents": [],
11983
+ "listenedEvents": [
11984
+ "PREFERENCE_CREATED",
11985
+ "PREFERENCE_UPDATED"
11986
+ ],
11957
11987
  "overridableConfigKeys": [
11958
11988
  {
11959
11989
  "key": "tableLook",
@@ -11998,122 +12028,44 @@
11998
12028
  "resource": "main"
11999
12029
  },
12000
12030
  {
12001
- "kind": "set",
12002
- "resource": "@entity.channel"
12003
- },
12004
- {
12005
- "kind": "set",
12006
- "resource": "@entity.createdAt"
12007
- },
12008
- {
12009
- "kind": "set",
12010
- "resource": "@entity.eventKey"
12011
- },
12012
- {
12013
- "kind": "set",
12014
- "resource": "@entity.id"
12015
- },
12016
- {
12017
- "kind": "set",
12018
- "resource": "@entity.mode"
12019
- },
12020
- {
12021
- "kind": "set",
12022
- "resource": "@entity.personId"
12023
- },
12024
- {
12025
- "kind": "set",
12026
- "resource": "@entity.quietHours"
12027
- },
12028
- {
12029
- "kind": "set",
12030
- "resource": "@entity.updatedAt"
12031
+ "kind": "render-ui",
12032
+ "resource": "toast"
12031
12033
  }
12032
12034
  ],
12033
12035
  "transitionEvents": [
12034
- "CANCEL",
12035
12036
  "DELETE",
12036
- "EDIT",
12037
+ "DO_CREATE",
12038
+ "DO_UPDATE",
12037
12039
  "INIT",
12038
- "NEW",
12039
12040
  "PreferenceDeleted",
12040
12041
  "PreferenceSaveFailed",
12041
12042
  "PreferenceSaved",
12042
12043
  "PreferencesLoadFailed",
12043
12044
  "PreferencesLoaded",
12044
- "SAVE",
12045
- "SET_CHANNEL",
12046
- "SET_EVENT_KEY",
12047
- "SET_MODE",
12048
- "SET_PERSON_ID",
12049
- "SET_QUIET_HOURS"
12045
+ "RETRY"
12050
12046
  ],
12051
12047
  "events": [
12052
12048
  {
12053
- "name": "NEW",
12049
+ "name": "CREATE",
12054
12050
  "direction": "emit",
12055
- "description": "Opens the blank preference form.",
12056
- "synonyms": "add, create, new preference",
12057
- "tier": "presentation"
12051
+ "description": "Opens the blank preference modal.",
12052
+ "synonyms": "add, new, insert",
12053
+ "tier": "domain"
12058
12054
  },
12059
12055
  {
12060
12056
  "name": "EDIT",
12061
12057
  "direction": "emit",
12062
- "description": "Opens a preference row in the edit form.",
12058
+ "description": "Opens a preference row in the edit modal.",
12063
12059
  "synonyms": "modify, update, change",
12064
- "tier": "presentation"
12060
+ "tier": "domain"
12065
12061
  },
12066
12062
  {
12067
12063
  "name": "DELETE",
12068
12064
  "direction": "emit",
12069
12065
  "description": "Removes a preference row.",
12070
12066
  "synonyms": "remove, discard, clear",
12071
- "tier": "presentation"
12072
- },
12073
- {
12074
- "name": "SAVE",
12075
- "direction": "emit",
12076
- "description": "Persists the preference form.",
12077
- "synonyms": "persist, store, commit",
12078
- "tier": "domain"
12079
- },
12080
- {
12081
- "name": "CANCEL",
12082
- "direction": "emit",
12083
- "description": "Aborts the preference form.",
12084
- "synonyms": "abort, dismiss, undo",
12085
12067
  "tier": "domain"
12086
12068
  },
12087
- {
12088
- "name": "SET_PERSON_ID",
12089
- "direction": "emit",
12090
- "description": "Preference form: person id changed.",
12091
- "tier": "internal"
12092
- },
12093
- {
12094
- "name": "SET_EVENT_KEY",
12095
- "direction": "emit",
12096
- "description": "Preference form: event key changed.",
12097
- "tier": "internal"
12098
- },
12099
- {
12100
- "name": "SET_CHANNEL",
12101
- "direction": "emit",
12102
- "description": "Preference form: channel changed.",
12103
- "tier": "internal"
12104
- },
12105
- {
12106
- "name": "SET_MODE",
12107
- "direction": "emit",
12108
- "description": "Preference form: delivery mode changed.",
12109
- "tier": "internal"
12110
- },
12111
- {
12112
- "name": "SET_QUIET_HOURS",
12113
- "direction": "emit",
12114
- "description": "Preference form: quiet-hours window changed.",
12115
- "tier": "internal"
12116
- },
12117
12069
  {
12118
12070
  "name": "PreferencesLoaded",
12119
12071
  "direction": "emit",
@@ -12152,10 +12104,135 @@
12152
12104
  {
12153
12105
  "name": "INIT",
12154
12106
  "direction": "listen"
12107
+ },
12108
+ {
12109
+ "name": "DO_CREATE",
12110
+ "direction": "listen",
12111
+ "description": "Create persist requested; the modal's SAVE payload carries the full form row.",
12112
+ "synonyms": "add, new, insert",
12113
+ "tier": "internal"
12114
+ },
12115
+ {
12116
+ "name": "DO_UPDATE",
12117
+ "direction": "listen",
12118
+ "description": "Update persist requested; the modal's SAVE payload carries the full form row.",
12119
+ "synonyms": "modified, changed, refreshed",
12120
+ "tier": "internal"
12121
+ },
12122
+ {
12123
+ "name": "RETRY",
12124
+ "direction": "listen",
12125
+ "description": "Retries loading the preference collection after a failure.",
12126
+ "synonyms": "try again, reload",
12127
+ "tier": "presentation"
12155
12128
  }
12156
12129
  ],
12157
12130
  "definerKnobs": []
12158
12131
  },
12132
+ {
12133
+ "name": "PreferenceCreate",
12134
+ "orbital": "NotificationPreferencesOrbital",
12135
+ "role": "renderer",
12136
+ "emittedEvents": [],
12137
+ "listenedEvents": [
12138
+ "CREATE"
12139
+ ],
12140
+ "overridableConfigKeys": [
12141
+ {
12142
+ "key": "fields",
12143
+ "type": "unknown",
12144
+ "default": [
12145
+ "personId",
12146
+ "eventKey",
12147
+ "channel",
12148
+ "mode",
12149
+ "quietHours"
12150
+ ]
12151
+ },
12152
+ {
12153
+ "key": "icon",
12154
+ "type": "unknown",
12155
+ "default": "plus-circle"
12156
+ },
12157
+ {
12158
+ "key": "mode",
12159
+ "type": "unknown",
12160
+ "default": "create"
12161
+ },
12162
+ {
12163
+ "key": "title",
12164
+ "type": "unknown",
12165
+ "default": "New notification preference"
12166
+ }
12167
+ ],
12168
+ "capabilities": [],
12169
+ "ticks": [],
12170
+ "rendersUi": true,
12171
+ "ref": "Modal.traits.ModalRecordModal",
12172
+ "category": "interaction",
12173
+ "linkedEntity": "NotificationPreference",
12174
+ "transitionEvents": [
12175
+ "CLOSE",
12176
+ "CREATE",
12177
+ "INIT",
12178
+ "ModalRecordLoadFailed",
12179
+ "PREFERENCE_CREATED",
12180
+ "SEED"
12181
+ ],
12182
+ "definerKnobs": []
12183
+ },
12184
+ {
12185
+ "name": "PreferenceEdit",
12186
+ "orbital": "NotificationPreferencesOrbital",
12187
+ "role": "renderer",
12188
+ "emittedEvents": [],
12189
+ "listenedEvents": [
12190
+ "EDIT"
12191
+ ],
12192
+ "overridableConfigKeys": [
12193
+ {
12194
+ "key": "fields",
12195
+ "type": "unknown",
12196
+ "default": [
12197
+ "personId",
12198
+ "eventKey",
12199
+ "channel",
12200
+ "mode",
12201
+ "quietHours"
12202
+ ]
12203
+ },
12204
+ {
12205
+ "key": "icon",
12206
+ "type": "unknown",
12207
+ "default": "pencil"
12208
+ },
12209
+ {
12210
+ "key": "mode",
12211
+ "type": "unknown",
12212
+ "default": "edit"
12213
+ },
12214
+ {
12215
+ "key": "title",
12216
+ "type": "unknown",
12217
+ "default": "Edit notification preference"
12218
+ }
12219
+ ],
12220
+ "capabilities": [],
12221
+ "ticks": [],
12222
+ "rendersUi": true,
12223
+ "ref": "Modal.traits.ModalRecordModal",
12224
+ "category": "interaction",
12225
+ "linkedEntity": "NotificationPreference",
12226
+ "transitionEvents": [
12227
+ "CLOSE",
12228
+ "EDIT",
12229
+ "INIT",
12230
+ "ModalRecordLoadFailed",
12231
+ "PREFERENCE_UPDATED",
12232
+ "SEED"
12233
+ ],
12234
+ "definerKnobs": []
12235
+ },
12159
12236
  {
12160
12237
  "name": "PreferenceGate",
12161
12238
  "orbital": "NotificationPreferencesOrbital",
@@ -12888,13 +12965,13 @@
12888
12965
  "topic": "infra",
12889
12966
  "family": "infra",
12890
12967
  "layer": "UI Patterns",
12891
- "description": "std-permission-matrix — role × module permission grant table / capability matrix admin surface. Use when a user voices that permissions must be managed per role and module (permission matrix, role permissions, capability matrix, permission grants, access matrix, who can see finance, hide margins, module-level permissions, admin permission screen, grant management, finance visibility by role, restrict modules by role). Persists PermissionGrant rows (workspaceId + role + module + capability flags canReadFinance / canSeeOthersHours / canSeeMargins) with full CRUD on an admin page mounted at /admin/permissions, and ships a query trait other traits consult event-wise: CHECK_GRANT { role, module } fetches the matching grant(s) and re-emits GRANT_RESOLVED { role, module, canReadFinance, canSeeOthersHours, canSeeMargins, found }. Grant SURFACE only — entity-layer @read/@update gate integration is a recorded core gap (gates are pure @entity/@user S-expressions and cannot consult another entity's rows), so enforcement stays with the consumer until that core lands.",
12968
+ "description": "std-permission-matrix — role × module permission grant table / capability matrix admin surface. Use when a user voices that permissions must be managed per role and module (permission matrix, role permissions, capability matrix, permission grants, access matrix, who can see finance, hide margins, module-level permissions, admin permission screen, grant management, finance visibility by role, restrict modules by role). Persists PermissionGrant rows (workspaceId + role + module + capability flags canReadFinance / canSeeOthersHours / canSeeMargins) with full CRUD on an admin page mounted at /admin/permissions — create/edit forms are the std-modal ModalRecordModal substrate (the corpus's two-trait CRUD shape, mirroring std-list), persists live in a sibling coordinator trait, and adminRoles is ENFORCED at the persist boundary (a viewer whose role is not listed cannot fire a write, from the button or from the bus). Ships a query trait other traits consult event-wise: CHECK_GRANT { role, module } fetches the matching grant(s) and re-emits GRANT_RESOLVED { role, module, canReadFinance, canSeeOthersHours, canSeeMargins, found }. Grant SURFACE only — entity-layer @read/@update gate integration is a recorded core gap (gates are pure @entity/@user S-expressions and cannot consult another entity's rows), so enforcement stays with the consumer until that core lands.",
12892
12969
  "defaultOrbitalName": "PermissionMatrixOrbital",
12893
- "statePattern": "editing, error, listing, loading",
12970
+ "statePattern": "error, listing, loading",
12894
12971
  "complexity": {
12895
- "states": 4,
12896
- "events": 14,
12897
- "transitions": 16
12972
+ "states": 3,
12973
+ "events": 6,
12974
+ "transitions": 5
12898
12975
  },
12899
12976
  "defaultEntity": {
12900
12977
  "name": "PermissionGrant",
@@ -12949,7 +13026,6 @@
12949
13026
  },
12950
13027
  "defaultIcons": [],
12951
13028
  "composableWith": [
12952
- "kflow-learning-companion",
12953
13029
  "std-anim-tick",
12954
13030
  "std-application",
12955
13031
  "std-approval-gate",
@@ -12962,38 +13038,26 @@
12962
13038
  "std-calendar-sync",
12963
13039
  "std-cascade-on-delete",
12964
13040
  "std-circuit-breaker",
12965
- "std-confirmation",
12966
13041
  "std-cooldown",
12967
13042
  "std-cross-reference",
12968
13043
  "std-data-erasure",
12969
13044
  "std-data-import",
12970
- "std-gallery",
12971
13045
  "std-game-clock",
12972
13046
  "std-global-search",
12973
- "std-helpdesk-ticket",
12974
13047
  "std-image-upload-multi",
12975
13048
  "std-integration-settings",
12976
- "std-inventory",
12977
- "std-iram",
12978
13049
  "std-lifecycle",
12979
13050
  "std-list",
12980
13051
  "std-menu",
12981
13052
  "std-migration-job",
12982
13053
  "std-mod-queue",
12983
- "std-modal",
12984
- "std-moderation-rule",
12985
13054
  "std-modifier-group",
12986
13055
  "std-notification-center",
12987
- "std-notification-panel",
12988
13056
  "std-notification-preferences",
12989
13057
  "std-notify-on-event",
12990
- "std-purchase-order",
12991
- "std-question-bank",
12992
13058
  "std-rate-limiter",
12993
13059
  "std-record-detail",
12994
13060
  "std-reminder-scheduler",
12995
- "std-reorder-rule",
12996
- "std-rfi",
12997
13061
  "std-row-access-control",
12998
13062
  "std-saved-search",
12999
13063
  "std-service-accounting",
@@ -13030,33 +13094,14 @@
13030
13094
  "std-service-wikimedia",
13031
13095
  "std-service-youtube",
13032
13096
  "std-status-lifecycle",
13033
- "std-status-lifecycle-control",
13034
- "std-stock-level",
13035
- "std-tag-taxonomy",
13036
- "std-ticket-tier",
13037
- "std-trait-wars",
13038
- "std-warehouse",
13039
- "ui-confirm-dialog",
13040
- "ui-drawer",
13041
- "ui-lightbox",
13042
- "ui-modal",
13043
- "ui-side-panel",
13044
- "ui-subagent-trace-panel"
13097
+ "std-status-lifecycle-control"
13045
13098
  ],
13046
13099
  "connectableEvents": [
13047
13100
  "PermissionGrantLoaded",
13048
13101
  "PermissionGrantLoadFailed",
13049
13102
  "NEW",
13050
13103
  "EDIT",
13051
- "DELETE",
13052
- "PermissionGrantDeleted",
13053
- "PermissionGrantDeleteFailed",
13054
- "CREATE_GRANT",
13055
- "SAVE_GRANT",
13056
- "CANCEL_GRANT",
13057
- "PermissionGrantSaved",
13058
- "PermissionGrantSaveFailed",
13059
- "CLOSE"
13104
+ "DELETE"
13060
13105
  ],
13061
13106
  "eventPayloads": {},
13062
13107
  "exposure": "both",
@@ -13191,88 +13236,6 @@
13191
13236
  ],
13192
13237
  "definerKnobs": []
13193
13238
  },
13194
- {
13195
- "name": "NewGrantButton",
13196
- "orbital": "PermissionMatrixOrbital",
13197
- "role": "renderer",
13198
- "emittedEvents": [],
13199
- "listenedEvents": [],
13200
- "overridableConfigKeys": [
13201
- {
13202
- "key": "action",
13203
- "type": "unknown",
13204
- "default": "NEW"
13205
- },
13206
- {
13207
- "key": "icon",
13208
- "type": "unknown",
13209
- "default": "plus"
13210
- },
13211
- {
13212
- "key": "label",
13213
- "type": "unknown",
13214
- "default": "New grant"
13215
- },
13216
- {
13217
- "key": "variant",
13218
- "type": "unknown",
13219
- "default": "primary"
13220
- }
13221
- ],
13222
- "capabilities": [],
13223
- "ticks": [],
13224
- "rendersUi": true,
13225
- "ref": "Button.traits.ButtonRender",
13226
- "category": "interaction",
13227
- "linkedEntity": "PermissionGrant",
13228
- "transitionEvents": [
13229
- "INIT"
13230
- ],
13231
- "definerKnobs": [
13232
- "action"
13233
- ]
13234
- },
13235
- {
13236
- "name": "BackButton",
13237
- "orbital": "PermissionMatrixOrbital",
13238
- "role": "renderer",
13239
- "emittedEvents": [],
13240
- "listenedEvents": [],
13241
- "overridableConfigKeys": [
13242
- {
13243
- "key": "action",
13244
- "type": "unknown",
13245
- "default": "CANCEL_GRANT"
13246
- },
13247
- {
13248
- "key": "icon",
13249
- "type": "unknown",
13250
- "default": "x"
13251
- },
13252
- {
13253
- "key": "label",
13254
- "type": "unknown",
13255
- "default": "Cancel"
13256
- },
13257
- {
13258
- "key": "variant",
13259
- "type": "unknown",
13260
- "default": "ghost"
13261
- }
13262
- ],
13263
- "capabilities": [],
13264
- "ticks": [],
13265
- "rendersUi": true,
13266
- "ref": "Button.traits.ButtonRender",
13267
- "category": "interaction",
13268
- "linkedEntity": "PermissionGrant",
13269
- "transitionEvents": [
13270
- "INIT"
13271
- ],
13272
- "definerKnobs": [
13273
- "action"
13274
- ]
13275
- },
13276
13239
  {
13277
13240
  "name": "GrantDivider",
13278
13241
  "orbital": "PermissionMatrixOrbital",
@@ -13331,44 +13294,14 @@
13331
13294
  "NEW",
13332
13295
  "EDIT",
13333
13296
  "DELETE",
13334
- "CREATE_GRANT",
13335
- "SAVE_GRANT",
13336
- "CANCEL_GRANT",
13337
- "CLOSE",
13338
13297
  "PermissionGrantLoaded",
13339
- "PermissionGrantLoadFailed",
13340
- "PermissionGrantSaved",
13341
- "PermissionGrantSaveFailed",
13342
- "PermissionGrantDeleted",
13343
- "PermissionGrantDeleteFailed"
13298
+ "PermissionGrantLoadFailed"
13344
13299
  ],
13345
13300
  "listenedEvents": [
13346
- "NEW",
13347
- "CANCEL_GRANT"
13348
- ],
13349
- "overridableConfigKeys": [
13350
- {
13351
- "key": "adminRoles",
13352
- "type": "[string]",
13353
- "default": [],
13354
- "label": "Who can manage grants?",
13355
- "description": "Roles eligible to create, edit, or delete grants. ENFORCED by the NEW/EDIT/DELETE/CREATE_GRANT/SAVE_GRANT transition guards: a viewer whose @user.role is not listed cannot fire a mutation, from the button or from the bus. Empty = every signed-in viewer may manage grants (ungated).",
13356
- "synonyms": "admin roles, permission managers, who edits permissions, grant admins",
13357
- "tier": "policy",
13358
- "items": {
13359
- "type": "string"
13360
- }
13361
- },
13362
- {
13363
- "key": "enabled",
13364
- "type": "boolean",
13365
- "default": false,
13366
- "label": "Manage role permissions",
13367
- "description": "Allow creating, editing, and deleting permission grants from this surface. Off by default.",
13368
- "synonyms": "enable, turn on, enforce, require, activate, apply, switch on, permission matrix, role permissions, capability matrix, permission grants, access matrix, manage permissions, who can see finance, hide margins, module-level permissions",
13369
- "tier": "policy"
13370
- }
13301
+ "PermissionGrantSaved",
13302
+ "PermissionGrantDeleted"
13371
13303
  ],
13304
+ "overridableConfigKeys": [],
13372
13305
  "capabilities": [
13373
13306
  "access"
13374
13307
  ],
@@ -13379,151 +13312,233 @@
13379
13312
  "linkedEntity": "PermissionGrant",
13380
13313
  "entityContract": {
13381
13314
  "requires": [],
13382
- "provides": [
13383
- "canReadFinance",
13384
- "canSeeMargins",
13385
- "canSeeOthersHours",
13386
- "module",
13387
- "role",
13388
- "workspaceId"
13389
- ]
13315
+ "provides": []
13390
13316
  },
13391
13317
  "effectRow": [
13392
13318
  {
13393
13319
  "kind": "fetch",
13394
13320
  "resource": "PermissionGrant"
13395
13321
  },
13396
- {
13397
- "kind": "persist",
13398
- "resource": "PermissionGrant"
13399
- },
13400
13322
  {
13401
13323
  "kind": "render-ui",
13402
13324
  "resource": "main"
13403
- },
13404
- {
13405
- "kind": "render-ui",
13406
- "resource": "modal"
13407
- },
13408
- {
13409
- "kind": "render-ui",
13410
- "resource": "toast"
13411
- },
13412
- {
13413
- "kind": "set",
13414
- "resource": "@entity.canReadFinance"
13415
- },
13416
- {
13417
- "kind": "set",
13418
- "resource": "@entity.canSeeMargins"
13419
- },
13420
- {
13421
- "kind": "set",
13422
- "resource": "@entity.canSeeOthersHours"
13423
- },
13424
- {
13425
- "kind": "set",
13426
- "resource": "@entity.id"
13427
- },
13428
- {
13429
- "kind": "set",
13430
- "resource": "@entity.module"
13431
- },
13432
- {
13433
- "kind": "set",
13434
- "resource": "@entity.role"
13435
- },
13436
- {
13437
- "kind": "set",
13438
- "resource": "@entity.workspaceId"
13439
13325
  }
13440
13326
  ],
13441
13327
  "transitionEvents": [
13442
- "CANCEL_GRANT",
13443
- "CLOSE",
13444
- "CREATE_GRANT",
13445
- "DELETE",
13446
- "EDIT",
13447
13328
  "INIT",
13448
- "NEW",
13449
- "PermissionGrantDeleteFailed",
13450
- "PermissionGrantDeleted",
13451
13329
  "PermissionGrantLoadFailed",
13452
- "PermissionGrantLoaded",
13453
- "PermissionGrantSaveFailed",
13454
- "PermissionGrantSaved",
13455
- "SAVE_GRANT"
13330
+ "PermissionGrantLoaded"
13456
13331
  ],
13457
13332
  "events": [
13458
13333
  {
13459
13334
  "name": "NEW",
13460
13335
  "direction": "emit",
13461
- "description": "Opens the create-grant form.",
13336
+ "description": "Requests the create-grant form (the create modal listens).",
13462
13337
  "synonyms": "add grant, new permission, create grant",
13463
13338
  "tier": "domain"
13464
13339
  },
13465
13340
  {
13466
13341
  "name": "EDIT",
13467
13342
  "direction": "emit",
13468
- "description": "Opens the edit form for a grant row.",
13343
+ "description": "Requests the edit form for a grant row (the edit modal listens).",
13469
13344
  "synonyms": "modify grant, change permission, update grant",
13470
13345
  "tier": "domain"
13471
13346
  },
13472
13347
  {
13473
13348
  "name": "DELETE",
13474
13349
  "direction": "emit",
13475
- "description": "Deletes a grant row (persisted; the grid refetches on success).",
13350
+ "description": "Requests deletion of a grant row (the persistor listens; adminRoles-guarded there).",
13476
13351
  "synonyms": "remove grant, revoke permission, delete grant",
13477
13352
  "tier": "domain"
13478
13353
  },
13479
13354
  {
13480
- "name": "CREATE_GRANT",
13355
+ "name": "PermissionGrantLoaded",
13481
13356
  "direction": "emit",
13482
- "description": "The create-grant form committed; data carries the new grant's fields.",
13483
- "synonyms": "submit grant, confirm create",
13357
+ "description": "Indicates the permission-grant collection has been successfully loaded.",
13358
+ "synonyms": "loaded, fetched, retrieved",
13484
13359
  "tier": "internal"
13485
13360
  },
13486
13361
  {
13487
- "name": "SAVE_GRANT",
13362
+ "name": "PermissionGrantLoadFailed",
13488
13363
  "direction": "emit",
13489
- "description": "The edit-grant form committed; data carries the grant id + updated fields.",
13490
- "synonyms": "submit edit, confirm update",
13364
+ "description": "Indicates failure to load the permission-grant collection.",
13365
+ "synonyms": "load error, failed load, request failure",
13491
13366
  "tier": "internal"
13492
13367
  },
13493
13368
  {
13494
- "name": "CANCEL_GRANT",
13495
- "direction": "emit",
13496
- "description": "The grant form was dismissed without committing; the grid repaints.",
13497
- "synonyms": "cancel, back to matrix, dismiss form",
13498
- "tier": "internal"
13369
+ "name": "INIT",
13370
+ "direction": "listen"
13371
+ }
13372
+ ],
13373
+ "definerKnobs": []
13374
+ },
13375
+ {
13376
+ "name": "PermissionGrantCreate",
13377
+ "orbital": "PermissionMatrixOrbital",
13378
+ "role": "renderer",
13379
+ "emittedEvents": [],
13380
+ "listenedEvents": [
13381
+ "NEW"
13382
+ ],
13383
+ "overridableConfigKeys": [
13384
+ {
13385
+ "key": "fields",
13386
+ "type": "unknown",
13387
+ "default": [
13388
+ "workspaceId",
13389
+ "role",
13390
+ "module",
13391
+ "canReadFinance",
13392
+ "canSeeOthersHours",
13393
+ "canSeeMargins"
13394
+ ]
13499
13395
  },
13500
13396
  {
13501
- "name": "CLOSE",
13502
- "direction": "emit",
13503
- "description": "Dismisses the grant form overlay (the modal shell's own X / Escape / overlay-click).",
13504
- "synonyms": "dismiss, hide, close form, done",
13505
- "tier": "domain"
13397
+ "key": "icon",
13398
+ "type": "unknown",
13399
+ "default": "plus-circle"
13506
13400
  },
13507
13401
  {
13508
- "name": "PermissionGrantLoaded",
13509
- "direction": "emit",
13510
- "description": "Indicates the permission-grant collection has been successfully loaded.",
13511
- "synonyms": "loaded, fetched, retrieved",
13512
- "tier": "internal"
13402
+ "key": "mode",
13403
+ "type": "unknown",
13404
+ "default": "create"
13513
13405
  },
13514
13406
  {
13515
- "name": "PermissionGrantLoadFailed",
13516
- "direction": "emit",
13517
- "description": "Indicates failure to load the permission-grant collection.",
13518
- "synonyms": "load error, failed load, request failure",
13519
- "tier": "internal"
13407
+ "key": "title",
13408
+ "type": "unknown",
13409
+ "default": "Create grant"
13410
+ }
13411
+ ],
13412
+ "capabilities": [],
13413
+ "ticks": [],
13414
+ "rendersUi": true,
13415
+ "ref": "Modal.traits.ModalRecordModal",
13416
+ "category": "interaction",
13417
+ "linkedEntity": "PermissionGrant",
13418
+ "transitionEvents": [
13419
+ "CLOSE",
13420
+ "GRANT_CREATED",
13421
+ "INIT",
13422
+ "ModalRecordLoadFailed",
13423
+ "NEW",
13424
+ "SEED"
13425
+ ],
13426
+ "definerKnobs": []
13427
+ },
13428
+ {
13429
+ "name": "PermissionGrantEdit",
13430
+ "orbital": "PermissionMatrixOrbital",
13431
+ "role": "renderer",
13432
+ "emittedEvents": [],
13433
+ "listenedEvents": [
13434
+ "EDIT"
13435
+ ],
13436
+ "overridableConfigKeys": [
13437
+ {
13438
+ "key": "fields",
13439
+ "type": "unknown",
13440
+ "default": [
13441
+ "workspaceId",
13442
+ "role",
13443
+ "module",
13444
+ "canReadFinance",
13445
+ "canSeeOthersHours",
13446
+ "canSeeMargins"
13447
+ ]
13448
+ },
13449
+ {
13450
+ "key": "icon",
13451
+ "type": "unknown",
13452
+ "default": "pencil"
13453
+ },
13454
+ {
13455
+ "key": "mode",
13456
+ "type": "unknown",
13457
+ "default": "edit"
13520
13458
  },
13459
+ {
13460
+ "key": "title",
13461
+ "type": "unknown",
13462
+ "default": "Edit grant"
13463
+ }
13464
+ ],
13465
+ "capabilities": [],
13466
+ "ticks": [],
13467
+ "rendersUi": true,
13468
+ "ref": "Modal.traits.ModalRecordModal",
13469
+ "category": "interaction",
13470
+ "linkedEntity": "PermissionGrant",
13471
+ "transitionEvents": [
13472
+ "CLOSE",
13473
+ "EDIT",
13474
+ "GRANT_UPDATED",
13475
+ "INIT",
13476
+ "ModalRecordLoadFailed",
13477
+ "SEED"
13478
+ ],
13479
+ "definerKnobs": []
13480
+ },
13481
+ {
13482
+ "name": "PermissionGrantPersistor",
13483
+ "orbital": "PermissionMatrixOrbital",
13484
+ "role": "renderer",
13485
+ "emittedEvents": [
13486
+ "PermissionGrantSaved",
13487
+ "PermissionGrantSaveFailed",
13488
+ "PermissionGrantDeleted",
13489
+ "PermissionGrantDeleteFailed"
13490
+ ],
13491
+ "listenedEvents": [
13492
+ "GRANT_CREATED",
13493
+ "GRANT_UPDATED",
13494
+ "DELETE"
13495
+ ],
13496
+ "overridableConfigKeys": [
13497
+ {
13498
+ "key": "adminRoles",
13499
+ "type": "[string]",
13500
+ "default": [],
13501
+ "label": "Who can manage grants?",
13502
+ "description": "Roles eligible to create, edit, or delete grants. ENFORCED by the DO_CREATE/DO_UPDATE/DO_DELETE transition guards: a viewer whose @user.role is not listed cannot fire a write, from the form submit or from the bus. Empty = every signed-in viewer may manage grants (ungated). Mounting the page is the opt-in — there is deliberately no separate enable flag (a default-off flag made the whole page's affordances dead on a fresh mount).",
13503
+ "synonyms": "admin roles, permission managers, who edits permissions, grant admins, permission matrix, role permissions, capability matrix, permission grants, access matrix, manage permissions",
13504
+ "tier": "policy",
13505
+ "items": {
13506
+ "type": "string"
13507
+ }
13508
+ }
13509
+ ],
13510
+ "capabilities": [
13511
+ "access"
13512
+ ],
13513
+ "ticks": [],
13514
+ "rendersUi": true,
13515
+ "category": "lifecycle",
13516
+ "linkedEntity": "PermissionGrant",
13517
+ "effectRow": [
13518
+ {
13519
+ "kind": "persist",
13520
+ "resource": "PermissionGrant"
13521
+ },
13522
+ {
13523
+ "kind": "render-ui",
13524
+ "resource": "toast"
13525
+ }
13526
+ ],
13527
+ "transitionEvents": [
13528
+ "DO_CREATE",
13529
+ "DO_DELETE",
13530
+ "DO_UPDATE",
13531
+ "INIT",
13532
+ "PermissionGrantDeleteFailed",
13533
+ "PermissionGrantSaveFailed"
13534
+ ],
13535
+ "events": [
13521
13536
  {
13522
13537
  "name": "PermissionGrantSaved",
13523
13538
  "direction": "emit",
13524
- "description": "Signals that a permission grant has been persisted (create / update).",
13539
+ "description": "Signals that a permission grant has been persisted (create / update); carries the persisted row's id.",
13525
13540
  "synonyms": "saved, created, updated, persisted",
13526
- "tier": "internal"
13541
+ "tier": "domain"
13527
13542
  },
13528
13543
  {
13529
13544
  "name": "PermissionGrantSaveFailed",
@@ -13537,7 +13552,7 @@
13537
13552
  "direction": "emit",
13538
13553
  "description": "Signals that a permission grant has been deleted.",
13539
13554
  "synonyms": "deleted, removed, revoked",
13540
- "tier": "internal"
13555
+ "tier": "domain"
13541
13556
  },
13542
13557
  {
13543
13558
  "name": "PermissionGrantDeleteFailed",
@@ -13549,6 +13564,27 @@
13549
13564
  {
13550
13565
  "name": "INIT",
13551
13566
  "direction": "listen"
13567
+ },
13568
+ {
13569
+ "name": "DO_CREATE",
13570
+ "direction": "listen",
13571
+ "description": "Indicates a request to create a grant row.",
13572
+ "synonyms": "add, new, insert",
13573
+ "tier": "domain"
13574
+ },
13575
+ {
13576
+ "name": "DO_UPDATE",
13577
+ "direction": "listen",
13578
+ "description": "Indicates a grant row has been modified.",
13579
+ "synonyms": "modify, update, change",
13580
+ "tier": "domain"
13581
+ },
13582
+ {
13583
+ "name": "DO_DELETE",
13584
+ "direction": "listen",
13585
+ "description": "Indicates a request to delete a grant row.",
13586
+ "synonyms": "remove, discard, erase",
13587
+ "tier": "domain"
13552
13588
  }
13553
13589
  ],
13554
13590
  "definerKnobs": []
@@ -14460,13 +14496,13 @@
14460
14496
  "topic": "infra",
14461
14497
  "family": "infra",
14462
14498
  "layer": "UI Patterns",
14463
- "description": "std-reminder-scheduler — deadline reminders for a target entity. A periodic tick scans the target for records whose `dateField` deadline (a ms-epoch number or an ISO datetime string) is within `offsetHours` of now and that have not been reminded yet, and emits `ReminderDue` for each — every matching record, via a self-driving scan loop. Marks each record `remindedAt` so it isn't reminded twice. Compose alongside std-notify-on-event to deliver the reminder.",
14499
+ "description": "std-reminder-scheduler — deadline reminders for a target entity. A periodic tick scans the target for records whose `dateField` deadline (a ms-epoch number or an ISO datetime string) is within `offsetHours` of now and that have not been reminded yet, and emits `ReminderDue` for each — every matching record, via a self-driving scan loop. `direction` picks which side of now the scan matches: 'future' (default) fires for deadlines up to `offsetHours` ahead; 'past' fires once a record's date is at least `offsetHours` behind now. Marks each record `remindedAt` so it isn't reminded twice — and only when the record actually matched the scan, so records outside the window stay eligible for later passes. Compose alongside std-notify-on-event to deliver the reminder.",
14464
14500
  "defaultOrbitalName": "ReminderSchedulerOrbital",
14465
14501
  "statePattern": "idle, scanning",
14466
14502
  "complexity": {
14467
14503
  "states": 2,
14468
14504
  "events": 5,
14469
- "transitions": 8
14505
+ "transitions": 9
14470
14506
  },
14471
14507
  "defaultEntity": {
14472
14508
  "name": "ReminderRunLog",
@@ -14611,6 +14647,19 @@
14611
14647
  "synonyms": "due date field, timestamp field, cutoff field, expiry field, when it's due",
14612
14648
  "tier": "internal"
14613
14649
  },
14650
+ {
14651
+ "key": "direction",
14652
+ "type": "string",
14653
+ "default": "future",
14654
+ "label": "Scan which side of now?",
14655
+ "description": "'future' (default) matches records whose dateField is still ahead, up to offsetHours out — upcoming-deadline reminders. 'past' matches records whose dateField is at least offsetHours behind now — act-after-the-fact policies. The emitted event and the dedup marker are identical either way.",
14656
+ "synonyms": "direction, past due, overdue, after the deadline, look back, backward scan, past-window",
14657
+ "tier": "infra",
14658
+ "enumValues": [
14659
+ "future",
14660
+ "past"
14661
+ ]
14662
+ },
14614
14663
  {
14615
14664
  "key": "enabled",
14616
14665
  "type": "boolean",
@@ -25538,6 +25587,7 @@
25538
25587
  "std-modal-editor",
25539
25588
  "std-multi-party-flow",
25540
25589
  "std-notification-panel",
25590
+ "std-notification-preferences",
25541
25591
  "std-pagination",
25542
25592
  "std-rating-review",
25543
25593
  "std-record-detail",
@@ -26821,10 +26871,8 @@
26821
26871
  "std-moderation-rule",
26822
26872
  "std-multi-party-flow",
26823
26873
  "std-notification-panel",
26824
- "std-notification-preferences",
26825
26874
  "std-objective-board-3d",
26826
26875
  "std-pagination",
26827
- "std-permission-matrix",
26828
26876
  "std-purchase-order",
26829
26877
  "std-question-bank",
26830
26878
  "std-rate-limiter",
@@ -28817,6 +28865,7 @@
28817
28865
  "std-nonprofit-donations",
28818
28866
  "std-note",
28819
28867
  "std-notification-panel",
28868
+ "std-notification-preferences",
28820
28869
  "std-pagination",
28821
28870
  "std-property-mgmt",
28822
28871
  "std-public-help-center",
@@ -32980,7 +33029,6 @@
32980
33029
  "std-modal-editor",
32981
33030
  "std-multi-party-flow",
32982
33031
  "std-notification-panel",
32983
- "std-notification-preferences",
32984
33032
  "std-objective-board-3d",
32985
33033
  "std-pagination",
32986
33034
  "std-physics-diagram",
@@ -33633,7 +33681,6 @@
33633
33681
  "std-multi-party-flow",
33634
33682
  "std-notification-panel",
33635
33683
  "std-pagination",
33636
- "std-permission-matrix",
33637
33684
  "std-purchase-order",
33638
33685
  "std-question-bank",
33639
33686
  "std-rating-review",
@@ -37503,7 +37550,6 @@
37503
37550
  "std-modal",
37504
37551
  "std-multi-party-flow",
37505
37552
  "std-notification-panel",
37506
- "std-notification-preferences",
37507
37553
  "std-pagination",
37508
37554
  "std-rating-review",
37509
37555
  "std-record-detail",
@@ -38429,9 +38475,7 @@
38429
38475
  "std-moderation-rule",
38430
38476
  "std-multi-party-flow",
38431
38477
  "std-notification-panel",
38432
- "std-notification-preferences",
38433
38478
  "std-pagination",
38434
- "std-permission-matrix",
38435
38479
  "std-purchase-order",
38436
38480
  "std-question-bank",
38437
38481
  "std-rating-review",
@@ -39914,7 +39958,6 @@
39914
39958
  "std-moderation-rule",
39915
39959
  "std-multi-party-flow",
39916
39960
  "std-pagination",
39917
- "std-permission-matrix",
39918
39961
  "std-purchase-order",
39919
39962
  "std-question-bank",
39920
39963
  "std-rating-review",
@@ -43838,6 +43881,7 @@
43838
43881
  "std-multi-party-flow",
43839
43882
  "std-notes",
43840
43883
  "std-notification-panel",
43884
+ "std-notification-preferences",
43841
43885
  "std-pagination",
43842
43886
  "std-rating-review",
43843
43887
  "std-record-detail",
@@ -45724,6 +45768,7 @@
45724
45768
  "std-modal-editor",
45725
45769
  "std-multi-party-flow",
45726
45770
  "std-notification-panel",
45771
+ "std-notification-preferences",
45727
45772
  "std-pagination",
45728
45773
  "std-rating-review",
45729
45774
  "std-record-detail",
@@ -49707,7 +49752,6 @@
49707
49752
  "std-multi-party-flow",
49708
49753
  "std-notification-panel",
49709
49754
  "std-pagination",
49710
- "std-permission-matrix",
49711
49755
  "std-purchase-order",
49712
49756
  "std-question-bank",
49713
49757
  "std-rating-review",
@@ -51078,6 +51122,7 @@
51078
51122
  "std-modal-editor",
51079
51123
  "std-multi-party-flow",
51080
51124
  "std-notification-panel",
51125
+ "std-notification-preferences",
51081
51126
  "std-pagination",
51082
51127
  "std-rating-review",
51083
51128
  "std-record-detail",
@@ -52941,7 +52986,6 @@
52941
52986
  "std-motion-body",
52942
52987
  "std-multi-party-flow",
52943
52988
  "std-notification-panel",
52944
- "std-notification-preferences",
52945
52989
  "std-objective-board-3d",
52946
52990
  "std-objective-flow",
52947
52991
  "std-objective-reach",
@@ -84909,7 +84953,6 @@
84909
84953
  "std-modal-editor",
84910
84954
  "std-multi-party-flow",
84911
84955
  "std-notification-panel",
84912
- "std-notification-preferences",
84913
84956
  "std-pagination",
84914
84957
  "std-rating-review",
84915
84958
  "std-record-detail",
@@ -86346,7 +86389,6 @@
86346
86389
  "std-multi-party-flow",
86347
86390
  "std-notification-panel",
86348
86391
  "std-pagination",
86349
- "std-permission-matrix",
86350
86392
  "std-purchase-order",
86351
86393
  "std-question-bank",
86352
86394
  "std-rating-review",
@@ -94551,7 +94593,6 @@
94551
94593
  "std-multi-party-flow",
94552
94594
  "std-notification-panel",
94553
94595
  "std-pagination",
94554
- "std-permission-matrix",
94555
94596
  "std-purchase-order",
94556
94597
  "std-question-bank",
94557
94598
  "std-rating-review",
@@ -108235,7 +108276,6 @@
108235
108276
  "std-multi-party-flow",
108236
108277
  "std-notification-panel",
108237
108278
  "std-pagination",
108238
- "std-permission-matrix",
108239
108279
  "std-purchase-order",
108240
108280
  "std-question-bank",
108241
108281
  "std-rating-review",
@@ -112496,7 +112536,6 @@
112496
112536
  "std-multi-party-flow",
112497
112537
  "std-notification-panel",
112498
112538
  "std-pagination",
112499
- "std-permission-matrix",
112500
112539
  "std-purchase-order",
112501
112540
  "std-question-bank",
112502
112541
  "std-rating-review",
@@ -123291,7 +123330,6 @@
123291
123330
  "std-multi-party-flow",
123292
123331
  "std-notification-panel",
123293
123332
  "std-pagination",
123294
- "std-permission-matrix",
123295
123333
  "std-purchase-order",
123296
123334
  "std-question-bank",
123297
123335
  "std-rating-review",
@@ -148915,7 +148953,6 @@
148915
148953
  "std-multi-party-flow",
148916
148954
  "std-notification-panel",
148917
148955
  "std-pagination",
148918
- "std-permission-matrix",
148919
148956
  "std-purchase-order",
148920
148957
  "std-question-bank",
148921
148958
  "std-rating-review",
@@ -183867,7 +183904,6 @@
183867
183904
  "std-mesh-tactics",
183868
183905
  "std-motion-body",
183869
183906
  "std-multi-party-flow",
183870
- "std-notification-preferences",
183871
183907
  "std-objective-board-3d",
183872
183908
  "std-objective-flow",
183873
183909
  "std-objective-reach",
@@ -185640,7 +185676,6 @@
185640
185676
  "std-mesh-asset-art",
185641
185677
  "std-mesh-tactics",
185642
185678
  "std-motion-body",
185643
- "std-notification-preferences",
185644
185679
  "std-objective-board-3d",
185645
185680
  "std-objective-flow",
185646
185681
  "std-objective-reach",
@@ -190694,7 +190729,6 @@
190694
190729
  "std-mesh-tactics",
190695
190730
  "std-motion-body",
190696
190731
  "std-multi-party-flow",
190697
- "std-notification-preferences",
190698
190732
  "std-objective-board-3d",
190699
190733
  "std-objective-flow",
190700
190734
  "std-objective-reach",
@@ -193017,7 +193051,6 @@
193017
193051
  "std-mesh-tactics",
193018
193052
  "std-motion-body",
193019
193053
  "std-multi-party-flow",
193020
- "std-notification-preferences",
193021
193054
  "std-objective-flow",
193022
193055
  "std-objective-reach",
193023
193056
  "std-pad-lock",
@@ -198760,7 +198793,6 @@
198760
198793
  "std-mesh-tactics",
198761
198794
  "std-motion-body",
198762
198795
  "std-multi-party-flow",
198763
- "std-notification-preferences",
198764
198796
  "std-objective-board-3d",
198765
198797
  "std-objective-flow",
198766
198798
  "std-objective-reach",
@@ -200547,7 +200579,6 @@
200547
200579
  "std-mesh-asset-art",
200548
200580
  "std-mesh-tactics",
200549
200581
  "std-motion-body",
200550
- "std-notification-preferences",
200551
200582
  "std-objective-board-3d",
200552
200583
  "std-objective-flow",
200553
200584
  "std-objective-reach",
@@ -202639,7 +202670,6 @@
202639
202670
  "std-mesh-asset-art",
202640
202671
  "std-mesh-tactics",
202641
202672
  "std-motion-body",
202642
- "std-notification-preferences",
202643
202673
  "std-objective-board-3d",
202644
202674
  "std-objective-flow",
202645
202675
  "std-objective-reach",
@@ -206988,6 +207018,7 @@
206988
207018
  "std-math-vectors-3d",
206989
207019
  "std-ml-exact-check",
206990
207020
  "std-motion-body",
207021
+ "std-notification-preferences",
206991
207022
  "std-physics-circular",
206992
207023
  "std-physics-collision",
206993
207024
  "std-physics-diagram",
@@ -207728,6 +207759,7 @@
207728
207759
  "std-math-unitcircle",
207729
207760
  "std-math-vectors",
207730
207761
  "std-math-vectors-3d",
207762
+ "std-notification-preferences",
207731
207763
  "std-physics-circular",
207732
207764
  "std-physics-collision",
207733
207765
  "std-physics-diagram",
@@ -212263,6 +212295,7 @@
212263
212295
  "std-math-unitcircle",
212264
212296
  "std-math-vectors",
212265
212297
  "std-math-vectors-3d",
212298
+ "std-notification-preferences",
212266
212299
  "std-physics-circular",
212267
212300
  "std-physics-collision",
212268
212301
  "std-physics-diagram",
@@ -215177,6 +215210,7 @@
215177
215210
  "std-math-unitcircle",
215178
215211
  "std-math-vectors",
215179
215212
  "std-math-vectors-3d",
215213
+ "std-notification-preferences",
215180
215214
  "std-physics-circular",
215181
215215
  "std-physics-collision",
215182
215216
  "std-physics-diagram",
@@ -218646,6 +218680,7 @@
218646
218680
  "std-math-unitcircle",
218647
218681
  "std-math-vectors",
218648
218682
  "std-math-vectors-3d",
218683
+ "std-notification-preferences",
218649
218684
  "std-physics-circular",
218650
218685
  "std-physics-collision",
218651
218686
  "std-physics-diagram",
@@ -223491,6 +223526,7 @@
223491
223526
  "std-math-unitcircle",
223492
223527
  "std-math-vectors",
223493
223528
  "std-math-vectors-3d",
223529
+ "std-notification-preferences",
223494
223530
  "std-physics-circular",
223495
223531
  "std-physics-collision",
223496
223532
  "std-physics-diagram",