@company-semantics/contracts 0.30.0 → 0.31.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@company-semantics/contracts",
3
- "version": "0.30.0",
3
+ "version": "0.31.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,6 +28,10 @@
28
28
  "types": "./src/mcp/index.ts",
29
29
  "default": "./src/mcp/index.ts"
30
30
  },
31
+ "./execution": {
32
+ "types": "./src/execution/index.ts",
33
+ "default": "./src/execution/index.ts"
34
+ },
31
35
  "./schemas/guard-result.schema.json": "./schemas/guard-result.schema.json"
32
36
  },
33
37
  "types": "./src/index.ts",
@@ -0,0 +1,46 @@
1
+ # execution/
2
+
3
+ ## Purpose
4
+
5
+ TypeScript types and registry for execution kinds and their governance metadata.
6
+
7
+ ## Invariants
8
+
9
+ - Types only; minimal runtime code (pure functions for registry lookup)
10
+ - No external dependencies (contracts policy)
11
+ - `ExecutionKind` union MUST match keys in `EXECUTION_KINDS` registry
12
+ - `EXECUTION_KINDS` is the single source of truth for display, governance, and UI metadata
13
+ - `ExecutionSummary` and `TimelineUIEvent` are **projection contracts** (derived at query time, not stored)
14
+ - `visibility` is derived from `EXECUTION_KINDS[kind].governance.visibility`, never independently authored
15
+ - Unknown execution kinds MUST be rejected at API boundaries via `isValidExecutionKind()`
16
+
17
+ ## Public API
18
+
19
+ ### Types
20
+
21
+ - `ExecutionKind` — Union of valid execution kind identifiers
22
+ - `ExecutionKindDefinition` — Full definition schema for a kind
23
+ - `ExecutionDomain` — Domain category (`integration`, `policy`, `data`, `system`)
24
+ - `ISO8601Timestamp` — ISO 8601 timestamp string alias
25
+ - `IconName` — Icon identifiers for UI
26
+
27
+ ### Projection Contracts
28
+
29
+ - `ExecutionSummary` — Admin-facing execution view (derived from audit records)
30
+ - `ExecutionTarget` — Target of execution (e.g., Slack workspace)
31
+ - `ExecutionInitiator` — Who initiated the execution
32
+ - `ExecutionStatus` — Execution status (`pending`, `succeeded`, `failed`)
33
+ - `TimelineUIEvent` — User-facing timeline entry (derived from audit records)
34
+ - `TimelineStatus` — Timeline-specific status mapping
35
+ - `TimelineIcon` — Timeline-specific icon subset
36
+
37
+ ### Registry & Functions
38
+
39
+ - `EXECUTION_KINDS` — Registry of all execution kinds
40
+ - `getExecutionKindDefinition(kind)` — Type-safe registry lookup
41
+ - `isValidExecutionKind(kind)` — Validate string is ExecutionKind
42
+
43
+ ## Dependencies
44
+
45
+ **Imports from:** (none — leaf module)
46
+ **Imported by:** company-semantics-backend, company-semantics-app
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Execution Domain Barrel
3
+ *
4
+ * Re-exports execution kind vocabulary types and registry.
5
+ * Import from '@company-semantics/contracts/execution'.
6
+ *
7
+ * @see ADR-CONT-029 for design rationale
8
+ */
9
+
10
+ // =============================================================================
11
+ // Kind Types
12
+ // =============================================================================
13
+
14
+ export type { ExecutionKind } from './kinds.js'
15
+
16
+ // =============================================================================
17
+ // Definition Types
18
+ // =============================================================================
19
+
20
+ export type {
21
+ ISO8601Timestamp,
22
+ IconName,
23
+ ExecutionDomain,
24
+ ExecutionKindDefinition,
25
+ } from './types.js'
26
+
27
+ // =============================================================================
28
+ // Registry
29
+ // =============================================================================
30
+
31
+ export {
32
+ EXECUTION_KINDS,
33
+ getExecutionKindDefinition,
34
+ isValidExecutionKind,
35
+ } from './registry.js'
36
+
37
+ // =============================================================================
38
+ // Projection Contracts
39
+ // =============================================================================
40
+
41
+ // ExecutionSummary (admin-facing projection)
42
+ export type {
43
+ ExecutionTarget,
44
+ ExecutionInitiator,
45
+ ExecutionStatus,
46
+ ExecutionSummary,
47
+ } from './summary.js'
48
+
49
+ // TimelineUIEvent (user-facing projection)
50
+ export type {
51
+ TimelineStatus,
52
+ TimelineIcon,
53
+ TimelineUIEvent,
54
+ } from './timeline-ui.js'
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Execution Kind Vocabulary
3
+ *
4
+ * Canonical type for execution kinds across Company Semantics.
5
+ * Each kind represents a discrete, auditable action in the system.
6
+ *
7
+ * @see ADR-CONT-029 for design rationale
8
+ */
9
+
10
+ // =============================================================================
11
+ // ExecutionKind Union
12
+ // =============================================================================
13
+
14
+ /**
15
+ * ExecutionKind identifies the type of execution action.
16
+ *
17
+ * Naming convention: `{domain}.{verb}`
18
+ * - domain: integration, policy, data, system
19
+ * - verb: action being performed (connect, disconnect, etc.)
20
+ *
21
+ * New kinds MUST be added to:
22
+ * 1. This union type
23
+ * 2. EXECUTION_KINDS registry in registry.ts
24
+ */
25
+ export type ExecutionKind =
26
+ | 'integration.connect'
27
+ | 'integration.disconnect'
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Execution Kind Registry
3
+ *
4
+ * Central registry of all execution kinds and their definitions.
5
+ * This is the single source of truth for execution metadata.
6
+ *
7
+ * Invariants:
8
+ * - Every ExecutionKind MUST have an entry in EXECUTION_KINDS
9
+ * - Registry keys MUST match definition.kind
10
+ * - Registry is exhaustive (satisfies Record<ExecutionKind, ...>)
11
+ *
12
+ * @see ADR-CONT-029 for design rationale
13
+ */
14
+
15
+ import type { ExecutionKind } from './kinds.js'
16
+ import type { ExecutionKindDefinition } from './types.js'
17
+
18
+ // =============================================================================
19
+ // Registry
20
+ // =============================================================================
21
+
22
+ /**
23
+ * EXECUTION_KINDS is the authoritative registry.
24
+ *
25
+ * All display text, governance rules, and UI hints are derived from here.
26
+ * Backend executors and frontend components MUST use this registry
27
+ * rather than hardcoding values.
28
+ *
29
+ * To add a new kind:
30
+ * 1. Add to ExecutionKind union in kinds.ts
31
+ * 2. Add entry to this registry
32
+ * 3. Implement executor in backend
33
+ * 4. Add explanation template
34
+ */
35
+ export const EXECUTION_KINDS = {
36
+ 'integration.connect': {
37
+ kind: 'integration.connect',
38
+ domain: 'integration',
39
+ display: {
40
+ label: 'Connect Slack',
41
+ pastTenseLabel: 'Slack connected',
42
+ icon: 'plug',
43
+ },
44
+ governance: {
45
+ visibility: 'admin',
46
+ requiresAdmin: true,
47
+ reversibleBy: 'integration.disconnect',
48
+ },
49
+ ui: {
50
+ showInAdmin: true,
51
+ showInTimeline: true,
52
+ confirmBeforeRun: false,
53
+ },
54
+ explanation: {
55
+ templateId: 'integration.connect',
56
+ },
57
+ },
58
+ 'integration.disconnect': {
59
+ kind: 'integration.disconnect',
60
+ domain: 'integration',
61
+ display: {
62
+ label: 'Disconnect Slack',
63
+ pastTenseLabel: 'Slack disconnected',
64
+ icon: 'unlink',
65
+ },
66
+ governance: {
67
+ visibility: 'admin',
68
+ requiresAdmin: true,
69
+ },
70
+ ui: {
71
+ showInAdmin: true,
72
+ showInTimeline: true,
73
+ confirmBeforeRun: true,
74
+ },
75
+ explanation: {
76
+ templateId: 'integration.disconnect',
77
+ },
78
+ },
79
+ } as const satisfies Record<ExecutionKind, ExecutionKindDefinition>
80
+
81
+ // =============================================================================
82
+ // Registry Helpers
83
+ // =============================================================================
84
+
85
+ /**
86
+ * Type-safe registry lookup.
87
+ * Returns the definition for a given execution kind.
88
+ */
89
+ export function getExecutionKindDefinition(
90
+ kind: ExecutionKind
91
+ ): ExecutionKindDefinition {
92
+ return EXECUTION_KINDS[kind]
93
+ }
94
+
95
+ /**
96
+ * Check if a string is a valid ExecutionKind.
97
+ * Use at API boundaries to reject unknown kinds.
98
+ */
99
+ export function isValidExecutionKind(kind: string): kind is ExecutionKind {
100
+ return kind in EXECUTION_KINDS
101
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Execution Summary Projection
3
+ *
4
+ * ExecutionSummary is a PROJECTION CONTRACT, not a storage contract.
5
+ * It describes what UI consumers receive, not what backends persist.
6
+ * Backend services derive this from audit records at query time.
7
+ *
8
+ * DERIVATION RULES:
9
+ * - ExecutionSummary.visibility MUST be derived from
10
+ * EXECUTION_KINDS[kind].governance.visibility + execution facts.
11
+ * - It MUST NOT be independently authored or stored.
12
+ *
13
+ * @see ADR-CONT-029 for design rationale
14
+ */
15
+
16
+ import type { ExecutionKind } from './kinds.js'
17
+ import type { ISO8601Timestamp } from './types.js'
18
+
19
+ // =============================================================================
20
+ // Execution Target
21
+ // =============================================================================
22
+
23
+ /**
24
+ * Target of an execution action.
25
+ * Currently supports Slack integration; extensible for future integrations.
26
+ */
27
+ export type ExecutionTarget =
28
+ | { type: 'slack'; workspaceId?: string }
29
+
30
+ // =============================================================================
31
+ // Initiator
32
+ // =============================================================================
33
+
34
+ /**
35
+ * Who initiated the execution.
36
+ */
37
+ export interface ExecutionInitiator {
38
+ /** Actor type (user or automated system) */
39
+ actorType: 'user' | 'system'
40
+ /** Actor identifier (userId or system identifier) */
41
+ actorId: string
42
+ /** Human-readable name for display */
43
+ displayName: string
44
+ }
45
+
46
+ // =============================================================================
47
+ // Execution Status
48
+ // =============================================================================
49
+
50
+ /**
51
+ * Status of an execution.
52
+ */
53
+ export type ExecutionStatus = 'pending' | 'succeeded' | 'failed'
54
+
55
+ // =============================================================================
56
+ // Execution Summary
57
+ // =============================================================================
58
+
59
+ /**
60
+ * ExecutionSummary is a PROJECTION CONTRACT.
61
+ *
62
+ * This type represents the admin-facing view of an execution.
63
+ * It is derived from audit records, not stored directly.
64
+ *
65
+ * Invariants:
66
+ * - executionId is globally unique
67
+ * - visibility is derived from EXECUTION_KINDS[kind].governance.visibility
68
+ * - explanationAvailable reflects whether explanation can be generated
69
+ */
70
+ export interface ExecutionSummary {
71
+ /** Unique execution identifier */
72
+ executionId: string
73
+
74
+ /** Type of execution */
75
+ kind: ExecutionKind
76
+
77
+ /** What the execution targeted */
78
+ target: ExecutionTarget
79
+
80
+ /** Current status */
81
+ status: ExecutionStatus
82
+
83
+ /** Who initiated the execution */
84
+ initiatedBy: ExecutionInitiator
85
+
86
+ /** When the execution was initiated (decision point) */
87
+ decidedAt: ISO8601Timestamp
88
+
89
+ /** When the execution completed (if finished) */
90
+ completedAt?: ISO8601Timestamp
91
+
92
+ /**
93
+ * Visibility level for this execution.
94
+ * Derived from EXECUTION_KINDS[kind].governance.visibility.
95
+ * Used for filtering in queries.
96
+ */
97
+ visibility: 'admin' | 'user'
98
+
99
+ /** Whether an explanation can be generated for this execution */
100
+ explanationAvailable: boolean
101
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Timeline UI Event Projection
3
+ *
4
+ * TimelineUIEvent is a PROJECTION CONTRACT, not a storage contract.
5
+ * It describes what the Timeline UI receives, not what backends persist.
6
+ * Backend services derive this from audit records at query time.
7
+ *
8
+ * DERIVATION RULES:
9
+ * - icon: Derived from EXECUTION_KINDS[kind].display.icon
10
+ * - label: Derived from EXECUTION_KINDS[kind].display.pastTenseLabel
11
+ * - These are NEVER independently authored or stored
12
+ *
13
+ * @see ADR-CONT-029 for design rationale
14
+ */
15
+
16
+ import type { ISO8601Timestamp } from './types.js'
17
+
18
+ // =============================================================================
19
+ // Timeline Status
20
+ // =============================================================================
21
+
22
+ /**
23
+ * Status for timeline display.
24
+ * Maps from ExecutionStatus for UI-specific presentation.
25
+ */
26
+ export type TimelineStatus = 'success' | 'failed' | 'pending'
27
+
28
+ // =============================================================================
29
+ // Timeline Icon
30
+ // =============================================================================
31
+
32
+ /**
33
+ * Icon for timeline items.
34
+ * Must match IconName but constrained to timeline-relevant icons.
35
+ */
36
+ export type TimelineIcon = 'plug' | 'unlink'
37
+
38
+ // =============================================================================
39
+ // Timeline UI Event
40
+ // =============================================================================
41
+
42
+ /**
43
+ * TimelineUIEvent is a PROJECTION CONTRACT.
44
+ *
45
+ * This type represents a single event in the user-facing timeline.
46
+ * All display values are derived from EXECUTION_KINDS, not stored.
47
+ *
48
+ * Invariants:
49
+ * - label is derived from EXECUTION_KINDS[kind].display.pastTenseLabel
50
+ * - icon is derived from EXECUTION_KINDS[kind].display.icon
51
+ * - expandable indicates whether details can be fetched
52
+ */
53
+ export interface TimelineUIEvent {
54
+ /** Execution ID for correlation and detail fetching */
55
+ executionId: string
56
+
57
+ /**
58
+ * Display label (past tense).
59
+ * Derived from EXECUTION_KINDS[kind].display.pastTenseLabel
60
+ */
61
+ label: string
62
+
63
+ /**
64
+ * Icon identifier.
65
+ * Derived from EXECUTION_KINDS[kind].display.icon
66
+ */
67
+ icon: TimelineIcon
68
+
69
+ /** Visual status indicator */
70
+ status: TimelineStatus
71
+
72
+ /** When this event occurred */
73
+ timestamp: ISO8601Timestamp
74
+
75
+ /** Whether this event has expandable details */
76
+ expandable: boolean
77
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Execution Types
3
+ *
4
+ * Interfaces for execution kind definitions and governance.
5
+ *
6
+ * @see ADR-CONT-029 for design rationale
7
+ */
8
+
9
+ import type { ExecutionKind } from './kinds.js'
10
+
11
+ // =============================================================================
12
+ // Utility Types
13
+ // =============================================================================
14
+
15
+ /**
16
+ * ISO 8601 timestamp string.
17
+ * Example: "2026-01-08T14:30:00.000Z"
18
+ */
19
+ export type ISO8601Timestamp = string
20
+
21
+ /**
22
+ * Icon names for execution kinds.
23
+ * Must be supported by the frontend icon system.
24
+ */
25
+ export type IconName = 'plug' | 'unlink'
26
+
27
+ // =============================================================================
28
+ // Execution Domain
29
+ // =============================================================================
30
+
31
+ /**
32
+ * Domain categories for execution kinds.
33
+ */
34
+ export type ExecutionDomain = 'integration' | 'policy' | 'data' | 'system'
35
+
36
+ // =============================================================================
37
+ // Execution Kind Definition
38
+ // =============================================================================
39
+
40
+ /**
41
+ * Complete definition for an execution kind.
42
+ *
43
+ * This interface is the schema for entries in EXECUTION_KINDS registry.
44
+ * It captures display, governance, UI, and explanation metadata.
45
+ *
46
+ * Invariants:
47
+ * - kind field MUST match the registry key
48
+ * - reversibleBy (if set) MUST be a valid ExecutionKind
49
+ */
50
+ export interface ExecutionKindDefinition {
51
+ /** The execution kind this definition describes */
52
+ kind: ExecutionKind
53
+
54
+ /** Domain category for grouping and filtering */
55
+ domain: ExecutionDomain
56
+
57
+ /** Display metadata for UI rendering */
58
+ display: {
59
+ /** Label shown on buttons/actions (imperative: "Connect Slack") */
60
+ label: string
61
+ /** Label for completed actions (past tense: "Slack connected") */
62
+ pastTenseLabel: string
63
+ /** Icon identifier for UI */
64
+ icon: IconName
65
+ }
66
+
67
+ /** Governance constraints */
68
+ governance: {
69
+ /** Who can see this execution in lists/timelines */
70
+ visibility: 'admin' | 'user'
71
+ /** Whether admin role is required to initiate */
72
+ requiresAdmin: boolean
73
+ /** If reversible, which kind reverses this action */
74
+ reversibleBy?: ExecutionKind
75
+ }
76
+
77
+ /** UI behavior hints */
78
+ ui: {
79
+ /** Show in admin settings panel */
80
+ showInAdmin: boolean
81
+ /** Show in user-facing timeline */
82
+ showInTimeline: boolean
83
+ /** Require confirmation dialog before execution */
84
+ confirmBeforeRun?: boolean
85
+ }
86
+
87
+ /** Explanation generation metadata */
88
+ explanation: {
89
+ /** Template ID for explanation builder */
90
+ templateId: string
91
+ }
92
+ }
package/src/index.ts CHANGED
@@ -181,3 +181,27 @@ export {
181
181
  getDroppedCount,
182
182
  WireSurfaceBuilder,
183
183
  } from './message-parts/index.js'
184
+
185
+ // Execution kind types and registry
186
+ // @see ADR-CONT-029 for design rationale
187
+ export type {
188
+ ExecutionKind,
189
+ ISO8601Timestamp,
190
+ IconName,
191
+ ExecutionDomain,
192
+ ExecutionKindDefinition,
193
+ // Projection contracts
194
+ ExecutionTarget,
195
+ ExecutionInitiator,
196
+ ExecutionStatus,
197
+ ExecutionSummary,
198
+ TimelineStatus,
199
+ TimelineIcon,
200
+ TimelineUIEvent,
201
+ } from './execution/index.js'
202
+
203
+ export {
204
+ EXECUTION_KINDS,
205
+ getExecutionKindDefinition,
206
+ isValidExecutionKind,
207
+ } from './execution/index.js'