@opensoftware/contracts 1.4.0 → 1.6.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/README.md +13 -2
- package/dist/formats.js +2 -0
- package/dist/formats.js.map +1 -1
- package/dist/generated/types.d.ts +258 -2
- package/dist/index.d.ts +6 -1
- package/dist/index.js.map +1 -1
- package/gate-record/gate-record.schema.json +140 -0
- package/openapi/openapi.json +466 -3
- package/package.json +5 -2
- package/sandbox-spec/sandbox-spec.schema.json +90 -0
- package/typespec/gatekeeper-api.tsp +39 -0
- package/typespec/gatekeeper.tsp +134 -0
- package/typespec/main.tsp +3 -0
- package/typespec/sandbox.tsp +63 -0
package/README.md
CHANGED
|
@@ -42,8 +42,18 @@ Each format has one schema, generated from `typespec/`, and fixtures that CONTRA
|
|
|
42
42
|
| run record | `run-record/run-record.schema.json` | `RunRecord` | OTel resource and root-span attributes; pins in `typespec/run-record.tsp`. |
|
|
43
43
|
| evidence bundle | `evidence-bundle/evidence-bundle.schema.json` | `EvidenceManifest` | `evidence.json` at the bundle root. |
|
|
44
44
|
| score | `score/score.schema.json` | `Score` | Subset of Langfuse's create-score request; factory fields in `metadata`. |
|
|
45
|
+
| gate record | `gate-record/gate-record.schema.json` | `GateRecord` | gatekeeper's signed approval record (ADR 0047). |
|
|
46
|
+
| sandbox spec | `sandbox-spec/sandbox-spec.schema.json` | `SandboxSpec` | The input of a sandbox adapter's `create` (ADR 0054). Closed objects: an unknown field is an error. |
|
|
45
47
|
| events | `events/<event>/<event>.schema.json`, `events/asyncapi.yaml` | `WorkReceived` … `PrClosed` | CloudEvents 1.0, structured JSON. |
|
|
46
48
|
|
|
49
|
+
## HTTP APIs
|
|
50
|
+
|
|
51
|
+
`openapi/openapi.json` also holds the paths of the module APIs, from the operations in `typespec/` (ADR 0048). The
|
|
52
|
+
first is gatekeeper's: `POST /v1/gates` and `GET /v1/gates/{gateId}` with the models `GateRequest`, `GateView` and
|
|
53
|
+
`ApiProblem` (RFC 9457). `pnpm build` compiles the operations with the TypeSpec OpenAPI 3 emitter and copies their
|
|
54
|
+
paths next to the named models; an operation that uses a type that is no model fails the build. The package exports
|
|
55
|
+
the type `paths`, which types a client such as openapi-fetch.
|
|
56
|
+
|
|
47
57
|
Wire formats (everything but the factory definition) are open: readers ignore fields they do not know, so a minor
|
|
48
58
|
version may add optional fields. Read `factory.yaml` with a YAML 1.2 parser: YAML 1.1 parsers turn the key `on`
|
|
49
59
|
into `true`.
|
|
@@ -71,8 +81,9 @@ release-please opens a release pull request from the Conventional Commits under
|
|
|
71
81
|
the tag `contracts-v<version>`. The release pull request also sets the version in `openapi/openapi.json`, which
|
|
72
82
|
`pnpm build` copies from `package.json`, so the generated file stays current. The workflow `.github/workflows/publish-contracts.yml` then builds the package and
|
|
73
83
|
publishes it to npm as `@opensoftware/contracts`. npm accepts a provenance statement only from a public
|
|
74
|
-
repository, so the workflow adds one only when this repository is public.
|
|
75
|
-
|
|
84
|
+
repository, so the workflow adds one only when this repository is public. When the newest tag is missing on npm,
|
|
85
|
+
for example after a failed upload, the next run of the workflow on `main` publishes it. To publish a tag again, run
|
|
86
|
+
the workflow by hand with the tag. The CONTRACT check and `osf-contracts breaking` compare with the newest `contracts-v*` tag.
|
|
76
87
|
|
|
77
88
|
Only the TypeScript package exists (ADR 0012). A client for another language can be generated from
|
|
78
89
|
`openapi/openapi.json` with any OpenAPI generator when someone needs one.
|
package/dist/formats.js
CHANGED
|
@@ -6,6 +6,8 @@ export const FORMATS = [
|
|
|
6
6
|
format("run-record", "RunRecord"),
|
|
7
7
|
format("evidence-bundle", "EvidenceManifest"),
|
|
8
8
|
format("score", "Score"),
|
|
9
|
+
format("gate-record", "GateRecord"),
|
|
10
|
+
format("sandbox-spec", "SandboxSpec"),
|
|
9
11
|
format("events/work-received", "WorkReceived"),
|
|
10
12
|
format("events/run-completed", "RunCompleted"),
|
|
11
13
|
format("events/gate-requested", "GateRequested"),
|
package/dist/formats.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formats.js","sourceRoot":"","sources":["../src/formats.ts"],"names":[],"mappings":"AAAA,2GAA2G;AAW3G,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,KAAa,EAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAY,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAEjH,MAAM,CAAC,MAAM,OAAO,GAAsB;IACxC,MAAM,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;IACjD,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC;IAC/B,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC;IACjC,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;IAC7C,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,sBAAsB,EAAE,cAAc,CAAC;IAC9C,MAAM,CAAC,sBAAsB,EAAE,cAAc,CAAC;IAC9C,MAAM,CAAC,uBAAuB,EAAE,eAAe,CAAC;IAChD,MAAM,CAAC,qBAAqB,EAAE,aAAa,CAAC;IAC5C,MAAM,CAAC,uBAAuB,EAAE,eAAe,CAAC;IAChD,MAAM,CAAC,kBAAkB,EAAE,UAAU,CAAC;IACtC,MAAM,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAC1C,MAAM,CAAC,kBAAkB,EAAE,UAAU,CAAC;CACvC,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC9D,CAAC"}
|
|
1
|
+
{"version":3,"file":"formats.js","sourceRoot":"","sources":["../src/formats.ts"],"names":[],"mappings":"AAAA,2GAA2G;AAW3G,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,KAAa,EAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAY,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAEjH,MAAM,CAAC,MAAM,OAAO,GAAsB;IACxC,MAAM,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;IACjD,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC;IAC/B,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC;IACjC,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;IAC7C,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC;IACnC,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC;IACrC,MAAM,CAAC,sBAAsB,EAAE,cAAc,CAAC;IAC9C,MAAM,CAAC,sBAAsB,EAAE,cAAc,CAAC;IAC9C,MAAM,CAAC,uBAAuB,EAAE,eAAe,CAAC;IAChD,MAAM,CAAC,qBAAqB,EAAE,aAAa,CAAC;IAC5C,MAAM,CAAC,uBAAuB,EAAE,eAAe,CAAC;IAChD,MAAM,CAAC,kBAAkB,EAAE,UAAU,CAAC;IACtC,MAAM,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAC1C,MAAM,CAAC,kBAAkB,EAAE,UAAU,CAAC;CACvC,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -1,4 +1,39 @@
|
|
|
1
|
-
export type paths =
|
|
1
|
+
export type paths = {
|
|
2
|
+
"/v1/gates": {
|
|
3
|
+
parameters: {
|
|
4
|
+
query?: never;
|
|
5
|
+
header?: never;
|
|
6
|
+
path?: never;
|
|
7
|
+
cookie?: never;
|
|
8
|
+
};
|
|
9
|
+
get?: never;
|
|
10
|
+
put?: never;
|
|
11
|
+
/** @description Ask the policy's approver groups for a decision. The same request again answers the gate it made before. */
|
|
12
|
+
post: operations["GatekeeperApi_requestGate"];
|
|
13
|
+
delete?: never;
|
|
14
|
+
options?: never;
|
|
15
|
+
head?: never;
|
|
16
|
+
patch?: never;
|
|
17
|
+
trace?: never;
|
|
18
|
+
};
|
|
19
|
+
"/v1/gates/{gateId}": {
|
|
20
|
+
parameters: {
|
|
21
|
+
query?: never;
|
|
22
|
+
header?: never;
|
|
23
|
+
path?: never;
|
|
24
|
+
cookie?: never;
|
|
25
|
+
};
|
|
26
|
+
/** @description A gate: its state, and its record once it is decided. */
|
|
27
|
+
get: operations["GatekeeperApi_getGate"];
|
|
28
|
+
put?: never;
|
|
29
|
+
post?: never;
|
|
30
|
+
delete?: never;
|
|
31
|
+
options?: never;
|
|
32
|
+
head?: never;
|
|
33
|
+
patch?: never;
|
|
34
|
+
trace?: never;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
2
37
|
export type webhooks = Record<string, never>;
|
|
3
38
|
export type components = {
|
|
4
39
|
schemas: {
|
|
@@ -33,6 +68,15 @@ export type components = {
|
|
|
33
68
|
/** @description Runtime of the agent. */
|
|
34
69
|
sandbox?: components["schemas"]["Sandbox"];
|
|
35
70
|
};
|
|
71
|
+
/** @description An error of an HTTP API (RFC 9457). */
|
|
72
|
+
ApiProblem: {
|
|
73
|
+
/** @description A short summary, the same for every occurrence of the problem. */
|
|
74
|
+
title: string;
|
|
75
|
+
/** @description The HTTP status code. */
|
|
76
|
+
status: number;
|
|
77
|
+
/** @description What went wrong this time, for example the field that is missing. */
|
|
78
|
+
detail?: string;
|
|
79
|
+
};
|
|
36
80
|
Artifact: {
|
|
37
81
|
path: components["schemas"]["BundlePath"];
|
|
38
82
|
kind: components["schemas"]["ArtifactKind"];
|
|
@@ -172,6 +216,47 @@ export type components = {
|
|
|
172
216
|
};
|
|
173
217
|
/** @enum {string} */
|
|
174
218
|
GateDecision: "approved" | "rejected" | "expired";
|
|
219
|
+
/** @description gatekeeper: who decided what and when, signed with Ed25519 (ADR 0047). */
|
|
220
|
+
GateRecord: {
|
|
221
|
+
gate: string;
|
|
222
|
+
workItem: string;
|
|
223
|
+
stage: components["schemas"]["Name"];
|
|
224
|
+
summary: string;
|
|
225
|
+
/** @description SHA-256 of the canonical request: what was approved. */
|
|
226
|
+
request: string;
|
|
227
|
+
/** @description The policy file. */
|
|
228
|
+
policy: string;
|
|
229
|
+
/** @description SHA-256 of the policy's text: the rules that picked the approvers. */
|
|
230
|
+
policyDigest: string;
|
|
231
|
+
risk?: string;
|
|
232
|
+
approvers: components["schemas"]["Name"][];
|
|
233
|
+
channel: string;
|
|
234
|
+
/** Format: date-time */
|
|
235
|
+
requestedAt: string;
|
|
236
|
+
decision: components["schemas"]["GateDecision"];
|
|
237
|
+
/** @description Who decided. Absent only when the gate expired. A policy that names no group decides as a trigger. */
|
|
238
|
+
decidedBy?: components["schemas"]["Actor"];
|
|
239
|
+
/** Format: date-time */
|
|
240
|
+
decidedAt: string;
|
|
241
|
+
/** @description The reason of a rejection. */
|
|
242
|
+
reason?: string;
|
|
243
|
+
/** @description Ed25519 over the canonical JSON of the rest of the record. Absent when the record is unsigned. */
|
|
244
|
+
signature?: components["schemas"]["RecordSignature"];
|
|
245
|
+
};
|
|
246
|
+
/** @description gatekeeper: what a person is asked to approve, and the facts the policy decides on (ADR 0047). */
|
|
247
|
+
GateRequest: {
|
|
248
|
+
/** @description What waits: a work item ID or a URL. */
|
|
249
|
+
workItem: string;
|
|
250
|
+
/** @description The stage that waits, for example "merge". */
|
|
251
|
+
stage: components["schemas"]["Name"];
|
|
252
|
+
/** @description What the approvers decide, shown in the channel. */
|
|
253
|
+
summary: string;
|
|
254
|
+
links?: components["schemas"]["Link"][];
|
|
255
|
+
/** @description Any facts the policy needs, such as changed paths, labels or the author. */
|
|
256
|
+
change?: {
|
|
257
|
+
[key: string]: unknown;
|
|
258
|
+
};
|
|
259
|
+
};
|
|
175
260
|
/** @description gatekeeper: a decision is needed before a stage starts. */
|
|
176
261
|
GateRequested: {
|
|
177
262
|
/** @constant */
|
|
@@ -210,6 +295,41 @@ export type components = {
|
|
|
210
295
|
/** Format: date-time */
|
|
211
296
|
expiresAt?: string;
|
|
212
297
|
};
|
|
298
|
+
/**
|
|
299
|
+
* @description A gate's state: waiting, or how it was decided.
|
|
300
|
+
* @enum {string}
|
|
301
|
+
*/
|
|
302
|
+
GateState: "pending" | "approved" | "rejected" | "expired";
|
|
303
|
+
/** @description gatekeeper: a gate as the HTTP API shows it (ADR 0048). */
|
|
304
|
+
GateView: {
|
|
305
|
+
/** @description "g" and 16 hex digits of the SHA-256 of the work item, the stage and the change. */
|
|
306
|
+
id: string;
|
|
307
|
+
workItem: string;
|
|
308
|
+
stage: components["schemas"]["Name"];
|
|
309
|
+
summary: string;
|
|
310
|
+
/** @description The risk the policy named, for example "high". */
|
|
311
|
+
risk?: string;
|
|
312
|
+
/** @description The groups whose members may decide. Empty when the policy approved without a person. */
|
|
313
|
+
approvers: components["schemas"]["Name"][];
|
|
314
|
+
/** @description The groups asked after the escalation time. */
|
|
315
|
+
escalateTo?: components["schemas"]["Name"][];
|
|
316
|
+
/** @description Where people decide, for example "slack:C0GATES". */
|
|
317
|
+
channel: string;
|
|
318
|
+
state: components["schemas"]["GateState"];
|
|
319
|
+
/** @description The groups that may decide now. Only while the gate is pending. */
|
|
320
|
+
waitingFor?: components["schemas"]["Name"][];
|
|
321
|
+
/** Format: date-time */
|
|
322
|
+
requestedAt: string;
|
|
323
|
+
/**
|
|
324
|
+
* Format: date-time
|
|
325
|
+
* @description When the gate expires without a decision.
|
|
326
|
+
*/
|
|
327
|
+
expiresAt?: string;
|
|
328
|
+
/** @description The record, once the gate is decided. */
|
|
329
|
+
record?: components["schemas"]["GateRecord"];
|
|
330
|
+
};
|
|
331
|
+
/** @description A hostname without scheme or port, for example "api.linear.app". */
|
|
332
|
+
Hostname: string;
|
|
213
333
|
/** @description An identifier chosen by the producer. ULIDs are recommended; consumers treat it as opaque. */
|
|
214
334
|
Identifier: string;
|
|
215
335
|
Link: {
|
|
@@ -367,6 +487,14 @@ export type components = {
|
|
|
367
487
|
[key: string]: components["schemas"]["VersionRange"];
|
|
368
488
|
};
|
|
369
489
|
};
|
|
490
|
+
RecordSignature: {
|
|
491
|
+
/** @constant */
|
|
492
|
+
algorithm: "Ed25519";
|
|
493
|
+
/** @description SHA-256 of the public key in DER, like "sha256:…". */
|
|
494
|
+
key: string;
|
|
495
|
+
/** @description The signature in base64. */
|
|
496
|
+
value: string;
|
|
497
|
+
};
|
|
370
498
|
/** @enum {string} */
|
|
371
499
|
ReviewState: "approved" | "changes_requested" | "commented";
|
|
372
500
|
/** @description foreman: a run ended. */
|
|
@@ -485,6 +613,42 @@ export type components = {
|
|
|
485
613
|
/** @description Hostnames the sandbox may reach. Everything else is blocked. */
|
|
486
614
|
egress?: string[];
|
|
487
615
|
};
|
|
616
|
+
/** @description An MCP server that a sandbox may call over Streamable HTTP. */
|
|
617
|
+
SandboxMcpServer: {
|
|
618
|
+
/** @description The name in the egress log, for example "wiki". */
|
|
619
|
+
name: components["schemas"]["Name"];
|
|
620
|
+
/** @description The server's endpoint, for example "https://wiki.example.com/mcp". */
|
|
621
|
+
url: string;
|
|
622
|
+
/** @description The tools the sandbox may call. A call to any other tool is refused. */
|
|
623
|
+
tools: string[];
|
|
624
|
+
};
|
|
625
|
+
/**
|
|
626
|
+
* @description The input of a sandbox adapter's `create` (ADR 0054): what one sandbox runs, how much it may use, and what it may
|
|
627
|
+
* reach. Realizes SCN-FACTORY-RUNTIME-004, -006 and -007.
|
|
628
|
+
*/
|
|
629
|
+
SandboxSpec: {
|
|
630
|
+
/** @description What the sandbox starts from: an image for the docker adapter, a SandboxTemplate for kubernetes, or a snapshot. */
|
|
631
|
+
template: string;
|
|
632
|
+
/** @description CPU cores. The smallest unit is 0.001 (one millicore). */
|
|
633
|
+
cpu?: number;
|
|
634
|
+
/** @description Kubernetes quantity, for example "8Gi". */
|
|
635
|
+
memory?: string;
|
|
636
|
+
/** @description Hostnames the sandbox may reach through its egress proxy. Everything else is refused. */
|
|
637
|
+
egress?: components["schemas"]["Hostname"][];
|
|
638
|
+
/** @description Variables of the sandbox's environment that hold no secret. */
|
|
639
|
+
env?: {
|
|
640
|
+
[key: string]: string;
|
|
641
|
+
};
|
|
642
|
+
/**
|
|
643
|
+
* @description Secrets by the name of the variable that holds the placeholder in the sandbox. The egress proxy puts the real
|
|
644
|
+
* value in on the way out, for the hosts of `egress`.
|
|
645
|
+
*/
|
|
646
|
+
secrets?: {
|
|
647
|
+
[key: string]: components["schemas"]["SecretReference"];
|
|
648
|
+
};
|
|
649
|
+
/** @description The MCP servers the sandbox may call. A call to any other MCP server is refused. */
|
|
650
|
+
mcp?: components["schemas"]["SandboxMcpServer"][];
|
|
651
|
+
};
|
|
488
652
|
ScenarioEvidence: {
|
|
489
653
|
id: components["schemas"]["ScenarioId"];
|
|
490
654
|
result: components["schemas"]["ScenarioResult"];
|
|
@@ -633,4 +797,96 @@ export type components = {
|
|
|
633
797
|
pathItems: never;
|
|
634
798
|
};
|
|
635
799
|
export type $defs = Record<string, never>;
|
|
636
|
-
export
|
|
800
|
+
export interface operations {
|
|
801
|
+
GatekeeperApi_requestGate: {
|
|
802
|
+
parameters: {
|
|
803
|
+
query?: never;
|
|
804
|
+
header?: never;
|
|
805
|
+
path?: never;
|
|
806
|
+
cookie?: never;
|
|
807
|
+
};
|
|
808
|
+
requestBody: {
|
|
809
|
+
content: {
|
|
810
|
+
"application/json": components["schemas"]["GateRequest"];
|
|
811
|
+
};
|
|
812
|
+
};
|
|
813
|
+
responses: {
|
|
814
|
+
/** @description The request has succeeded. */
|
|
815
|
+
200: {
|
|
816
|
+
headers: {
|
|
817
|
+
[name: string]: unknown;
|
|
818
|
+
};
|
|
819
|
+
content: {
|
|
820
|
+
"application/json": components["schemas"]["GateView"];
|
|
821
|
+
};
|
|
822
|
+
};
|
|
823
|
+
/** @description The request has succeeded and a new resource has been created as a result. */
|
|
824
|
+
201: {
|
|
825
|
+
headers: {
|
|
826
|
+
[name: string]: unknown;
|
|
827
|
+
};
|
|
828
|
+
content: {
|
|
829
|
+
"application/json": components["schemas"]["GateView"];
|
|
830
|
+
};
|
|
831
|
+
};
|
|
832
|
+
/** @description The server could not understand the request due to invalid syntax. */
|
|
833
|
+
400: {
|
|
834
|
+
headers: {
|
|
835
|
+
[name: string]: unknown;
|
|
836
|
+
};
|
|
837
|
+
content: {
|
|
838
|
+
"application/problem+json": components["schemas"]["ApiProblem"];
|
|
839
|
+
};
|
|
840
|
+
};
|
|
841
|
+
/** @description Access is unauthorized. */
|
|
842
|
+
401: {
|
|
843
|
+
headers: {
|
|
844
|
+
[name: string]: unknown;
|
|
845
|
+
};
|
|
846
|
+
content: {
|
|
847
|
+
"application/problem+json": components["schemas"]["ApiProblem"];
|
|
848
|
+
};
|
|
849
|
+
};
|
|
850
|
+
};
|
|
851
|
+
};
|
|
852
|
+
GatekeeperApi_getGate: {
|
|
853
|
+
parameters: {
|
|
854
|
+
query?: never;
|
|
855
|
+
header?: never;
|
|
856
|
+
path: {
|
|
857
|
+
gateId: string;
|
|
858
|
+
};
|
|
859
|
+
cookie?: never;
|
|
860
|
+
};
|
|
861
|
+
requestBody?: never;
|
|
862
|
+
responses: {
|
|
863
|
+
/** @description The request has succeeded. */
|
|
864
|
+
200: {
|
|
865
|
+
headers: {
|
|
866
|
+
[name: string]: unknown;
|
|
867
|
+
};
|
|
868
|
+
content: {
|
|
869
|
+
"application/json": components["schemas"]["GateView"];
|
|
870
|
+
};
|
|
871
|
+
};
|
|
872
|
+
/** @description Access is unauthorized. */
|
|
873
|
+
401: {
|
|
874
|
+
headers: {
|
|
875
|
+
[name: string]: unknown;
|
|
876
|
+
};
|
|
877
|
+
content: {
|
|
878
|
+
"application/problem+json": components["schemas"]["ApiProblem"];
|
|
879
|
+
};
|
|
880
|
+
};
|
|
881
|
+
/** @description The server cannot find the requested resource. */
|
|
882
|
+
404: {
|
|
883
|
+
headers: {
|
|
884
|
+
[name: string]: unknown;
|
|
885
|
+
};
|
|
886
|
+
content: {
|
|
887
|
+
"application/problem+json": components["schemas"]["ApiProblem"];
|
|
888
|
+
};
|
|
889
|
+
};
|
|
890
|
+
};
|
|
891
|
+
};
|
|
892
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type Format } from "./formats.ts";
|
|
|
2
2
|
import type { components } from "./generated/types.ts";
|
|
3
3
|
export { diff as breakingChanges, type Schema } from "./breaking.ts";
|
|
4
4
|
export { FORMATS, type Format, formatNamed } from "./formats.ts";
|
|
5
|
-
export type { components } from "./generated/types.ts";
|
|
5
|
+
export type { components, paths } from "./generated/types.ts";
|
|
6
6
|
export { type AttributeValue, type RunSpan, runSpans, type SpanAttributes } from "./run-record.ts";
|
|
7
7
|
type Schemas = components["schemas"];
|
|
8
8
|
export type FactoryDefinition = Schemas["FactoryDefinition"];
|
|
@@ -18,6 +18,11 @@ export type ScoreRecorded = Schemas["ScoreRecorded"];
|
|
|
18
18
|
export type PrOpened = Schemas["PrOpened"];
|
|
19
19
|
export type PrReviewed = Schemas["PrReviewed"];
|
|
20
20
|
export type PrClosed = Schemas["PrClosed"];
|
|
21
|
+
export type GateRecord = Schemas["GateRecord"];
|
|
22
|
+
export type GateRequest = Schemas["GateRequest"];
|
|
23
|
+
export type GateView = Schemas["GateView"];
|
|
24
|
+
export type ApiProblem = Schemas["ApiProblem"];
|
|
25
|
+
export type SandboxSpec = Schemas["SandboxSpec"];
|
|
21
26
|
/** One reason a document does not match its format. `path` is a JSON Pointer into the document. */
|
|
22
27
|
export interface Problem {
|
|
23
28
|
path: string;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oHAAoH;AACpH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,OAAO,EAAE,EAA2C,MAAM,kBAAkB,CAAC;AACpF,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,EAAe,WAAW,EAAE,MAAM,cAAc,CAAC;AAGxD,OAAO,EAAE,IAAI,IAAI,eAAe,EAAe,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,OAAO,EAAe,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjE,OAAO,EAAqC,QAAQ,EAAuB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oHAAoH;AACpH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,OAAO,EAAE,EAA2C,MAAM,kBAAkB,CAAC;AACpF,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,EAAe,WAAW,EAAE,MAAM,cAAc,CAAC;AAGxD,OAAO,EAAE,IAAI,IAAI,eAAe,EAAe,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,OAAO,EAAe,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjE,OAAO,EAAqC,QAAQ,EAAuB,MAAM,iBAAiB,CAAC;AA4BnG,gGAAgG;AAChG,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACjE,MAAM,UAAU,GAAG,IAAI,GAAG,EAA4B,CAAC;AAEvD,gFAAgF;AAChF,MAAM,UAAU,QAAQ,CAAC,MAAuB;IAC9C,MAAM,KAAK,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACxE,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACjE,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,cAAc,CAAC,EAAE,MAAM,CAAC,CAG1F,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,QAAQ,CAAC,MAAuB,EAAE,QAAiB;IACjE,MAAM,IAAI,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;IAC/D,IAAI,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,2FAA2F;QAC3F,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1F,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACxB,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACtC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,OAAO,CAAI,MAAuB,EAAE,QAAiB;IACnE,OAAO,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAEjD,iHAAiH;AACjH,SAAS,QAAQ,CAAC,MAAqB;IACrC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAClH,MAAM,iBAAiB,GAAG,CAAC,KAAkB,EAAW,EAAE,CACxD,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;QAChC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;QAC1C,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,KAAK,IAAI,IAAI,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;IACxG,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,iBAAiB,CAAC,KAAK,CAAC;YAAE,SAAS;QACvC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACjD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,QAAQ,CAAC,KAAkB;IAClC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,GAAG,KAAK,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;IACpH,QAAQ,KAAK,CAAC,OAAO,EAAE,CAAC;QACtB,KAAK,sBAAsB;YACzB,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;QAC5F,KAAK,uBAAuB;YAC1B,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;QAC7F,KAAK,UAAU;YACb,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC;QAClG,KAAK,OAAO,CAAC;QACb,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,YAAY,IAAI,GAAG,EAAE,OAAO,EAAE,6CAA6C,EAAE,CAAC;QACrG;YACE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,YAAY,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;IACxF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/sesigl/open-software-factory/main/contracts/gate-record/gate-record.schema.json",
|
|
4
|
+
"title": "GateRecord",
|
|
5
|
+
"$comment": "Generated by `pnpm build` in contracts/ from typespec/. Do not edit.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"gate": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"pattern": "^g[0-9a-f]{16}$"
|
|
11
|
+
},
|
|
12
|
+
"workItem": {
|
|
13
|
+
"type": "string"
|
|
14
|
+
},
|
|
15
|
+
"stage": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"pattern": "^[a-z][a-z0-9-]{0,62}$",
|
|
18
|
+
"description": "A lowercase name: letters, digits and hyphens, starting with a letter. Agents, stages, adapters, sources."
|
|
19
|
+
},
|
|
20
|
+
"summary": {
|
|
21
|
+
"type": "string"
|
|
22
|
+
},
|
|
23
|
+
"request": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"pattern": "^sha256:[0-9a-f]{64}$",
|
|
26
|
+
"description": "SHA-256 of the canonical request: what was approved."
|
|
27
|
+
},
|
|
28
|
+
"policy": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"minLength": 1,
|
|
31
|
+
"description": "The policy file."
|
|
32
|
+
},
|
|
33
|
+
"policyDigest": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"pattern": "^sha256:[0-9a-f]{64}$",
|
|
36
|
+
"description": "SHA-256 of the policy's text: the rules that picked the approvers."
|
|
37
|
+
},
|
|
38
|
+
"risk": {
|
|
39
|
+
"type": "string"
|
|
40
|
+
},
|
|
41
|
+
"approvers": {
|
|
42
|
+
"type": "array",
|
|
43
|
+
"items": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"pattern": "^[a-z][a-z0-9-]{0,62}$",
|
|
46
|
+
"description": "A lowercase name: letters, digits and hyphens, starting with a letter. Agents, stages, adapters, sources."
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"channel": {
|
|
50
|
+
"type": "string"
|
|
51
|
+
},
|
|
52
|
+
"requestedAt": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"format": "date-time"
|
|
55
|
+
},
|
|
56
|
+
"decision": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"enum": [
|
|
59
|
+
"approved",
|
|
60
|
+
"rejected",
|
|
61
|
+
"expired"
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"decidedBy": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"properties": {
|
|
67
|
+
"kind": {
|
|
68
|
+
"type": "string",
|
|
69
|
+
"enum": [
|
|
70
|
+
"person",
|
|
71
|
+
"trigger"
|
|
72
|
+
],
|
|
73
|
+
"description": "Who caused something: a person, or an automated trigger such as a cron rule or an alert."
|
|
74
|
+
},
|
|
75
|
+
"id": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"minLength": 1,
|
|
78
|
+
"description": "Stable ID in the source system, prefixed with the source, for example \"slack:U024BE7LH\"."
|
|
79
|
+
},
|
|
80
|
+
"displayName": {
|
|
81
|
+
"type": "string",
|
|
82
|
+
"description": "Shown to people, for example \"Varun\"."
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"required": [
|
|
86
|
+
"kind",
|
|
87
|
+
"id"
|
|
88
|
+
],
|
|
89
|
+
"description": "Who decided. Absent only when the gate expired. A policy that names no group decides as a trigger."
|
|
90
|
+
},
|
|
91
|
+
"decidedAt": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"format": "date-time"
|
|
94
|
+
},
|
|
95
|
+
"reason": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"description": "The reason of a rejection."
|
|
98
|
+
},
|
|
99
|
+
"signature": {
|
|
100
|
+
"type": "object",
|
|
101
|
+
"properties": {
|
|
102
|
+
"algorithm": {
|
|
103
|
+
"type": "string",
|
|
104
|
+
"const": "Ed25519"
|
|
105
|
+
},
|
|
106
|
+
"key": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"pattern": "^sha256:",
|
|
109
|
+
"description": "SHA-256 of the public key in DER, like \"sha256:…\"."
|
|
110
|
+
},
|
|
111
|
+
"value": {
|
|
112
|
+
"type": "string",
|
|
113
|
+
"minLength": 1,
|
|
114
|
+
"description": "The signature in base64."
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"required": [
|
|
118
|
+
"algorithm",
|
|
119
|
+
"key",
|
|
120
|
+
"value"
|
|
121
|
+
],
|
|
122
|
+
"description": "Ed25519 over the canonical JSON of the rest of the record. Absent when the record is unsigned."
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"required": [
|
|
126
|
+
"gate",
|
|
127
|
+
"workItem",
|
|
128
|
+
"stage",
|
|
129
|
+
"summary",
|
|
130
|
+
"request",
|
|
131
|
+
"policy",
|
|
132
|
+
"policyDigest",
|
|
133
|
+
"approvers",
|
|
134
|
+
"channel",
|
|
135
|
+
"requestedAt",
|
|
136
|
+
"decision",
|
|
137
|
+
"decidedAt"
|
|
138
|
+
],
|
|
139
|
+
"description": "gatekeeper: who decided what and when, signed with Ed25519 (ADR 0047)."
|
|
140
|
+
}
|