@company-semantics/contracts 100.0.0 → 101.1.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": "100.0.0",
3
+ "version": "101.1.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
2
- export const SPEC_HASH = '7e0143b235a3' as const;
3
- export const SPEC_HASH_FULL = '7e0143b235a3cc79cc020305bc8e4cf82c7784774cff280504fe70c0e9ee9a81' as const;
2
+ export const SPEC_HASH = '2a364932e5ca' as const;
3
+ export const SPEC_HASH_FULL = '2a364932e5ca5fb988423a06d4c58a57c255317be05c842237ce045260d2dd93' as const;
@@ -7469,11 +7469,13 @@ export interface components {
7469
7469
  /** @enum {string} */
7470
7470
  kind: "produced" | "empty" | "partial" | "stopped" | "failed" | "abandoned" | "unknown";
7471
7471
  /** @enum {string} */
7472
- reason: "updates_ready" | "updates_ready_partial" | "updates_applied" | "stopped_by_user" | "paused_billing" | "run_ceiling_reached" | "pricing_unconfigured" | "synthesis_incomplete" | "approval_mismatch" | "landing_refused" | "standing_order_refused" | "no_connection" | "source_sync_off" | "internal_error" | "abandoned" | "unrecognized_terminal_state";
7472
+ reason: "updates_ready" | "updates_ready_partial" | "updates_applied" | "updates_applied_partial" | "apply_refused" | "stopped_by_user" | "paused_billing" | "run_ceiling_reached" | "pricing_unconfigured" | "synthesis_incomplete" | "approval_mismatch" | "landing_refused" | "standing_order_refused" | "no_connection" | "source_sync_off" | "internal_error" | "abandoned" | "unrecognized_terminal_state";
7473
7473
  facts: {
7474
7474
  scopeCount: number;
7475
7475
  violationCount: number;
7476
7476
  notLandedCount: number;
7477
+ appliedDocCount: number | null;
7478
+ notAppliedDocCount: number | null;
7477
7479
  } | null;
7478
7480
  disposition: {
7479
7481
  /** @constant */
@@ -10850,7 +10852,7 @@ export interface components {
10850
10852
  } | null;
10851
10853
  approvedAt: string | null;
10852
10854
  approvable: boolean;
10853
- blockedReason: "needs_doc_access" | null;
10855
+ blockedReason: ("needs_approval_authority" | "needs_doc_access") | null;
10854
10856
  }[];
10855
10857
  discovery: {
10856
10858
  foundThisRun: number;
@@ -10916,7 +10918,7 @@ export interface components {
10916
10918
  } | null;
10917
10919
  approvedAt: string | null;
10918
10920
  approvable: boolean;
10919
- blockedReason: "needs_doc_access" | null;
10921
+ blockedReason: ("needs_approval_authority" | "needs_doc_access") | null;
10920
10922
  }[];
10921
10923
  /** Format: uuid */
10922
10924
  workflowId: string;
@@ -11045,7 +11047,7 @@ export interface components {
11045
11047
  } | null;
11046
11048
  approvedAt: string | null;
11047
11049
  approvable: boolean;
11048
- blockedReason: "needs_doc_access" | null;
11050
+ blockedReason: ("needs_approval_authority" | "needs_doc_access") | null;
11049
11051
  }[];
11050
11052
  };
11051
11053
  SourceSyncApplyResponse: {
@@ -11106,7 +11108,7 @@ export interface components {
11106
11108
  } | null;
11107
11109
  approvedAt: string | null;
11108
11110
  approvable: boolean;
11109
- blockedReason: "needs_doc_access" | null;
11111
+ blockedReason: ("needs_approval_authority" | "needs_doc_access") | null;
11110
11112
  }[];
11111
11113
  };
11112
11114
  SourceSyncRulesResponse: {
@@ -11547,7 +11549,12 @@ export interface components {
11547
11549
  grantedByLabel: string | null;
11548
11550
  /** Format: date-time */
11549
11551
  grantedAt: string;
11550
- suspendedReason: ("grantor_lost_authority" | "spend_cap_reached" | "connection_lost") | null;
11552
+ suspendedReason: ("grantor_lost_authority" | "grantor_lost_doc_access" | "spend_cap_reached" | "connection_lost") | null;
11553
+ }[];
11554
+ grantability: {
11555
+ scopeKey: string;
11556
+ grantable: boolean;
11557
+ blockedReason: ("needs_approval_authority" | "needs_doc_access") | null;
11551
11558
  }[];
11552
11559
  };
11553
11560
  SourceSyncStandingOrder: {
@@ -11560,7 +11567,7 @@ export interface components {
11560
11567
  grantedByLabel: string | null;
11561
11568
  /** Format: date-time */
11562
11569
  grantedAt: string;
11563
- suspendedReason: ("grantor_lost_authority" | "spend_cap_reached" | "connection_lost") | null;
11570
+ suspendedReason: ("grantor_lost_authority" | "grantor_lost_doc_access" | "spend_cap_reached" | "connection_lost") | null;
11564
11571
  };
11565
11572
  SourceSyncPutStandingOrderRequest: {
11566
11573
  /** @enum {string} */
@@ -21463,6 +21470,13 @@ export interface operations {
21463
21470
  };
21464
21471
  content?: never;
21465
21472
  };
21473
+ /** @description A scope the caller may not approve (SOURCE_SYNC_SCOPE_NOT_YOURS), or one whose document the caller cannot upload to and edit (SOURCE_SYNC_SCOPE_DOC_ACCESS_DENIED) */
21474
+ 403: {
21475
+ headers: {
21476
+ [name: string]: unknown;
21477
+ };
21478
+ content?: never;
21479
+ };
21466
21480
  /** @description The set is not the org’s */
21467
21481
  404: {
21468
21482
  headers: {
package/src/index.ts CHANGED
@@ -57,67 +57,9 @@ export type {
57
57
  AggregatedCapabilities,
58
58
  } from "./system/index";
59
59
 
60
- // Guard types (CI guard vocabulary)
61
- // @see schemas/guard-result.schema.json for JSON Schema
62
- export type {
63
- GuardMessage,
64
- GuardTierResult,
65
- GuardTier,
66
- GuardResults,
67
- CheckResult,
68
- GuardOutput,
69
- RoleLimit,
70
- GuardConfig,
71
- GuardCheck,
72
- GuardCheckFactory,
73
- BoundGuardCheck,
74
- GuardCheckRegistry,
75
- StructuralBaselines,
76
- ScriptsDepsBaseline,
77
- EvolutionBaselines,
78
- ContractsFreshnessBaseline,
79
- MetaBaselines,
80
- // Aggregate evolution types
81
- DomainAggregateBaseline,
82
- AggregateEvolutionConfig,
83
- // SOC 2 Compliance types
84
- Soc2ControlArea,
85
- Soc2ControlStatus,
86
- Soc2ControlResult,
87
- Soc2ComplianceOutput,
88
- // SOC 2 Guard Configuration types
89
- SecretsDetectionConfig,
90
- StructuredLoggingConfig,
91
- AlertsConfigGuardConfig,
92
- BackupConfigGuardConfig,
93
- Soc2Baselines,
94
- } from "./guards/index";
95
-
96
- export {
97
- GUARD_SCHEMA_VERSION,
98
- GUARD_TIERS,
99
- DEFAULT_SKIP_DIRECTORIES,
100
- DEFAULT_DOMAIN_SECTIONS,
101
- DEFAULT_INFRA_SECTIONS,
102
- // SOC 2 Compliance constants
103
- SOC2_CONTROL_NAMES,
104
- REQUIRED_SOC2_CONTROLS,
105
- BLOCKING_SOC2_CONTROLS,
106
- SOC2_SCHEMA_VERSION,
107
- } from "./guards/index";
108
-
109
- // Cross-repo CI aggregation vocabulary
110
- // @see ADR-CONT-033 for contracts boundary rationale
111
- // Note: GuardTier is already exported above from './guards/index' (structurally
112
- // identical); not re-exported here to avoid a duplicate-identifier collision.
113
- export type { GuardResultPayload, RepoCiResult } from "./ci-results/index";
114
-
115
- export { assertRepoCiResultConsistent } from "./ci-results/index";
116
-
117
- // Compatibility manifest (CI guard vocabulary)
118
- // @see ADR-2025-12-011 for design rationale
119
- export { COMPATIBILITY } from "./compatibility";
120
- export type { Compatibility, Deprecation } from "./compatibility";
60
+ // CI guard, CI aggregation and compatibility vocabulary — see
61
+ // ./root-exports/ci-governance.ts.
62
+ export * from "./root-exports/ci-governance";
121
63
 
122
64
  // User identity types and functions
123
65
  // @see ADR-CONT-032 for design rationale
@@ -232,21 +174,13 @@ export {
232
174
  export type { PrincipalRef } from "./identity/index";
233
175
 
234
176
  // Auth domain types
177
+ // Named, not starred: identity/index re-exports AuthStartResponse, and the
178
+ // export guard reads the identity names from this file's named lists.
235
179
  export type { AuthStartMode, AuthStartResponse } from "./auth/index";
236
180
  export { OTPErrorCode } from "./auth/index";
237
181
 
238
182
  // Dispatch deny vocabulary (PRD-00519/00521/00522)
239
- export { DISPATCH_DENY_CODES, isDispatchDenyCode } from "./dispatch/index";
240
- export type {
241
- ActionTier,
242
- DispatchDenyCode,
243
- DispatchDenyMetaByCode,
244
- ExecutionBudgetExceededMeta,
245
- IncrementalConsentRequiredMeta,
246
- ProviderAccessDenyReason,
247
- ProviderAccessDeniedMeta,
248
- WriteTierDisabledMeta,
249
- } from "./dispatch/index";
183
+ export * from "./dispatch/index";
250
184
 
251
185
  // Named re-export lists for the rest of the root surface live in
252
186
  // ./root-exports/, one slice per theme, each re-exported whole below. A slice
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Capability Schemas
3
+ *
4
+ * Zod schemas for the viewer's mutation capabilities (GET /api/capabilities).
5
+ * Re-exported from `./schemas`, the one import path for every org schema.
6
+ */
7
+ import { z } from "zod";
8
+ import { AI_PAUSE_REASONS } from "../billing/vocabulary";
9
+
10
+ // =============================================================================
11
+ // Mutation Capabilities (GET /api/capabilities) — ADR-BE-241 / PRD-00707 F4
12
+ // =============================================================================
13
+ // Canonical home for the viewer's resolved mutation-capability projection. The
14
+ // backend derives it (src/capabilities/derive.ts) and validates the response
15
+ // against CapabilitiesResponseSchema via sendValidated; the frontend reads the
16
+ // inferred types to render lock/allow affordances. Previously duplicated as a
17
+ // backend-local Zod + hand-written frontend interfaces — unified here.
18
+
19
+ /** Scope identifiers are dot-namespaced strings (see backend trust/scopes.ts). */
20
+ const RequiredScopeSchema = z.string();
21
+
22
+ /** A mutable field's gate: editable, or locked with attribution (sso vs rbac). */
23
+ export const FieldCapabilitySchema = z.object({
24
+ state: z.enum(["editable", "locked"]),
25
+ reason: z.enum(["sso", "rbac"]).optional(),
26
+ requiredScope: RequiredScopeSchema.optional(),
27
+ });
28
+
29
+ /** An action's gate: allowed, or blocked with the scope that would unlock it. */
30
+ export const ActionCapabilitySchema = z.object({
31
+ state: z.enum(["allowed", "blocked"]),
32
+ requiredScope: RequiredScopeSchema.optional(),
33
+ });
34
+
35
+ /**
36
+ * The single validated capability surface the UI reads. Every sub-object is
37
+ * optional, matching the partial derivation in deriveCapabilities() (actions/org
38
+ * are present only when scopes resolved).
39
+ */
40
+ export const CapabilitiesResponseSchema = z.object({
41
+ profile: z
42
+ .object({
43
+ fullName: FieldCapabilitySchema,
44
+ preferredName: FieldCapabilitySchema,
45
+ })
46
+ .optional(),
47
+ org: z
48
+ .object({
49
+ name: FieldCapabilitySchema,
50
+ })
51
+ .optional(),
52
+ actions: z
53
+ .object({
54
+ members: z.object({
55
+ invite: ActionCapabilitySchema,
56
+ remove: ActionCapabilitySchema,
57
+ changeRole: ActionCapabilitySchema,
58
+ }),
59
+ orgAdmins: z.object({
60
+ manage: ActionCapabilitySchema,
61
+ }),
62
+ orgUnit: z.object({
63
+ manage: ActionCapabilitySchema,
64
+ }),
65
+ // Entity ownership-transfer overrides (backend ADR-BE-259) +
66
+ // sharing-management custody (backend ADR-BE-288). Optional so older
67
+ // backends that don't derive them still validate. manageSharing gates the
68
+ // admin Share affordance on content the admin may not be able to view.
69
+ companyMd: z
70
+ .object({
71
+ transferOwnership: ActionCapabilitySchema,
72
+ manageSharing: ActionCapabilitySchema,
73
+ })
74
+ .optional(),
75
+ workItem: z
76
+ .object({
77
+ transferOwnership: ActionCapabilitySchema,
78
+ manageSharing: ActionCapabilitySchema,
79
+ })
80
+ .optional(),
81
+ meetingRecording: z
82
+ .object({
83
+ manageSharing: ActionCapabilitySchema,
84
+ })
85
+ .optional(),
86
+ })
87
+ .optional(),
88
+ // Gates the chat composer's mention affordance (PRD-00988). Optional for the
89
+ // same rollout symmetry as the action sub-objects above: a backend that does
90
+ // not yet derive the flag must still validate its own response, and the spec
91
+ // already carried the field before this schema did.
92
+ chatMentions: z.boolean().optional(),
93
+ // Gates the multi-party chat affordances — the participant header, the invite
94
+ // flow, speaker labels (PRD-00990/00991). Optional for the same rollout
95
+ // symmetry as `chatMentions` directly above, and it REQUIRES `chatMentions`:
96
+ // inviting someone is a mention, so multi-party without mentions is not a
97
+ // state the backend derives. The two are resolved from ONE flag read, not
98
+ // two — the capabilities route holds a hard 4-query budget for a P0 own-data
99
+ // read, and `chatMentions` already took the fourth slot.
100
+ chatMultiParty: z.boolean().optional(),
101
+ // Gates every AI affordance at once (PRD-01002). Optional for the same
102
+ // rollout symmetry as the flags above. It is deliberately a CAPABILITY and
103
+ // not a billing read: the UI needs to know whether to offer AI and what to
104
+ // say when it cannot, and nothing more — the balance, the ledger and the
105
+ // recovery live behind the billing endpoints, which an ordinary member has
106
+ // no right to. `reason` is the one AiPauseReason a human can act on, and it
107
+ // is null exactly when `aiPaused` is false.
108
+ billing: z
109
+ .object({
110
+ aiPaused: z.boolean(),
111
+ reason: z.enum(AI_PAUSE_REASONS).nullable(),
112
+ })
113
+ .optional(),
114
+ });
115
+
116
+ export type FieldCapability = z.infer<typeof FieldCapabilitySchema>;
117
+ export type ActionCapability = z.infer<typeof ActionCapabilitySchema>;
118
+ export type CapabilitiesResponse = z.infer<typeof CapabilitiesResponseSchema>;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Reporting Write Schemas
3
+ *
4
+ * Zod response schemas for setting a seat's manager (PUT
5
+ * /api/reporting/positions/:positionId/manager) and for submitting the
6
+ * interactive chat task surface that drives such writes. Re-exported from
7
+ * `./schemas`, the one import path for every org schema.
8
+ */
9
+ import { z } from "zod";
10
+ import { PositionRefSchema } from "../identity/position-ref";
11
+
12
+ // ---------------------------------------------------------------------------
13
+ // PUT /api/reporting/positions/:positionId/manager
14
+ // ---------------------------------------------------------------------------
15
+
16
+ /**
17
+ * Response for the one idempotent set-or-clear of a seat's solid-line manager —
18
+ * the reporting edge the org chart is built from. Position-keyed at BOTH ends
19
+ * (ADR-CONTRACTS-131): `reportPositionId` is the seat whose edge moved and
20
+ * `manager` is the POSITION it now reports to, null after a clear. A position
21
+ * names a vacant seat and an accountless occupant's seat just as well as a
22
+ * filled one, which the retired member-or-open-role union could not.
23
+ *
24
+ * `relationshipType` is a literal rather than the identity-domain
25
+ * `ReportingRelationshipTypeSchema`: importing that here would invert the
26
+ * existing people-org-chart → org/schemas dependency and recreate the
27
+ * module-init cycle. This route only ever writes solid edges, so the narrower
28
+ * literal is also the truthful shape. (`PositionReportingRelationshipTypeSchema`
29
+ * in ./position-reporting carries the open {solid, dotted} vocabulary for the
30
+ * read model.)
31
+ *
32
+ * Distinct from team membership (RBAC scopes) and `primary_unit_id` (home
33
+ * unit): neither of those places a person in the reporting hierarchy.
34
+ * See ADR-BE-253.
35
+ */
36
+ export const SetSeatManagerResponseSchema = z.object({
37
+ success: z.boolean(),
38
+ reportPositionId: z.string().uuid(),
39
+ manager: PositionRefSchema.nullable(),
40
+ relationshipType: z.literal("solid"),
41
+ message: z.string(),
42
+ });
43
+
44
+ export type SetSeatManagerResponse = z.infer<
45
+ typeof SetSeatManagerResponseSchema
46
+ >;
47
+
48
+ // ---------------------------------------------------------------------------
49
+ // POST /api/chat/interactive-tasks/submit
50
+ // ---------------------------------------------------------------------------
51
+
52
+ /**
53
+ * Response for submitting a filled-in interactive chat task surface (e.g. the
54
+ * editable "change reporting manager" form). The submit endpoint runs the
55
+ * Deterministic Execution & Governance Engine: it creates an execution and,
56
+ * when no further confirmation is required, drives it to execution in the same
57
+ * request. The frontend then drives the surface's lifecycle card off
58
+ * `executionId` (the execution-lifecycle stream), exactly like a confirmation.
59
+ *
60
+ * See ADR-CONTRACTS-068.
61
+ */
62
+ export const SubmitInteractiveTaskResponseSchema = z.object({
63
+ /** Lifecycle record id created for this submission. */
64
+ executionId: z.string(),
65
+ /** Coarse lifecycle status at the time the request returns. */
66
+ status: z.enum(["executing", "completed", "failed", "pending_confirmation"]),
67
+ });
68
+
69
+ export type SubmitInteractiveTaskResponse = z.infer<
70
+ typeof SubmitInteractiveTaskResponseSchema
71
+ >;