@company-semantics/contracts 0.126.0 → 0.128.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 +1 -1
- package/schemas/repo-ci-result.schema.json +40 -0
- package/src/ci-results/index.ts +16 -0
- package/src/ci-results/repo-ci-result.ts +94 -0
- package/src/execution/index.ts +2 -0
- package/src/execution/schemas.ts +7 -0
- package/src/identity/index.ts +4 -0
- package/src/identity/schemas.ts +20 -0
- package/src/index.ts +15 -0
package/package.json
CHANGED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://company-semantics.dev/schemas/repo-ci-result.json",
|
|
4
|
+
"title": "RepoCiResult",
|
|
5
|
+
"description": "Per-repo result of a cross-repo CI health aggregation run (e.g. pnpm ci:all). Denormalized view of guard-result.schema.json: the top-level errors and warnings are scalar counts; guardResult is the full tiered detail. The scalars MUST equal the aggregated totals in guardResult.results when guardResult is present. Producers derive the scalars from guardResult, never the reverse.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["repo", "status", "errors", "warnings", "durationMs"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"repo": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"minLength": 1,
|
|
13
|
+
"description": "Sibling repo name without the company-semantics- prefix (e.g. 'backend', 'contracts')."
|
|
14
|
+
},
|
|
15
|
+
"status": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"enum": ["pass", "fail"],
|
|
18
|
+
"description": "pass when the repo's ci:local exited 0 and the guard artifact was produced; fail otherwise."
|
|
19
|
+
},
|
|
20
|
+
"errors": {
|
|
21
|
+
"type": "integer",
|
|
22
|
+
"minimum": 0,
|
|
23
|
+
"description": "Total errors across all guard tiers. MUST equal the sum of guardResult.results[tier].errors.length across all tiers when guardResult is present."
|
|
24
|
+
},
|
|
25
|
+
"warnings": {
|
|
26
|
+
"type": "integer",
|
|
27
|
+
"minimum": 0,
|
|
28
|
+
"description": "Total warnings across all guard tiers. MUST equal the sum of guardResult.results[tier].warnings.length across all tiers when guardResult is present."
|
|
29
|
+
},
|
|
30
|
+
"durationMs": {
|
|
31
|
+
"type": "integer",
|
|
32
|
+
"minimum": 0,
|
|
33
|
+
"description": "Wall-clock duration of the repo's ci:local run in milliseconds."
|
|
34
|
+
},
|
|
35
|
+
"guardResult": {
|
|
36
|
+
"$ref": "guard-result.schema.json",
|
|
37
|
+
"description": "Optional full guard orchestrator output for the repo. When present, errors and warnings MUST be derived from it."
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CI Results Vocabulary Barrel
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the per-repo cross-repo CI aggregation result vocabulary.
|
|
5
|
+
* Import from '@company-semantics/contracts/ci-results' or '@company-semantics/contracts'.
|
|
6
|
+
*
|
|
7
|
+
* @see ADR-CONT-033 for contracts boundary rationale
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type {
|
|
11
|
+
GuardTier,
|
|
12
|
+
GuardResultPayload,
|
|
13
|
+
RepoCiResult,
|
|
14
|
+
} from './repo-ci-result';
|
|
15
|
+
|
|
16
|
+
export { assertRepoCiResultConsistent } from './repo-ci-result';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RepoCiResult — per-repo result of a cross-repo CI health aggregation run.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors schemas/repo-ci-result.schema.json. The JSON schema is the source
|
|
5
|
+
* of truth; this file is the TypeScript projection.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type GuardTier =
|
|
9
|
+
| 'structural'
|
|
10
|
+
| 'behavioral'
|
|
11
|
+
| 'invariants'
|
|
12
|
+
| 'evolution'
|
|
13
|
+
| 'meta';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Minimal structural shape of a guard orchestrator result payload.
|
|
17
|
+
* The full shape is described by guard-result.schema.json; this is the
|
|
18
|
+
* subset assertRepoCiResultConsistent needs to cross-check against the
|
|
19
|
+
* RepoCiResult scalars.
|
|
20
|
+
*/
|
|
21
|
+
export interface GuardResultPayload {
|
|
22
|
+
readonly results: Readonly<
|
|
23
|
+
Record<
|
|
24
|
+
GuardTier,
|
|
25
|
+
{ readonly errors: readonly unknown[]; readonly warnings: readonly unknown[] }
|
|
26
|
+
>
|
|
27
|
+
>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Per-repo result of a cross-repo CI health aggregation run.
|
|
32
|
+
*
|
|
33
|
+
* Load-bearing invariant: when guardResult is present, errors and warnings
|
|
34
|
+
* MUST equal the aggregated counts across all tiers in guardResult.results.
|
|
35
|
+
* Producers derive the scalars from guardResult, never the reverse.
|
|
36
|
+
* Consumers can enforce this at runtime via assertRepoCiResultConsistent.
|
|
37
|
+
*/
|
|
38
|
+
export interface RepoCiResult {
|
|
39
|
+
/** Sibling repo name without the 'company-semantics-' prefix. */
|
|
40
|
+
readonly repo: string;
|
|
41
|
+
/** pass when ci:local exited 0 and the guard artifact was produced; fail otherwise. */
|
|
42
|
+
readonly status: 'pass' | 'fail';
|
|
43
|
+
/**
|
|
44
|
+
* Total errors across all guard tiers.
|
|
45
|
+
* MUST equal the sum of guardResult.results[tier].errors.length across
|
|
46
|
+
* all tiers when guardResult is present.
|
|
47
|
+
*/
|
|
48
|
+
readonly errors: number;
|
|
49
|
+
/**
|
|
50
|
+
* Total warnings across all guard tiers.
|
|
51
|
+
* MUST equal the sum of guardResult.results[tier].warnings.length across
|
|
52
|
+
* all tiers when guardResult is present.
|
|
53
|
+
*/
|
|
54
|
+
readonly warnings: number;
|
|
55
|
+
/** Wall-clock duration of ci:local in milliseconds. */
|
|
56
|
+
readonly durationMs: number;
|
|
57
|
+
/** Optional full guard orchestrator output. */
|
|
58
|
+
readonly guardResult?: GuardResultPayload;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const TIERS: readonly GuardTier[] = [
|
|
62
|
+
'structural',
|
|
63
|
+
'behavioral',
|
|
64
|
+
'invariants',
|
|
65
|
+
'evolution',
|
|
66
|
+
'meta',
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Throws when result.guardResult is present and its aggregated tier counts
|
|
71
|
+
* do not match result.errors / result.warnings. Enforces the load-bearing
|
|
72
|
+
* derivation invariant of the RepoCiResult contract at runtime.
|
|
73
|
+
*/
|
|
74
|
+
export function assertRepoCiResultConsistent(result: RepoCiResult): void {
|
|
75
|
+
if (!result.guardResult) return;
|
|
76
|
+
let errorSum = 0;
|
|
77
|
+
let warningSum = 0;
|
|
78
|
+
for (const tier of TIERS) {
|
|
79
|
+
const tierResult = result.guardResult.results[tier];
|
|
80
|
+
if (!tierResult) continue;
|
|
81
|
+
errorSum += tierResult.errors.length;
|
|
82
|
+
warningSum += tierResult.warnings.length;
|
|
83
|
+
}
|
|
84
|
+
if (errorSum !== result.errors) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`RepoCiResult invariant violation: repo=${result.repo} errors=${result.errors} but guardResult aggregates to ${errorSum}`,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
if (warningSum !== result.warnings) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`RepoCiResult invariant violation: repo=${result.repo} warnings=${result.warnings} but guardResult aggregates to ${warningSum}`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
package/src/execution/index.ts
CHANGED
|
@@ -157,6 +157,7 @@ export {
|
|
|
157
157
|
ExecutionTimelineResponseSchema,
|
|
158
158
|
ConfirmExecutionResponseSchema,
|
|
159
159
|
RejectExecutionResponseSchema,
|
|
160
|
+
StartExecutionResponseSchema,
|
|
160
161
|
} from './schemas'
|
|
161
162
|
|
|
162
163
|
export type {
|
|
@@ -166,4 +167,5 @@ export type {
|
|
|
166
167
|
ExecutionTimelineResponse,
|
|
167
168
|
ConfirmExecutionResponse,
|
|
168
169
|
RejectExecutionResponse,
|
|
170
|
+
StartExecutionResponse,
|
|
169
171
|
} from './schemas'
|
package/src/execution/schemas.ts
CHANGED
|
@@ -93,3 +93,10 @@ export const RejectExecutionResponseSchema = z.object({
|
|
|
93
93
|
})
|
|
94
94
|
|
|
95
95
|
export type RejectExecutionResponse = z.infer<typeof RejectExecutionResponseSchema>
|
|
96
|
+
|
|
97
|
+
export const StartExecutionResponseSchema = z.object({
|
|
98
|
+
executionId: z.string().uuid(),
|
|
99
|
+
redirectUrl: z.string().optional(),
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
export type StartExecutionResponse = z.infer<typeof StartExecutionResponseSchema>
|
package/src/identity/index.ts
CHANGED
|
@@ -42,6 +42,8 @@ export {
|
|
|
42
42
|
AccountDeleteResponseSchema,
|
|
43
43
|
AccountConfirmDeletionResponseSchema,
|
|
44
44
|
AccountCancelDeletionResponseSchema,
|
|
45
|
+
BannerDismissedListResponseSchema,
|
|
46
|
+
BannerDismissResponseSchema,
|
|
45
47
|
} from './schemas';
|
|
46
48
|
export type {
|
|
47
49
|
MeResponse,
|
|
@@ -55,4 +57,6 @@ export type {
|
|
|
55
57
|
AccountDeleteResponse,
|
|
56
58
|
AccountConfirmDeletionResponse,
|
|
57
59
|
AccountCancelDeletionResponse,
|
|
60
|
+
BannerDismissedListResponse,
|
|
61
|
+
BannerDismissResponse,
|
|
58
62
|
} from './schemas';
|
package/src/identity/schemas.ts
CHANGED
|
@@ -222,3 +222,23 @@ export const AccountCancelDeletionResponseSchema = z.object({
|
|
|
222
222
|
});
|
|
223
223
|
|
|
224
224
|
export type AccountCancelDeletionResponse = z.infer<typeof AccountCancelDeletionResponseSchema>;
|
|
225
|
+
|
|
226
|
+
// ---------------------------------------------------------------------------
|
|
227
|
+
// GET /api/user/preferences/dismissed-banners
|
|
228
|
+
// ---------------------------------------------------------------------------
|
|
229
|
+
|
|
230
|
+
export const BannerDismissedListResponseSchema = z.object({
|
|
231
|
+
bannerIds: z.array(z.string()),
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
export type BannerDismissedListResponse = z.infer<typeof BannerDismissedListResponseSchema>;
|
|
235
|
+
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
// POST /api/user/preferences/dismissed-banners/:bannerId
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
|
|
240
|
+
export const BannerDismissResponseSchema = z.object({
|
|
241
|
+
success: z.literal(true),
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
export type BannerDismissResponse = z.infer<typeof BannerDismissResponseSchema>;
|
package/src/index.ts
CHANGED
|
@@ -98,6 +98,17 @@ export {
|
|
|
98
98
|
SOC2_SCHEMA_VERSION,
|
|
99
99
|
} from './guards/index'
|
|
100
100
|
|
|
101
|
+
// Cross-repo CI aggregation vocabulary
|
|
102
|
+
// @see ADR-CONT-033 for contracts boundary rationale
|
|
103
|
+
// Note: GuardTier is already exported above from './guards/index' (structurally
|
|
104
|
+
// identical); not re-exported here to avoid a duplicate-identifier collision.
|
|
105
|
+
export type {
|
|
106
|
+
GuardResultPayload,
|
|
107
|
+
RepoCiResult,
|
|
108
|
+
} from './ci-results/index'
|
|
109
|
+
|
|
110
|
+
export { assertRepoCiResultConsistent } from './ci-results/index'
|
|
111
|
+
|
|
101
112
|
// Compatibility manifest (CI guard vocabulary)
|
|
102
113
|
// @see ADR-2025-12-011 for design rationale
|
|
103
114
|
export { COMPATIBILITY } from './compatibility'
|
|
@@ -133,6 +144,8 @@ export {
|
|
|
133
144
|
AccountDeleteResponseSchema,
|
|
134
145
|
AccountConfirmDeletionResponseSchema,
|
|
135
146
|
AccountCancelDeletionResponseSchema,
|
|
147
|
+
BannerDismissedListResponseSchema,
|
|
148
|
+
BannerDismissResponseSchema,
|
|
136
149
|
} from './identity/index'
|
|
137
150
|
export type {
|
|
138
151
|
MeResponse,
|
|
@@ -145,6 +158,8 @@ export type {
|
|
|
145
158
|
AccountDeleteResponse,
|
|
146
159
|
AccountConfirmDeletionResponse,
|
|
147
160
|
AccountCancelDeletionResponse,
|
|
161
|
+
BannerDismissedListResponse,
|
|
162
|
+
BannerDismissResponse,
|
|
148
163
|
} from './identity/index'
|
|
149
164
|
|
|
150
165
|
// Auth domain types
|