@company-semantics/contracts 27.5.0 → 27.7.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 +8 -6
- package/src/api/generated-spec-hash.ts +2 -2
- package/src/api/generated.ts +80 -10
- package/src/generated/openapi-routes.ts +1 -0
- package/src/guards/config.ts +30 -217
- package/src/guards/evolution-config.ts +123 -0
- package/src/guards/soc2-config.ts +122 -0
- package/src/org/sharing.ts +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@company-semantics/contracts",
|
|
3
|
-
"version": "27.
|
|
3
|
+
"version": "27.7.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -105,9 +105,11 @@
|
|
|
105
105
|
"test": "vitest run",
|
|
106
106
|
"test:run": "vitest run",
|
|
107
107
|
"generate:spec-hash": "tsx scripts/generate-spec-hash.ts",
|
|
108
|
-
"generate:
|
|
108
|
+
"generate:spec-hash:check": "tsx scripts/generate-spec-hash.ts --check",
|
|
109
|
+
"generate:api": "pnpm generate:api-types && pnpm generate:spec-hash && pnpm generate:openapi-routes",
|
|
109
110
|
"generate:api-types": "openapi-typescript openapi/backend.yaml -o src/api/generated.ts",
|
|
110
111
|
"generate:openapi-routes": "tsx scripts/generate-openapi-routes.ts",
|
|
112
|
+
"generate:openapi-routes:check": "tsx scripts/generate-openapi-routes.ts --check",
|
|
111
113
|
"generate:api-types:check": "openapi-typescript openapi/backend.yaml -o /tmp/cs-api-types-check.ts && diff -q src/api/generated.ts /tmp/cs-api-types-check.ts",
|
|
112
114
|
"generate:current": "tsx ../company-semantics-ci/scripts/generate-current.ts",
|
|
113
115
|
"repo-map": "tsx ../company-semantics-ci/scripts/generate-repo-map.ts --roots src --name company-semantics-contracts --write",
|
|
@@ -123,15 +125,15 @@
|
|
|
123
125
|
"zod": "^4.4.3"
|
|
124
126
|
},
|
|
125
127
|
"devDependencies": {
|
|
126
|
-
"@types/node": "^
|
|
128
|
+
"@types/node": "^22.20.0",
|
|
127
129
|
"husky": "^9.1.7",
|
|
128
130
|
"lint-staged": "^17.0.8",
|
|
129
|
-
"markdownlint-cli2": "^0.
|
|
131
|
+
"markdownlint-cli2": "^0.23.0",
|
|
130
132
|
"openapi-typescript": "^7.13.0",
|
|
131
133
|
"prettier": "^3.9.4",
|
|
132
|
-
"tsx": "^4.
|
|
134
|
+
"tsx": "^4.23.0",
|
|
133
135
|
"typescript": "^5.8.3",
|
|
134
|
-
"vitest": "^4.1.
|
|
136
|
+
"vitest": "^4.1.10",
|
|
135
137
|
"yaml": "^2.9.0"
|
|
136
138
|
},
|
|
137
139
|
"pnpm": {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
|
|
2
|
-
export const SPEC_HASH = '
|
|
3
|
-
export const SPEC_HASH_FULL = '
|
|
2
|
+
export const SPEC_HASH = '628fe99ff916' as const;
|
|
3
|
+
export const SPEC_HASH_FULL = '628fe99ff9166b9eb6c0b2bab2794f4e730ceabff0785b7b54b8015897e9551d' as const;
|
package/src/api/generated.ts
CHANGED
|
@@ -770,6 +770,23 @@ export interface paths {
|
|
|
770
770
|
patch?: never;
|
|
771
771
|
trace?: never;
|
|
772
772
|
};
|
|
773
|
+
"/api/reporting/move/apply": {
|
|
774
|
+
parameters: {
|
|
775
|
+
query?: never;
|
|
776
|
+
header?: never;
|
|
777
|
+
path?: never;
|
|
778
|
+
cookie?: never;
|
|
779
|
+
};
|
|
780
|
+
get?: never;
|
|
781
|
+
put?: never;
|
|
782
|
+
/** Apply a confirmed org-chart reporting move as a governed semantic transform */
|
|
783
|
+
post: operations["applyReportingMove"];
|
|
784
|
+
delete?: never;
|
|
785
|
+
options?: never;
|
|
786
|
+
head?: never;
|
|
787
|
+
patch?: never;
|
|
788
|
+
trace?: never;
|
|
789
|
+
};
|
|
773
790
|
"/api/chat/interactive-tasks/submit": {
|
|
774
791
|
parameters: {
|
|
775
792
|
query?: never;
|
|
@@ -3927,16 +3944,47 @@ export interface components {
|
|
|
3927
3944
|
idempotencyKey: string;
|
|
3928
3945
|
};
|
|
3929
3946
|
MovePreviewRequest: {
|
|
3930
|
-
/**
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3947
|
+
/** @constant */
|
|
3948
|
+
kind: "reporting.setManager";
|
|
3949
|
+
/** Format: uuid */
|
|
3950
|
+
reportPositionId: string;
|
|
3951
|
+
/** Format: uuid */
|
|
3952
|
+
managerPositionId: string;
|
|
3953
|
+
} | {
|
|
3954
|
+
/** @constant */
|
|
3955
|
+
kind: "unit.setParent";
|
|
3956
|
+
/** Format: uuid */
|
|
3957
|
+
unitId: string;
|
|
3958
|
+
parentUnitId: string | null;
|
|
3959
|
+
} | {
|
|
3960
|
+
/** @constant */
|
|
3961
|
+
kind: "position.setTitle";
|
|
3962
|
+
/** Format: uuid */
|
|
3963
|
+
positionId: string;
|
|
3964
|
+
title: string;
|
|
3965
|
+
};
|
|
3966
|
+
MoveApplyRequest: {
|
|
3967
|
+
mutations: ({
|
|
3968
|
+
/** @constant */
|
|
3969
|
+
kind: "reporting.setManager";
|
|
3970
|
+
/** Format: uuid */
|
|
3971
|
+
reportPositionId: string;
|
|
3972
|
+
managerPositionId: string | null;
|
|
3973
|
+
} | {
|
|
3974
|
+
/** @constant */
|
|
3975
|
+
kind: "unit.setParent";
|
|
3976
|
+
/** Format: uuid */
|
|
3977
|
+
unitId: string;
|
|
3978
|
+
parentUnitId: string | null;
|
|
3979
|
+
} | {
|
|
3980
|
+
/** @constant */
|
|
3981
|
+
kind: "position.setTitle";
|
|
3982
|
+
/** Format: uuid */
|
|
3983
|
+
positionId: string;
|
|
3984
|
+
title: string;
|
|
3985
|
+
})[];
|
|
3986
|
+
reason: string | null;
|
|
3987
|
+
idempotencyKey: string;
|
|
3940
3988
|
};
|
|
3941
3989
|
SubmitInteractiveTaskResponse: {
|
|
3942
3990
|
executionId: string;
|
|
@@ -7101,6 +7149,28 @@ export interface operations {
|
|
|
7101
7149
|
};
|
|
7102
7150
|
};
|
|
7103
7151
|
};
|
|
7152
|
+
applyReportingMove: {
|
|
7153
|
+
parameters: {
|
|
7154
|
+
query?: never;
|
|
7155
|
+
header?: never;
|
|
7156
|
+
path?: never;
|
|
7157
|
+
cookie?: never;
|
|
7158
|
+
};
|
|
7159
|
+
requestBody: {
|
|
7160
|
+
content: {
|
|
7161
|
+
"application/json": components["schemas"]["MoveApplyRequest"];
|
|
7162
|
+
};
|
|
7163
|
+
};
|
|
7164
|
+
responses: {
|
|
7165
|
+
/** @description The confirmed transformation was applied through the governed execution */
|
|
7166
|
+
200: {
|
|
7167
|
+
headers: {
|
|
7168
|
+
[name: string]: unknown;
|
|
7169
|
+
};
|
|
7170
|
+
content?: never;
|
|
7171
|
+
};
|
|
7172
|
+
};
|
|
7173
|
+
};
|
|
7104
7174
|
submitInteractiveTask: {
|
|
7105
7175
|
parameters: {
|
|
7106
7176
|
query?: never;
|
|
@@ -126,6 +126,7 @@ export const openApiRoutes = {
|
|
|
126
126
|
'/api/orgs/{orgId}/level-config': ['GET', 'PUT'],
|
|
127
127
|
'/api/rbac/roles': ['GET'],
|
|
128
128
|
'/api/reporting/bulk-reparent': ['POST'],
|
|
129
|
+
'/api/reporting/move/apply': ['POST'],
|
|
129
130
|
'/api/reporting/move/preview': ['POST'],
|
|
130
131
|
'/api/scope/check': ['GET'],
|
|
131
132
|
'/api/scope/check-batch': ['POST'],
|
package/src/guards/config.ts
CHANGED
|
@@ -8,7 +8,36 @@
|
|
|
8
8
|
* Each repo provides its own config values; shared guards consume them.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { CheckResult
|
|
11
|
+
import type { CheckResult } from "./types";
|
|
12
|
+
// The EvolutionBaselines interface below references these evolution baseline
|
|
13
|
+
// types, which now live in ./evolution-config.
|
|
14
|
+
import type {
|
|
15
|
+
CoverageBaseline,
|
|
16
|
+
FileClusterBaseline,
|
|
17
|
+
SubdirectoryAffinityBaseline,
|
|
18
|
+
} from "./evolution-config";
|
|
19
|
+
|
|
20
|
+
// SOC 2 guard configuration types live in a sibling module (extracted to keep
|
|
21
|
+
// this file within its size envelope). Re-exported here so the package public
|
|
22
|
+
// surface — consumed via the guards barrel — is unchanged.
|
|
23
|
+
export type {
|
|
24
|
+
SecretsDetectionConfig,
|
|
25
|
+
StructuredLoggingConfig,
|
|
26
|
+
AlertsConfigGuardConfig,
|
|
27
|
+
BackupConfigGuardConfig,
|
|
28
|
+
Soc2Baselines,
|
|
29
|
+
} from "./soc2-config";
|
|
30
|
+
|
|
31
|
+
// Evolution & drift-detection baseline config types live in a sibling module
|
|
32
|
+
// (extracted to keep this file within its size envelope). Re-exported here so
|
|
33
|
+
// the package public surface — consumed via the guards barrel — is unchanged.
|
|
34
|
+
export type {
|
|
35
|
+
DomainAggregateBaseline,
|
|
36
|
+
AggregateEvolutionConfig,
|
|
37
|
+
CoverageBaseline,
|
|
38
|
+
FileClusterBaseline,
|
|
39
|
+
SubdirectoryAffinityBaseline,
|
|
40
|
+
} from "./evolution-config";
|
|
12
41
|
|
|
13
42
|
// =============================================================================
|
|
14
43
|
// Size Limits
|
|
@@ -299,222 +328,6 @@ export interface EvolutionBaselines {
|
|
|
299
328
|
subdirectoryAffinity?: SubdirectoryAffinityBaseline;
|
|
300
329
|
}
|
|
301
330
|
|
|
302
|
-
// =============================================================================
|
|
303
|
-
// Aggregate Evolution Types
|
|
304
|
-
// =============================================================================
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Domain-level aggregate baseline for evolution tracking.
|
|
308
|
-
* Replaces per-file baselines with domain-aggregated metrics.
|
|
309
|
-
*
|
|
310
|
-
* Design: Domains are extracted from file paths (first 2 segments).
|
|
311
|
-
* Example: 'src/chat/execution/types.ts' → domain 'chat/execution'
|
|
312
|
-
*/
|
|
313
|
-
export interface DomainAggregateBaseline {
|
|
314
|
-
/** Total exports across all files in domain */
|
|
315
|
-
exports: number;
|
|
316
|
-
/** Total imports across all files in domain */
|
|
317
|
-
imports: number;
|
|
318
|
-
/** Diagnostic only, not thresholded */
|
|
319
|
-
fileCount: number;
|
|
320
|
-
/** ISO timestamp when baseline was captured */
|
|
321
|
-
capturedAt?: string;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Configuration for aggregate evolution guard.
|
|
326
|
-
* Uses domain-level metrics instead of per-file tracking.
|
|
327
|
-
*
|
|
328
|
-
* Benefits over per-file:
|
|
329
|
-
* - ~22 entries vs ~300 entries
|
|
330
|
-
* - Stable under refactors within domains
|
|
331
|
-
* - Grows O(domains) not O(files)
|
|
332
|
-
*/
|
|
333
|
-
export interface AggregateEvolutionConfig {
|
|
334
|
-
/** Source directory to scan */
|
|
335
|
-
srcDir: string;
|
|
336
|
-
/** Domain baselines keyed by domain path */
|
|
337
|
-
domains: Record<string, DomainAggregateBaseline>;
|
|
338
|
-
/** Global totals for sanity checking */
|
|
339
|
-
totals?: {
|
|
340
|
-
exports: number;
|
|
341
|
-
imports: number;
|
|
342
|
-
files: number;
|
|
343
|
-
capturedAt?: string;
|
|
344
|
-
};
|
|
345
|
-
/** Warning thresholds (sensible defaults applied if omitted) */
|
|
346
|
-
thresholds?: {
|
|
347
|
-
/** Absolute export growth before warning (default: 10) */
|
|
348
|
-
domainExportGrowth?: number;
|
|
349
|
-
/** Percentage growth before warning (default: 0.25 = 25%) */
|
|
350
|
-
domainGrowthPercent?: number;
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// =============================================================================
|
|
355
|
-
// Coverage Baseline Types
|
|
356
|
-
// =============================================================================
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Coverage baseline configuration.
|
|
360
|
-
* Used by CI orchestrator to inject coverage drift guard.
|
|
361
|
-
*/
|
|
362
|
-
export interface CoverageBaseline {
|
|
363
|
-
/** Path to coverage-summary.json (default: 'coverage/coverage-summary.json') */
|
|
364
|
-
coverageFile?: string;
|
|
365
|
-
/** Baseline coverage percentage (lines) */
|
|
366
|
-
baseline: number;
|
|
367
|
-
/** Allowed drop threshold before error (default: 0 = any drop errors) */
|
|
368
|
-
dropThreshold?: number;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* File cluster detection configuration.
|
|
373
|
-
* Detects clusters of related files that could benefit from
|
|
374
|
-
* parent-child folder organization.
|
|
375
|
-
*
|
|
376
|
-
* @see ADR-CI-010
|
|
377
|
-
*/
|
|
378
|
-
export interface FileClusterBaseline {
|
|
379
|
-
/** Minimum files to form a cluster */
|
|
380
|
-
minClusterSize?: number;
|
|
381
|
-
/** Minimum stragglers to suggest reorganization */
|
|
382
|
-
minStragglers?: number;
|
|
383
|
-
/** Suffixes to strip when detecting clusters (e.g., '.test', '.spec') */
|
|
384
|
-
stripSuffixes?: string[];
|
|
385
|
-
/** Role words to strip (e.g., 'Service', 'Handler') */
|
|
386
|
-
stripRoleWords?: string[];
|
|
387
|
-
/** Directories to ignore */
|
|
388
|
-
ignoredDirectories?: string[];
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* Subdirectory affinity detection configuration.
|
|
393
|
-
* Detects files in a parent directory that are only imported by
|
|
394
|
-
* files within a single subdirectory, suggesting they should move.
|
|
395
|
-
*/
|
|
396
|
-
export interface SubdirectoryAffinityBaseline {
|
|
397
|
-
/** Minimum importers required */
|
|
398
|
-
minImporters?: number;
|
|
399
|
-
/** Maximum non-subdirectory imports allowed */
|
|
400
|
-
maxNonSubdirImports?: number;
|
|
401
|
-
/** Patterns to exclude from analysis */
|
|
402
|
-
excludePatterns?: RegExp[];
|
|
403
|
-
/** Importer patterns to ignore */
|
|
404
|
-
ignoredImporterPatterns?: RegExp[];
|
|
405
|
-
/** Directories to ignore */
|
|
406
|
-
ignoredDirectories?: string[];
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
// =============================================================================
|
|
410
|
-
// SOC 2 Guard Configuration Types
|
|
411
|
-
// =============================================================================
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* Configuration for the secrets detection guard.
|
|
415
|
-
* This is a blocking control for SOC 2 Access Control (AC).
|
|
416
|
-
*/
|
|
417
|
-
export interface SecretsDetectionConfig {
|
|
418
|
-
/** Source directory to scan (relative to repo root) */
|
|
419
|
-
srcDir?: string;
|
|
420
|
-
/** Additional directories to scan */
|
|
421
|
-
additionalDirs?: string[];
|
|
422
|
-
/** File patterns to exclude (globs) */
|
|
423
|
-
excludePatterns?: string[];
|
|
424
|
-
/** Additional secret patterns to detect (regex strings) */
|
|
425
|
-
additionalPatterns?: string[];
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* Configuration for the structured logging guard.
|
|
430
|
-
* This is a non-blocking control for SOC 2 Logging & Monitoring (LM).
|
|
431
|
-
*/
|
|
432
|
-
export interface StructuredLoggingConfig {
|
|
433
|
-
/** Entry point files to check (relative to repo root) */
|
|
434
|
-
entryPoints?: string[];
|
|
435
|
-
/** Source directory to scan for logging (fallback if no entry points) */
|
|
436
|
-
srcDir?: string;
|
|
437
|
-
/** Recognized logging libraries */
|
|
438
|
-
loggingLibraries?: string[];
|
|
439
|
-
/** Logger instantiation patterns (regex strings) */
|
|
440
|
-
instantiationPatterns?: string[];
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
/**
|
|
444
|
-
* Configuration for the alerts config guard.
|
|
445
|
-
* This is a non-blocking control for SOC 2 Logging & Monitoring (LM).
|
|
446
|
-
*/
|
|
447
|
-
export interface AlertsConfigGuardConfig {
|
|
448
|
-
/**
|
|
449
|
-
* Files or directories to check for alerting configuration.
|
|
450
|
-
* Supports both file paths and directory paths.
|
|
451
|
-
*/
|
|
452
|
-
files?: string[];
|
|
453
|
-
/**
|
|
454
|
-
* Whether this check should be skipped.
|
|
455
|
-
* Use for repos that don't have alerting (e.g., pure libraries).
|
|
456
|
-
*/
|
|
457
|
-
skip?: boolean;
|
|
458
|
-
/**
|
|
459
|
-
* Evidence string when alerting is explicitly skipped.
|
|
460
|
-
*/
|
|
461
|
-
skipEvidence?: string;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/**
|
|
465
|
-
* Configuration for the backup config guard.
|
|
466
|
-
* This is a non-blocking control for SOC 2 Backup & Recovery (BR).
|
|
467
|
-
*/
|
|
468
|
-
export interface BackupConfigGuardConfig {
|
|
469
|
-
/**
|
|
470
|
-
* Files or directories to check for backup configuration.
|
|
471
|
-
*/
|
|
472
|
-
files?: string[];
|
|
473
|
-
/**
|
|
474
|
-
* Whether this check should be skipped.
|
|
475
|
-
* Use for repos that don't manage backups (e.g., frontend-only).
|
|
476
|
-
*/
|
|
477
|
-
skip?: boolean;
|
|
478
|
-
/**
|
|
479
|
-
* Evidence string when backup check is explicitly skipped.
|
|
480
|
-
*/
|
|
481
|
-
skipEvidence?: string;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* SOC 2 compliance baselines.
|
|
486
|
-
* Configures SOC 2 control guards for a repository.
|
|
487
|
-
*
|
|
488
|
-
* Design: Product repos provide data only; CI orchestrator owns guard implementations.
|
|
489
|
-
*/
|
|
490
|
-
export interface Soc2Baselines {
|
|
491
|
-
/** Enable SOC 2 compliance reporting */
|
|
492
|
-
enabled?: boolean;
|
|
493
|
-
/** Advisory mode: all controls become non-blocking for visibility-only rollout */
|
|
494
|
-
advisoryMode?: boolean;
|
|
495
|
-
/** Repository name (for evidence) */
|
|
496
|
-
repository?: string;
|
|
497
|
-
/** Secrets detection configuration */
|
|
498
|
-
secretsDetection?: SecretsDetectionConfig;
|
|
499
|
-
/** Structured logging configuration */
|
|
500
|
-
structuredLogging?: StructuredLoggingConfig;
|
|
501
|
-
/** Alerts config configuration */
|
|
502
|
-
alertsConfig?: AlertsConfigGuardConfig;
|
|
503
|
-
/** Backup config configuration */
|
|
504
|
-
backupConfig?: BackupConfigGuardConfig;
|
|
505
|
-
/** Controls to explicitly skip (with evidence) */
|
|
506
|
-
skipControls?: {
|
|
507
|
-
area: Soc2ControlArea;
|
|
508
|
-
evidence: string;
|
|
509
|
-
}[];
|
|
510
|
-
/**
|
|
511
|
-
* Controls that remain blocking even in advisory mode.
|
|
512
|
-
* Use to gradually promote controls from advisory to blocking.
|
|
513
|
-
* Example: ['AC'] to make secrets-detection blocking first.
|
|
514
|
-
*/
|
|
515
|
-
alwaysBlockingControls?: Soc2ControlArea[];
|
|
516
|
-
}
|
|
517
|
-
|
|
518
331
|
/**
|
|
519
332
|
* Registry of checks grouped by tier.
|
|
520
333
|
* Each repo exports this from guard-entries.ts for universal orchestration.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evolution & Drift-Detection Guard Configuration Vocabulary
|
|
3
|
+
*
|
|
4
|
+
* Polymorphic configuration types for the evolution/drift guards: domain-level
|
|
5
|
+
* aggregate tracking plus the coverage, file-cluster, and subdirectory-affinity
|
|
6
|
+
* baselines referenced by EvolutionBaselines.
|
|
7
|
+
*
|
|
8
|
+
* Extracted from ./config.ts as a cohesive sub-module (the evolution guard
|
|
9
|
+
* baseline family) to keep config.ts within its file-size envelope. This is a
|
|
10
|
+
* pure, behavior-preserving move: the identifiers are re-exported from
|
|
11
|
+
* ./config.ts so the package public surface is unchanged.
|
|
12
|
+
*
|
|
13
|
+
* Design principle: Configuration is data, not code.
|
|
14
|
+
*
|
|
15
|
+
* @architecture-role universal
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// Aggregate Evolution Types
|
|
20
|
+
// =============================================================================
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Domain-level aggregate baseline for evolution tracking.
|
|
24
|
+
* Replaces per-file baselines with domain-aggregated metrics.
|
|
25
|
+
*
|
|
26
|
+
* Design: Domains are extracted from file paths (first 2 segments).
|
|
27
|
+
* Example: 'src/chat/execution/types.ts' → domain 'chat/execution'
|
|
28
|
+
*/
|
|
29
|
+
export interface DomainAggregateBaseline {
|
|
30
|
+
/** Total exports across all files in domain */
|
|
31
|
+
exports: number;
|
|
32
|
+
/** Total imports across all files in domain */
|
|
33
|
+
imports: number;
|
|
34
|
+
/** Diagnostic only, not thresholded */
|
|
35
|
+
fileCount: number;
|
|
36
|
+
/** ISO timestamp when baseline was captured */
|
|
37
|
+
capturedAt?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Configuration for aggregate evolution guard.
|
|
42
|
+
* Uses domain-level metrics instead of per-file tracking.
|
|
43
|
+
*
|
|
44
|
+
* Benefits over per-file:
|
|
45
|
+
* - ~22 entries vs ~300 entries
|
|
46
|
+
* - Stable under refactors within domains
|
|
47
|
+
* - Grows O(domains) not O(files)
|
|
48
|
+
*/
|
|
49
|
+
export interface AggregateEvolutionConfig {
|
|
50
|
+
/** Source directory to scan */
|
|
51
|
+
srcDir: string;
|
|
52
|
+
/** Domain baselines keyed by domain path */
|
|
53
|
+
domains: Record<string, DomainAggregateBaseline>;
|
|
54
|
+
/** Global totals for sanity checking */
|
|
55
|
+
totals?: {
|
|
56
|
+
exports: number;
|
|
57
|
+
imports: number;
|
|
58
|
+
files: number;
|
|
59
|
+
capturedAt?: string;
|
|
60
|
+
};
|
|
61
|
+
/** Warning thresholds (sensible defaults applied if omitted) */
|
|
62
|
+
thresholds?: {
|
|
63
|
+
/** Absolute export growth before warning (default: 10) */
|
|
64
|
+
domainExportGrowth?: number;
|
|
65
|
+
/** Percentage growth before warning (default: 0.25 = 25%) */
|
|
66
|
+
domainGrowthPercent?: number;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// =============================================================================
|
|
71
|
+
// Coverage Baseline Types
|
|
72
|
+
// =============================================================================
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Coverage baseline configuration.
|
|
76
|
+
* Used by CI orchestrator to inject coverage drift guard.
|
|
77
|
+
*/
|
|
78
|
+
export interface CoverageBaseline {
|
|
79
|
+
/** Path to coverage-summary.json (default: 'coverage/coverage-summary.json') */
|
|
80
|
+
coverageFile?: string;
|
|
81
|
+
/** Baseline coverage percentage (lines) */
|
|
82
|
+
baseline: number;
|
|
83
|
+
/** Allowed drop threshold before error (default: 0 = any drop errors) */
|
|
84
|
+
dropThreshold?: number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* File cluster detection configuration.
|
|
89
|
+
* Detects clusters of related files that could benefit from
|
|
90
|
+
* parent-child folder organization.
|
|
91
|
+
*
|
|
92
|
+
* @see ADR-CI-010
|
|
93
|
+
*/
|
|
94
|
+
export interface FileClusterBaseline {
|
|
95
|
+
/** Minimum files to form a cluster */
|
|
96
|
+
minClusterSize?: number;
|
|
97
|
+
/** Minimum stragglers to suggest reorganization */
|
|
98
|
+
minStragglers?: number;
|
|
99
|
+
/** Suffixes to strip when detecting clusters (e.g., '.test', '.spec') */
|
|
100
|
+
stripSuffixes?: string[];
|
|
101
|
+
/** Role words to strip (e.g., 'Service', 'Handler') */
|
|
102
|
+
stripRoleWords?: string[];
|
|
103
|
+
/** Directories to ignore */
|
|
104
|
+
ignoredDirectories?: string[];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Subdirectory affinity detection configuration.
|
|
109
|
+
* Detects files in a parent directory that are only imported by
|
|
110
|
+
* files within a single subdirectory, suggesting they should move.
|
|
111
|
+
*/
|
|
112
|
+
export interface SubdirectoryAffinityBaseline {
|
|
113
|
+
/** Minimum importers required */
|
|
114
|
+
minImporters?: number;
|
|
115
|
+
/** Maximum non-subdirectory imports allowed */
|
|
116
|
+
maxNonSubdirImports?: number;
|
|
117
|
+
/** Patterns to exclude from analysis */
|
|
118
|
+
excludePatterns?: RegExp[];
|
|
119
|
+
/** Importer patterns to ignore */
|
|
120
|
+
ignoredImporterPatterns?: RegExp[];
|
|
121
|
+
/** Directories to ignore */
|
|
122
|
+
ignoredDirectories?: string[];
|
|
123
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SOC 2 Guard Configuration Vocabulary
|
|
3
|
+
*
|
|
4
|
+
* Polymorphic configuration types for the SOC 2 compliance guards.
|
|
5
|
+
* Each repo provides its own control config values; shared guards consume them.
|
|
6
|
+
*
|
|
7
|
+
* Extracted from ./config.ts as a cohesive sub-module (the SOC 2 control
|
|
8
|
+
* config family) to keep config.ts within its file-size envelope. This is a
|
|
9
|
+
* pure, behavior-preserving move: the identifiers are re-exported from
|
|
10
|
+
* ./config.ts so the package public surface is unchanged.
|
|
11
|
+
*
|
|
12
|
+
* Design principle: Configuration is data, not code.
|
|
13
|
+
*
|
|
14
|
+
* @architecture-role universal
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { Soc2ControlArea } from "./types";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Configuration for the secrets detection guard.
|
|
21
|
+
* This is a blocking control for SOC 2 Access Control (AC).
|
|
22
|
+
*/
|
|
23
|
+
export interface SecretsDetectionConfig {
|
|
24
|
+
/** Source directory to scan (relative to repo root) */
|
|
25
|
+
srcDir?: string;
|
|
26
|
+
/** Additional directories to scan */
|
|
27
|
+
additionalDirs?: string[];
|
|
28
|
+
/** File patterns to exclude (globs) */
|
|
29
|
+
excludePatterns?: string[];
|
|
30
|
+
/** Additional secret patterns to detect (regex strings) */
|
|
31
|
+
additionalPatterns?: string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Configuration for the structured logging guard.
|
|
36
|
+
* This is a non-blocking control for SOC 2 Logging & Monitoring (LM).
|
|
37
|
+
*/
|
|
38
|
+
export interface StructuredLoggingConfig {
|
|
39
|
+
/** Entry point files to check (relative to repo root) */
|
|
40
|
+
entryPoints?: string[];
|
|
41
|
+
/** Source directory to scan for logging (fallback if no entry points) */
|
|
42
|
+
srcDir?: string;
|
|
43
|
+
/** Recognized logging libraries */
|
|
44
|
+
loggingLibraries?: string[];
|
|
45
|
+
/** Logger instantiation patterns (regex strings) */
|
|
46
|
+
instantiationPatterns?: string[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Configuration for the alerts config guard.
|
|
51
|
+
* This is a non-blocking control for SOC 2 Logging & Monitoring (LM).
|
|
52
|
+
*/
|
|
53
|
+
export interface AlertsConfigGuardConfig {
|
|
54
|
+
/**
|
|
55
|
+
* Files or directories to check for alerting configuration.
|
|
56
|
+
* Supports both file paths and directory paths.
|
|
57
|
+
*/
|
|
58
|
+
files?: string[];
|
|
59
|
+
/**
|
|
60
|
+
* Whether this check should be skipped.
|
|
61
|
+
* Use for repos that don't have alerting (e.g., pure libraries).
|
|
62
|
+
*/
|
|
63
|
+
skip?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Evidence string when alerting is explicitly skipped.
|
|
66
|
+
*/
|
|
67
|
+
skipEvidence?: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Configuration for the backup config guard.
|
|
72
|
+
* This is a non-blocking control for SOC 2 Backup & Recovery (BR).
|
|
73
|
+
*/
|
|
74
|
+
export interface BackupConfigGuardConfig {
|
|
75
|
+
/**
|
|
76
|
+
* Files or directories to check for backup configuration.
|
|
77
|
+
*/
|
|
78
|
+
files?: string[];
|
|
79
|
+
/**
|
|
80
|
+
* Whether this check should be skipped.
|
|
81
|
+
* Use for repos that don't manage backups (e.g., frontend-only).
|
|
82
|
+
*/
|
|
83
|
+
skip?: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Evidence string when backup check is explicitly skipped.
|
|
86
|
+
*/
|
|
87
|
+
skipEvidence?: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* SOC 2 compliance baselines.
|
|
92
|
+
* Configures SOC 2 control guards for a repository.
|
|
93
|
+
*
|
|
94
|
+
* Design: Product repos provide data only; CI orchestrator owns guard implementations.
|
|
95
|
+
*/
|
|
96
|
+
export interface Soc2Baselines {
|
|
97
|
+
/** Enable SOC 2 compliance reporting */
|
|
98
|
+
enabled?: boolean;
|
|
99
|
+
/** Advisory mode: all controls become non-blocking for visibility-only rollout */
|
|
100
|
+
advisoryMode?: boolean;
|
|
101
|
+
/** Repository name (for evidence) */
|
|
102
|
+
repository?: string;
|
|
103
|
+
/** Secrets detection configuration */
|
|
104
|
+
secretsDetection?: SecretsDetectionConfig;
|
|
105
|
+
/** Structured logging configuration */
|
|
106
|
+
structuredLogging?: StructuredLoggingConfig;
|
|
107
|
+
/** Alerts config configuration */
|
|
108
|
+
alertsConfig?: AlertsConfigGuardConfig;
|
|
109
|
+
/** Backup config configuration */
|
|
110
|
+
backupConfig?: BackupConfigGuardConfig;
|
|
111
|
+
/** Controls to explicitly skip (with evidence) */
|
|
112
|
+
skipControls?: {
|
|
113
|
+
area: Soc2ControlArea;
|
|
114
|
+
evidence: string;
|
|
115
|
+
}[];
|
|
116
|
+
/**
|
|
117
|
+
* Controls that remain blocking even in advisory mode.
|
|
118
|
+
* Use to gradually promote controls from advisory to blocking.
|
|
119
|
+
* Example: ['AC'] to make secrets-detection blocking first.
|
|
120
|
+
*/
|
|
121
|
+
alwaysBlockingControls?: Soc2ControlArea[];
|
|
122
|
+
}
|
package/src/org/sharing.ts
CHANGED
|
@@ -31,10 +31,20 @@ export interface AclEntry {
|
|
|
31
31
|
* unit via the authority projection (ADR-BE-169). Distinct from
|
|
32
32
|
* `unit_baseline` (which is membership-role-based) — delegations live on the
|
|
33
33
|
* `org_unit_authority_grants` table and carry an explicit scope set.
|
|
34
|
+
*
|
|
35
|
+
* `visibility` covers the general-access band (`private` | `unit` | `org` on
|
|
36
|
+
* the entity's `visibility` column) — the "General access" tier in the share
|
|
37
|
+
* dialog. `unit` grants viewer to everyone home-in or matrixed-into the owning
|
|
38
|
+
* unit's subtree (members ∪ contributors, flowing down); at the org root `unit`
|
|
39
|
+
* normalizes to org-wide. `org` grants viewer to every org member. This is a
|
|
40
|
+
* first-class source so the deterministic evaluator, the in-memory open gate,
|
|
41
|
+
* and the materialized grant-compiler all resolve the band identically. See
|
|
42
|
+
* ADR-CONTRACTS-075 and backend ADR-BE-374.
|
|
34
43
|
*/
|
|
35
44
|
export type AccessSource =
|
|
36
45
|
| "org_rbac"
|
|
37
46
|
| "sharing_policy"
|
|
47
|
+
| "visibility"
|
|
38
48
|
| "unit_baseline"
|
|
39
49
|
| "unit_delegation"
|
|
40
50
|
| "acl_grant"
|