@ai-matrx/records 0.8.0 → 0.11.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.
package/dist/index.d.cts CHANGED
@@ -2596,6 +2596,116 @@ interface FieldPatch {
2596
2596
  options?: string[];
2597
2597
  }
2598
2598
 
2599
+ /** The seven table types. Only these two carry custom fields (REC-34, DD-011). */
2600
+ type CustomFieldTableType = "entity" | "detail";
2601
+ /** What `custom.entity_table` answers about a registry token. */
2602
+ interface EntityTableFacts {
2603
+ token: string;
2604
+ schema_name: string;
2605
+ table_name: string;
2606
+ type: CustomFieldTableType;
2607
+ title_column: string | null;
2608
+ /** The name a person reads. Never the type word. */
2609
+ label: string;
2610
+ /**
2611
+ * 57 of the 643 have no `organization_id`. They carry the column like every
2612
+ * other one, but a VALUE on them would belong to nobody — the guard finds an
2613
+ * organization's Fields through the row's own `organization_id` — so the
2614
+ * value doors refuse them BY NAME rather than writing something unowned.
2615
+ */
2616
+ has_organization: boolean;
2617
+ has_deleted_at: boolean;
2618
+ }
2619
+ /** One custom field of a standard row, as the read door hands it back. */
2620
+ interface EntityFieldValue {
2621
+ id: Uuid;
2622
+ key: string;
2623
+ label: string;
2624
+ type: Field["type"];
2625
+ parity_type?: ParityFieldType;
2626
+ format?: string;
2627
+ unit?: string;
2628
+ multi?: boolean;
2629
+ required?: boolean;
2630
+ sort?: number;
2631
+ sensitivity?: Field["sensitivity"];
2632
+ options_table_id?: Uuid;
2633
+ relation_target?: Uuid;
2634
+ /** The value itself, or undefined when this row has none. */
2635
+ value?: unknown;
2636
+ /** VAL-1…VAL-8: who wrote it, when, on whose behalf, in which version. */
2637
+ written?: {
2638
+ ver?: number;
2639
+ actor?: string;
2640
+ on_behalf_of?: string | null;
2641
+ at?: string;
2642
+ src?: unknown;
2643
+ absent?: unknown;
2644
+ alternates?: unknown;
2645
+ dated?: unknown;
2646
+ };
2647
+ }
2648
+ /**
2649
+ * REC-53 IN ONE ANSWER: a standard row is its real columns, plus the base
2650
+ * contract, plus its organization's custom fields — three named blocks, never
2651
+ * one flat bag, so nothing can quietly shadow anything.
2652
+ */
2653
+ interface EntityRecordRead {
2654
+ token: string;
2655
+ label: string;
2656
+ type: CustomFieldTableType;
2657
+ id: Uuid;
2658
+ organization_id: Uuid;
2659
+ /** The registry's `title_column` of this row, when it has one. */
2660
+ title: string | null;
2661
+ /** The row's own columns, `custom_fields` removed. */
2662
+ columns: Record<string, unknown>;
2663
+ /** The custom values, by key. */
2664
+ custom: Record<string, unknown>;
2665
+ /** Their envelopes, by key. */
2666
+ custom_written: Record<string, EntityFieldValue["written"]>;
2667
+ /** The definitions, in the organization's own sort order, each with its value. */
2668
+ fields: EntityFieldValue[];
2669
+ live: boolean;
2670
+ }
2671
+ /** One row the filter matched. */
2672
+ interface EntityRecordMatch {
2673
+ id: Uuid;
2674
+ title: string | null;
2675
+ value: unknown;
2676
+ }
2677
+ interface EntityRecordsFound {
2678
+ token: string;
2679
+ label: string;
2680
+ key: string;
2681
+ value: unknown;
2682
+ rows: EntityRecordMatch[];
2683
+ count: number;
2684
+ }
2685
+ /**
2686
+ * What a person knows when they add a column. The SAME spec `fieldDeclare`
2687
+ * takes for a custom table — the store turns it into the document its guards
2688
+ * demand, so a standard table gets the whole type vocabulary rather than a
2689
+ * second, poorer one.
2690
+ */
2691
+ type NewEntityFieldDeclaration = Record<string, unknown> & {
2692
+ label: string;
2693
+ type?: string;
2694
+ options?: string[];
2695
+ };
2696
+ /**
2697
+ * SCR-12. May this person add a column to this standard table, and if not, the
2698
+ * sentence saying why — so the control is ABSENT with a reason rather than dead
2699
+ * when pressed. Filling in the fields that already exist is not admin work.
2700
+ */
2701
+ interface EntityFieldRights {
2702
+ token: string;
2703
+ label: string;
2704
+ may_declare: boolean;
2705
+ reason: string | null;
2706
+ may_fill_in: boolean;
2707
+ }
2708
+
2599
2709
  /**
2600
2710
  * A rule expression as `custom.rule_eval` ACTUALLY evaluates it — read off the
2601
2711
  * door's own body, not invented here. A leaf is the node's name carrying its
@@ -3096,6 +3206,111 @@ interface AnonTokenBinding {
3096
3206
  record_id: Uuid | null;
3097
3207
  mode: "read" | "write";
3098
3208
  }
3209
+ /** The three things that land in the one inbox. Closed, one word each. */
3210
+ type WorkInboxKind = "assignment" | "approval" | "proposal";
3211
+ /** Who filed it: a colleague, or an agent acting for one. */
3212
+ type WorkOrigin = "person" | "agent";
3213
+ /** Where a due date stands, in the store's own words. */
3214
+ type WorkDueState = "overdue" | "due_today" | "scheduled" | "undated" | "finished";
3215
+ /** One row of `custom.work_inbox` — the SAME shape whichever of the three it is. */
3216
+ interface WorkInboxItem {
3217
+ item_id: Uuid;
3218
+ kind: WorkInboxKind;
3219
+ origin: WorkOrigin;
3220
+ title: string;
3221
+ subject_id: Uuid | null;
3222
+ subject_kind: string;
3223
+ summary: string | null;
3224
+ state: string;
3225
+ due_on: Timestamp | null;
3226
+ due_state: WorkDueState | null;
3227
+ /** False for a decided row a person asked to see. A screen shows it, inert. */
3228
+ actionable: boolean;
3229
+ requested_by: Uuid | null;
3230
+ requested_by_name: string | null;
3231
+ at: Timestamp;
3232
+ }
3233
+ /** Which of the three lists `custom.work_list` answers. */
3234
+ type WorkListFlavour = "mine" | "assigned" | "unassigned";
3235
+ /** One row of `custom.work_list`: a record, whose it is, and where it is up to. */
3236
+ interface WorkListItem {
3237
+ record_id: Uuid;
3238
+ table_id: Uuid;
3239
+ table_name: string | null;
3240
+ title: string | null;
3241
+ assignee_id: Uuid | null;
3242
+ assignee_name: string | null;
3243
+ assignee_user_id: Uuid | null;
3244
+ due_on: Timestamp | null;
3245
+ due_state: WorkDueState;
3246
+ status: string | null;
3247
+ terminal: boolean;
3248
+ assigned_by: Uuid | null;
3249
+ updated_at: Timestamp;
3250
+ }
3251
+ /**
3252
+ * One state a record may be moved to, with the model's own answer about whether
3253
+ * it may — and, when it may not, the sentence saying why. A screen offers what
3254
+ * is allowed and explains what is not; it never renders a dead control.
3255
+ */
3256
+ interface WorkRecordState {
3257
+ state_id: Uuid;
3258
+ name: string;
3259
+ sort: number;
3260
+ terminal: boolean;
3261
+ is_current: boolean;
3262
+ allowed: boolean;
3263
+ refusal: string | null;
3264
+ }
3265
+ /** The change a pending approval carries. Two kinds, because two can be applied. */
3266
+ type WorkChange = {
3267
+ kind: "record_patch";
3268
+ patch: Record<string, unknown>;
3269
+ } | {
3270
+ kind: "field_add";
3271
+ field: Record<string, unknown>;
3272
+ };
3273
+ /** Somebody who may decide a particular request, and the reason they may. */
3274
+ interface WorkApprover {
3275
+ user_id: Uuid;
3276
+ name: string;
3277
+ why: string;
3278
+ }
3279
+ /** What `custom.work_approval_request` answers: it is filed, and who it waits on. */
3280
+ interface WorkApprovalFiled {
3281
+ approval_id: Uuid;
3282
+ state: "pending";
3283
+ subject_id: Uuid;
3284
+ subject_kind: string;
3285
+ origin: WorkOrigin;
3286
+ approvers: WorkApprover[];
3287
+ message: string;
3288
+ }
3289
+ /** What a decision answers — including whether the change was actually made. */
3290
+ interface WorkApprovalDecision {
3291
+ approval_id: Uuid;
3292
+ state: "approved" | "declined";
3293
+ subject_id: Uuid;
3294
+ /** The whole point: approving APPLIES the change, in the same transaction. */
3295
+ applied: boolean;
3296
+ field_id: Uuid | null;
3297
+ version: number | null;
3298
+ message: string;
3299
+ }
3300
+ /** What `custom.work_assign` answers: the value, the access, and who holds it now. */
3301
+ interface WorkAssignment {
3302
+ record_id: Uuid;
3303
+ assigned: boolean;
3304
+ assignee: Uuid | null;
3305
+ assignee_user_id: Uuid | null;
3306
+ assignee_name: string | null;
3307
+ was: Uuid | null;
3308
+ due_date: Timestamp | null;
3309
+ version: number | null;
3310
+ /** The share sentence, or why nothing was taken away when un-assigning. */
3311
+ access: string;
3312
+ message: string;
3313
+ }
3099
3314
 
3100
3315
  /**
3101
3316
  * VIS-31. A signed-in OUTSIDER, with the reason in plain English.
@@ -3426,4 +3641,4 @@ interface RecordsConfig {
3426
3641
  schema?: string;
3427
3642
  }
3428
3643
 
3429
- export { ABSENCE_REASONS, ACTOR_VOCABULARY, type AbsenceReason, type Actor, type AggregateBucket, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AnonTokenBinding, COMPUTE_ON, CONTEXT_POLICIES, type ComputeOn, type ContextPolicy, DELIVERIES, type Delivery, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EntityToken, type ExternalPrincipalCard, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type Home, KERNEL_TABLES, type KernelTableName, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type PredictedRefusal, type ProvenancePointer, type PublishBinding, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordDocument, type RecordRead, type RecordRevision, type RecordsActor, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type Subscription, type SubscriptionBlock, type SubscriptionCadence, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkAssignmentField, type WorkGraph, type WorkInstantiation, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, asPermissionLevel, atLeast, err, highestLevel, isRecordsErr, measureKey, ok, publicFormPath };
3644
+ export { ABSENCE_REASONS, ACTOR_VOCABULARY, type AbsenceReason, type Actor, type AggregateBucket, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AnonTokenBinding, COMPUTE_ON, CONTEXT_POLICIES, type ComputeOn, type ContextPolicy, type CustomFieldTableType, DELIVERIES, type Delivery, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type EntityToken, type ExternalPrincipalCard, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type Home, KERNEL_TABLES, type KernelTableName, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type NewEntityFieldDeclaration, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type PredictedRefusal, type ProvenancePointer, type PublishBinding, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordDocument, type RecordRead, type RecordRevision, type RecordsActor, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type Subscription, type SubscriptionBlock, type SubscriptionCadence, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, asPermissionLevel, atLeast, err, highestLevel, isRecordsErr, measureKey, ok, publicFormPath };
package/dist/index.d.ts CHANGED
@@ -2596,6 +2596,116 @@ interface FieldPatch {
2596
2596
  options?: string[];
2597
2597
  }
2598
2598
 
2599
+ /** The seven table types. Only these two carry custom fields (REC-34, DD-011). */
2600
+ type CustomFieldTableType = "entity" | "detail";
2601
+ /** What `custom.entity_table` answers about a registry token. */
2602
+ interface EntityTableFacts {
2603
+ token: string;
2604
+ schema_name: string;
2605
+ table_name: string;
2606
+ type: CustomFieldTableType;
2607
+ title_column: string | null;
2608
+ /** The name a person reads. Never the type word. */
2609
+ label: string;
2610
+ /**
2611
+ * 57 of the 643 have no `organization_id`. They carry the column like every
2612
+ * other one, but a VALUE on them would belong to nobody — the guard finds an
2613
+ * organization's Fields through the row's own `organization_id` — so the
2614
+ * value doors refuse them BY NAME rather than writing something unowned.
2615
+ */
2616
+ has_organization: boolean;
2617
+ has_deleted_at: boolean;
2618
+ }
2619
+ /** One custom field of a standard row, as the read door hands it back. */
2620
+ interface EntityFieldValue {
2621
+ id: Uuid;
2622
+ key: string;
2623
+ label: string;
2624
+ type: Field["type"];
2625
+ parity_type?: ParityFieldType;
2626
+ format?: string;
2627
+ unit?: string;
2628
+ multi?: boolean;
2629
+ required?: boolean;
2630
+ sort?: number;
2631
+ sensitivity?: Field["sensitivity"];
2632
+ options_table_id?: Uuid;
2633
+ relation_target?: Uuid;
2634
+ /** The value itself, or undefined when this row has none. */
2635
+ value?: unknown;
2636
+ /** VAL-1…VAL-8: who wrote it, when, on whose behalf, in which version. */
2637
+ written?: {
2638
+ ver?: number;
2639
+ actor?: string;
2640
+ on_behalf_of?: string | null;
2641
+ at?: string;
2642
+ src?: unknown;
2643
+ absent?: unknown;
2644
+ alternates?: unknown;
2645
+ dated?: unknown;
2646
+ };
2647
+ }
2648
+ /**
2649
+ * REC-53 IN ONE ANSWER: a standard row is its real columns, plus the base
2650
+ * contract, plus its organization's custom fields — three named blocks, never
2651
+ * one flat bag, so nothing can quietly shadow anything.
2652
+ */
2653
+ interface EntityRecordRead {
2654
+ token: string;
2655
+ label: string;
2656
+ type: CustomFieldTableType;
2657
+ id: Uuid;
2658
+ organization_id: Uuid;
2659
+ /** The registry's `title_column` of this row, when it has one. */
2660
+ title: string | null;
2661
+ /** The row's own columns, `custom_fields` removed. */
2662
+ columns: Record<string, unknown>;
2663
+ /** The custom values, by key. */
2664
+ custom: Record<string, unknown>;
2665
+ /** Their envelopes, by key. */
2666
+ custom_written: Record<string, EntityFieldValue["written"]>;
2667
+ /** The definitions, in the organization's own sort order, each with its value. */
2668
+ fields: EntityFieldValue[];
2669
+ live: boolean;
2670
+ }
2671
+ /** One row the filter matched. */
2672
+ interface EntityRecordMatch {
2673
+ id: Uuid;
2674
+ title: string | null;
2675
+ value: unknown;
2676
+ }
2677
+ interface EntityRecordsFound {
2678
+ token: string;
2679
+ label: string;
2680
+ key: string;
2681
+ value: unknown;
2682
+ rows: EntityRecordMatch[];
2683
+ count: number;
2684
+ }
2685
+ /**
2686
+ * What a person knows when they add a column. The SAME spec `fieldDeclare`
2687
+ * takes for a custom table — the store turns it into the document its guards
2688
+ * demand, so a standard table gets the whole type vocabulary rather than a
2689
+ * second, poorer one.
2690
+ */
2691
+ type NewEntityFieldDeclaration = Record<string, unknown> & {
2692
+ label: string;
2693
+ type?: string;
2694
+ options?: string[];
2695
+ };
2696
+ /**
2697
+ * SCR-12. May this person add a column to this standard table, and if not, the
2698
+ * sentence saying why — so the control is ABSENT with a reason rather than dead
2699
+ * when pressed. Filling in the fields that already exist is not admin work.
2700
+ */
2701
+ interface EntityFieldRights {
2702
+ token: string;
2703
+ label: string;
2704
+ may_declare: boolean;
2705
+ reason: string | null;
2706
+ may_fill_in: boolean;
2707
+ }
2708
+
2599
2709
  /**
2600
2710
  * A rule expression as `custom.rule_eval` ACTUALLY evaluates it — read off the
2601
2711
  * door's own body, not invented here. A leaf is the node's name carrying its
@@ -3096,6 +3206,111 @@ interface AnonTokenBinding {
3096
3206
  record_id: Uuid | null;
3097
3207
  mode: "read" | "write";
3098
3208
  }
3209
+ /** The three things that land in the one inbox. Closed, one word each. */
3210
+ type WorkInboxKind = "assignment" | "approval" | "proposal";
3211
+ /** Who filed it: a colleague, or an agent acting for one. */
3212
+ type WorkOrigin = "person" | "agent";
3213
+ /** Where a due date stands, in the store's own words. */
3214
+ type WorkDueState = "overdue" | "due_today" | "scheduled" | "undated" | "finished";
3215
+ /** One row of `custom.work_inbox` — the SAME shape whichever of the three it is. */
3216
+ interface WorkInboxItem {
3217
+ item_id: Uuid;
3218
+ kind: WorkInboxKind;
3219
+ origin: WorkOrigin;
3220
+ title: string;
3221
+ subject_id: Uuid | null;
3222
+ subject_kind: string;
3223
+ summary: string | null;
3224
+ state: string;
3225
+ due_on: Timestamp | null;
3226
+ due_state: WorkDueState | null;
3227
+ /** False for a decided row a person asked to see. A screen shows it, inert. */
3228
+ actionable: boolean;
3229
+ requested_by: Uuid | null;
3230
+ requested_by_name: string | null;
3231
+ at: Timestamp;
3232
+ }
3233
+ /** Which of the three lists `custom.work_list` answers. */
3234
+ type WorkListFlavour = "mine" | "assigned" | "unassigned";
3235
+ /** One row of `custom.work_list`: a record, whose it is, and where it is up to. */
3236
+ interface WorkListItem {
3237
+ record_id: Uuid;
3238
+ table_id: Uuid;
3239
+ table_name: string | null;
3240
+ title: string | null;
3241
+ assignee_id: Uuid | null;
3242
+ assignee_name: string | null;
3243
+ assignee_user_id: Uuid | null;
3244
+ due_on: Timestamp | null;
3245
+ due_state: WorkDueState;
3246
+ status: string | null;
3247
+ terminal: boolean;
3248
+ assigned_by: Uuid | null;
3249
+ updated_at: Timestamp;
3250
+ }
3251
+ /**
3252
+ * One state a record may be moved to, with the model's own answer about whether
3253
+ * it may — and, when it may not, the sentence saying why. A screen offers what
3254
+ * is allowed and explains what is not; it never renders a dead control.
3255
+ */
3256
+ interface WorkRecordState {
3257
+ state_id: Uuid;
3258
+ name: string;
3259
+ sort: number;
3260
+ terminal: boolean;
3261
+ is_current: boolean;
3262
+ allowed: boolean;
3263
+ refusal: string | null;
3264
+ }
3265
+ /** The change a pending approval carries. Two kinds, because two can be applied. */
3266
+ type WorkChange = {
3267
+ kind: "record_patch";
3268
+ patch: Record<string, unknown>;
3269
+ } | {
3270
+ kind: "field_add";
3271
+ field: Record<string, unknown>;
3272
+ };
3273
+ /** Somebody who may decide a particular request, and the reason they may. */
3274
+ interface WorkApprover {
3275
+ user_id: Uuid;
3276
+ name: string;
3277
+ why: string;
3278
+ }
3279
+ /** What `custom.work_approval_request` answers: it is filed, and who it waits on. */
3280
+ interface WorkApprovalFiled {
3281
+ approval_id: Uuid;
3282
+ state: "pending";
3283
+ subject_id: Uuid;
3284
+ subject_kind: string;
3285
+ origin: WorkOrigin;
3286
+ approvers: WorkApprover[];
3287
+ message: string;
3288
+ }
3289
+ /** What a decision answers — including whether the change was actually made. */
3290
+ interface WorkApprovalDecision {
3291
+ approval_id: Uuid;
3292
+ state: "approved" | "declined";
3293
+ subject_id: Uuid;
3294
+ /** The whole point: approving APPLIES the change, in the same transaction. */
3295
+ applied: boolean;
3296
+ field_id: Uuid | null;
3297
+ version: number | null;
3298
+ message: string;
3299
+ }
3300
+ /** What `custom.work_assign` answers: the value, the access, and who holds it now. */
3301
+ interface WorkAssignment {
3302
+ record_id: Uuid;
3303
+ assigned: boolean;
3304
+ assignee: Uuid | null;
3305
+ assignee_user_id: Uuid | null;
3306
+ assignee_name: string | null;
3307
+ was: Uuid | null;
3308
+ due_date: Timestamp | null;
3309
+ version: number | null;
3310
+ /** The share sentence, or why nothing was taken away when un-assigning. */
3311
+ access: string;
3312
+ message: string;
3313
+ }
3099
3314
 
3100
3315
  /**
3101
3316
  * VIS-31. A signed-in OUTSIDER, with the reason in plain English.
@@ -3426,4 +3641,4 @@ interface RecordsConfig {
3426
3641
  schema?: string;
3427
3642
  }
3428
3643
 
3429
- export { ABSENCE_REASONS, ACTOR_VOCABULARY, type AbsenceReason, type Actor, type AggregateBucket, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AnonTokenBinding, COMPUTE_ON, CONTEXT_POLICIES, type ComputeOn, type ContextPolicy, DELIVERIES, type Delivery, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EntityToken, type ExternalPrincipalCard, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type Home, KERNEL_TABLES, type KernelTableName, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type PredictedRefusal, type ProvenancePointer, type PublishBinding, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordDocument, type RecordRead, type RecordRevision, type RecordsActor, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type Subscription, type SubscriptionBlock, type SubscriptionCadence, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkAssignmentField, type WorkGraph, type WorkInstantiation, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, asPermissionLevel, atLeast, err, highestLevel, isRecordsErr, measureKey, ok, publicFormPath };
3644
+ export { ABSENCE_REASONS, ACTOR_VOCABULARY, type AbsenceReason, type Actor, type AggregateBucket, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AnonTokenBinding, COMPUTE_ON, CONTEXT_POLICIES, type ComputeOn, type ContextPolicy, type CustomFieldTableType, DELIVERIES, type Delivery, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type EntityToken, type ExternalPrincipalCard, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type Home, KERNEL_TABLES, type KernelTableName, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type NewEntityFieldDeclaration, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type PredictedRefusal, type ProvenancePointer, type PublishBinding, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordDocument, type RecordRead, type RecordRevision, type RecordsActor, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type Subscription, type SubscriptionBlock, type SubscriptionCadence, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, asPermissionLevel, atLeast, err, highestLevel, isRecordsErr, measureKey, ok, publicFormPath };