Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
70 linesCodeBlameRaw
1/**
2 * Guardrails: how long a workspace's runs may take, kept by the work
3 * service. Mirrors `g1t_contracts::guardrails`. Sandboxes reach the
4 * internet as any CI machine does; guardrails say nothing about the
5 * network.
6 */
7import type { ServiceBinding } from "./clients";
8import type { User, Viewer } from "./identity";
9import type { RepoPath } from "./repos";
10import type { Result } from "./result";
11
12/** What one level, the workspace or a project, sets. Unset is inherited. */
13export type GuardrailSettings = {
14 /** How long each kind of run may take, in minutes. */
15 minutes?: Record<string, number>;
16 updatedBy?: string | null;
17 updatedAt?: string | null;
18};
19
20/** What a run actually gets. */
21export type Guardrails = {
22 minutes: Record<string, number>;
23};
24
25export type GuardrailsView = {
26 workspace: GuardrailSettings;
27 project: GuardrailSettings | null;
28 defaults: Guardrails;
29 /** g1t's defaults with the workspace's: what a project inherits. */
30 inherited: Guardrails;
31 effective: Guardrails;
32};
33
34export interface GuardrailsApi {
35 /** Members only. With `repo`, that project's level too. */
36 getGuardrails(viewer: Viewer, workspace: string, repo?: RepoPath | null): Promise<Result<GuardrailsView>>;
37 /** The workspace's level (owners), or with `repo`, that project's (members). */
38 updateGuardrails(
39 actor: User,
40 workspace: string,
41 repo: RepoPath | null,
42 settings: GuardrailSettings,
43 ): Promise<Result<GuardrailsView>>;
44 /**
45 * For the runner: what a run in `repo` gets, which is always its
46 * project's. `repoId` names the project however it has moved since; a
47 * pull request's working copy (`pulls/<pull id>`) stands for the
48 * repository the pull request is to.
49 */
50 runGuardrails(repo: RepoPath, repoId?: string | null): Promise<Result<Guardrails>>;
51}
52
53/** The guardrails methods of the work service. */
54export function guardrailsClient(service: ServiceBinding): GuardrailsApi {
55 const call = async <T>(method: string, args: object): Promise<T> => {
56 const response = await service.fetch(`https://service/rpc/${method}`, {
57 method: "POST",
58 headers: { "content-type": "application/json" },
59 body: JSON.stringify(args),
60 });
61 if (!response.ok) throw new Error(`${method} failed with status ${response.status}`);
62 return (await response.json()) as T;
63 };
64 return {
65 getGuardrails: (viewer, workspace, repo) => call("get_guardrails", { viewer, workspace, repo: repo ?? null }),
66 updateGuardrails: (actor, workspace, repo, settings) =>
67 call("update_guardrails", { actor, workspace, repo, settings }),
68 runGuardrails: (repo, repoId) => call("run_guardrails", { repo, repo_id: repoId ?? null }),
69 };
70}