Skip to content
293 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API1//! Types and service interfaces shared by every g1t service.
2//!
3//! Each service has a module here holding the data it exchanges and the
4//! arguments of each of its methods. Services and their callers depend on
5//! this crate, never on each other's code.
6
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb977pub mod about;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look8pub mod access;
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r99pub mod advisories;
Merge account deletion: soft delete for 30 days, staff restore and purge, ghost for what remains (identity 0037)10pub mod account_deletion;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look11pub mod accounts;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API12pub mod actions;
13pub mod agents;
14pub mod audit;
Merge branch 'worktree-agent-ac5b181a013e54348'15pub mod backups;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API16pub mod billing;
17pub mod capture;
Merge checks: statuses and check runs on every commit18pub mod checks;
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar19pub mod codeowners;
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r920pub mod coding_agents;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API21pub mod credentials;
Artifacts contracts: folios, their four kinds, dashboard datasets, folio events and the artifacts scopes are typed and validated the same in TypeScript and Rust, with nothing using them yet22pub mod datasets;
Merge branch 'worktree-agent-a5a5de74d8863d554' into worktree-agent-a16631325aecf58ca23pub mod deploy_keys;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API24pub mod events;
Artifacts contracts: folios, their four kinds, dashboard datasets, folio events and the artifacts scopes are typed and validated the same in TypeScript and Rust, with nothing using them yet25pub mod folios;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look26pub mod github;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API27pub mod guardrails;
28pub mod identity;
Inbox: the events service tells people what needs them as events arrive29pub mod inbox;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API30pub mod integrations;
Merge main (membership, two-factor, GitHub repo roles) into tokens31pub mod members;
Merge branch 'mirroring' into artifacts-mode32pub mod mirrors;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API33mod ids;
34mod names;
35mod outcome;
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member36pub mod packages;
People and teams are front and centre: one directory of people and agents with presence, local time, titles, teams and what each owns; profiles with manager and reports and the agents they work with; an org chart with each team's agents beside the person who leads it; and teams of any mix, with a lead, a channel, a budget agents keep to and the agents on them. Every agent is told its teams each turn (who leads, who owns what, who's around and who to page), and the team page shows exactly what. Member management is Members and invites; the people and teams guide says how.37pub mod people;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API38pub mod projects;
39pub mod repos;
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge40pub mod rules;
Fast pages, required checks on the branch, self-hosted runners, honest incidents41pub mod runners;
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step42pub mod scopes;
Search across all of g1t, Explore, and a command palette43pub mod search;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API44pub mod security;
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar45pub mod teams;
46pub mod security_suite;
Merge branch 'worktree-agent-ad8a36dfcd4176015' into spend-guardrails47pub mod subscribers;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API48pub mod time;
Fine-grained personal tokens, workspace token rules and approvals in identity49pub mod tokens;
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar50pub mod updates;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API51pub mod webhooks;
52pub mod work;
53
Home says what people did as well as what agents did. Since you were last here now has a People column and an Agents column: who pushed how many commits to which projects, pull requests opened, merged and reviewed, issues opened and closed, docs edited, messages sent and deploys that went out, each line a link to where those are listed, with the agents' acceptance (first time, after review, didn't finish) kept as a row of their column; the sentence under the heading sums it up honestly, and says when a part of g1t could not be read, or that the span was quiet. Landed counts merged pull requests, commits pushed straight to a default branch, production deploys that went live, releases and packages, newest first; Running now adds workflow runs. Behind it, the events service answers an activity digest over a span in one round trip from its existing indexes, every push now records how many commits it carried, and chat counts the messages sent in the conversations you can read. The Home guide defines every line, and says how this scales.54pub use ids::{id_floor, new_id};
Merge branch 'worktree-agent-a8385d293d42c913a'55pub use names::{
A workflow's `uses: actions/setup-node@v4` means GitHub's `actions` again, whoever is on g1t. g1t looked for a repository on g1t before GitHub, and anyone could make a public workspace called `actions`, `docker` or `aws-actions` and have its `setup-node` run in every workflow that names GitHub's, with that job's secrets. Now another workspace's public repository answers only for a name GitHub has no public repository of; the caller's own workspace and g1t's own `g1t/…` still answer from g1t, and when GitHub can't be asked, GitHub's is used. The names of the GitHub accounts whose actions workflows use most can no longer be registered, renamed to, or taken by signing up with GitHub (which suggests the name with `-gh`); an account that has one keeps it, and mentions and invitations still find it. The Actions, authentication and workspaces guides say so.56 Username, aliasable_name, claimable_namespace, is_action_owner_name, is_claimable_name, claimable_username, is_namespace_shaped, is_reserved_name, is_route_name,
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers57 is_valid_namespace, is_valid_repo_name,
Merge branch 'worktree-agent-a8385d293d42c913a'58};
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API59pub use outcome::{Failure, FailureCode, Outcome};
60
61use serde::{Deserialize, Serialize};
62
Merge main (membership, two-factor, GitHub repo roles) into tokens63/// What a member may do in a workspace. A member may also hold
64/// [`members::OrgRole`]s, which add to it.
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API65#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
66#[serde(rename_all = "lowercase")]
67pub enum Role {
Merge main (membership, two-factor, GitHub repo roles) into tokens68 /// Everything: Admin on every repository, the workspace's members,
69 /// settings, billing and security.
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API70 Owner,
Merge main (membership, two-factor, GitHub repo roles) into tokens71 /// The workspace's base permission on each repository, and what its
72 /// member privileges allow (see [`members::MemberPrivileges`]).
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API73 Member,
74}
75
Merge main (membership, two-factor, GitHub repo roles) into tokens76pub use members::{MemberPrivileges, OrgRole};
77
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API78/// One workspace a user belongs to.
79#[derive(Clone, Debug, Serialize, Deserialize)]
80pub struct Membership {
81 /// The workspace's name in URLs: `g1t.sh/<slug>`.
82 pub slug: String,
83 pub role: Role,
84 /// The workspace's display name, for showing it to people. Set when a
85 /// user is resolved from credentials; absent on principals made up by
86 /// a service.
87 #[serde(default, skip_serializing_if = "Option::is_none")]
88 pub name: Option<String>,
89 /// The workspace's uploaded icon: the SHA-256 of its bytes, served at
90 /// `/avatars/<avatar>`. Absent means the generated letter avatar.
91 #[serde(default, skip_serializing_if = "Option::is_none")]
92 pub avatar: Option<String>,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look93 /// What a member gets on each of the workspace's repositories: the
94 /// workspace's base permission. Set when a user is resolved from
95 /// credentials; absent means the default, Write. Owners have Admin
96 /// whatever it says. See [`access`].
97 #[serde(default, skip_serializing_if = "Option::is_none")]
98 pub base_permission: Option<access::BasePermission>,
Merge branch 'worktree-agent-ad7c6d88d93adc817'99 /// Who may create the workspace's teams. Set when a user is resolved
100 /// from credentials; absent means the default, any member. See
101 /// [`teams::TeamCreation`].
102 #[serde(default, skip_serializing_if = "Option::is_none")]
103 pub team_creation: Option<teams::TeamCreation>,
Merge main (membership, two-factor, GitHub repo roles) into tokens104 /// The roles the member holds besides `role`: billing manager,
105 /// security manager. Set when a user is resolved from credentials.
106 #[serde(default, skip_serializing_if = "Vec::is_empty")]
107 pub org_roles: Vec<OrgRole>,
108 /// What the workspace lets members (and repository admins) do. Set
109 /// when a user is resolved from credentials; absent means the
110 /// defaults. See [`members::MemberPrivileges`].
111 #[serde(default, skip_serializing_if = "Option::is_none")]
112 pub privileges: Option<MemberPrivileges>,
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API113}
114
115impl Membership {
116 /// A plain member of `slug`, as services act inside one workspace.
117 pub fn member(slug: impl Into<String>) -> Self {
118 Membership {
119 slug: slug.into(),
120 role: Role::Member,
121 name: None,
122 avatar: None,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look123 base_permission: None,
Merge branch 'worktree-agent-ad7c6d88d93adc817'124 team_creation: None,
Merge main (membership, two-factor, GitHub repo roles) into tokens125 org_roles: Vec::new(),
126 privileges: None,
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API127 }
128 }
Merge main (membership, two-factor, GitHub repo roles) into tokens129
130 /// Whether the member holds `role` besides owner or member.
131 pub fn has(&self, role: OrgRole) -> bool {
132 self.org_roles.contains(&role)
133 }
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API134}
135
136/// What a set of credentials resolved to.
137#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
138#[serde(rename_all = "lowercase")]
139pub enum PrincipalKind {
140 /// A person's account.
141 #[default]
142 User,
143 /// A workspace, acting through one of its own access tokens. Its `id`
144 /// is the workspace's, its `username` the workspace's slug, and it is a
145 /// member of that workspace and no other.
146 Workspace,
147 /// A g1t agent at work in a sandbox, acting through a token that lives
148 /// as long as its run and can do only what that token's scope lists, in
g1t is one name: its agent's work, commits and comments show as @g1t, and nobody can claim g1t or g1t-agent149 /// one repository. Its `username` is `g1t`.
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API150 Agent,
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily151 /// g1t itself: the platform acting on its own, as when it opens a
152 /// pull request to upgrade a vulnerable dependency or merges from the
153 /// queue. Never resolved from credentials: only services make one,
154 /// with [`User::system`]. Its `username` is `g1t`, which nobody can
155 /// register.
156 System,
157}
158
159/// g1t's own identity, as [`PrincipalKind::System`] work is recorded.
160pub mod system {
161 /// Its id wherever an author or actor id is stored.
162 pub const ID: &str = "g1t";
163 /// Its name, shown as the author of what it does.
164 pub const USERNAME: &str = "g1t";
165 /// The address on the commits it makes, which no mailbox receives.
166 pub const EMAIL: &str = "g1t@users.noreply.g1t.sh";
167 /// Ids that earlier versions stored for g1t's own actions, such as a
168 /// merge its settings made. Read as g1t too.
169 pub const LEGACY_IDS: [&str; 3] = ["g1t_policy", "svc_runner", "g1t_runner"];
170
171 /// Whether `id` is g1t's own.
172 pub fn is_system_id(id: &str) -> bool {
173 id == ID || LEGACY_IDS.contains(&id)
174 }
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API175}
176
177#[derive(Clone, Debug, Default, Serialize, Deserialize)]
178pub struct User {
179 pub id: String,
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers180 /// Lowercased: what the person is found, linked and mentioned by.
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API181 pub username: String,
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers182 /// The username as its owner wrote it (`Ana`), when that differs from
183 /// `username`: what pages show. Set on the signed-in person and on
184 /// people looked up by name; absent elsewhere, where `username` is shown.
185 #[serde(default, skip_serializing_if = "Option::is_none")]
186 pub display_username: Option<String>,
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API187 #[serde(default)]
188 pub kind: PrincipalKind,
189 /// Whether the account's email address has been confirmed. Unverified
190 /// accounts can sign in but cannot create or change anything.
191 #[serde(default)]
192 pub verified: bool,
193 /// The workspaces this user belongs to. Filled in when a user is
194 /// resolved from credentials, so any service can authorize from it.
195 #[serde(default)]
196 pub workspaces: Vec<Membership>,
197 /// The person's uploaded avatar: the SHA-256 of its bytes, served at
198 /// `/avatars/<avatar>`. Absent means the generated letter avatar.
199 #[serde(default, skip_serializing_if = "Option::is_none")]
200 pub avatar: Option<String>,
201 /// Set on an agent resolved from its token: who it acts for, with which
202 /// credential, and what it may do. See [`credentials`].
203 #[serde(default, skip_serializing_if = "Option::is_none")]
204 pub acting: Option<Box<credentials::Acting>>,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look205 /// The repositories this user has been given a role on directly,
206 /// whether or not they belong to its workspace. Filled in with
207 /// `workspaces`; see [`access`].
208 #[serde(default, skip_serializing_if = "Vec::is_empty")]
209 pub grants: Vec<access::RepoGrant>,
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step210 /// Set on a user resolved from an access token: its scopes and the
211 /// workspaces or repositories it is limited to. Absent on a signed-in
212 /// session and on an agent (whose `acting` scope applies instead).
213 /// See [`scopes`].
214 #[serde(default, skip_serializing_if = "Option::is_none")]
215 pub token: Option<Box<scopes::TokenAccess>>,
Merge main (membership, two-factor, GitHub repo roles) into tokens216 /// The workspaces this person belongs to but cannot use until they
217 /// meet its policy, such as turning on two-factor authentication.
218 /// They are left out of `workspaces` and `grants` meanwhile. Set when
219 /// a person is resolved from a session.
220 #[serde(default, skip_serializing_if = "Vec::is_empty")]
221 pub held: Vec<members::PolicyHold>,
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API222}
223
224impl User {
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily225 /// g1t itself, acting in `workspace`: what the platform's own work,
226 /// such as security updates, is done and recorded as.
227 pub fn system(workspace: &str) -> User {
228 User {
229 id: system::ID.to_owned(),
230 username: system::USERNAME.to_owned(),
231 kind: PrincipalKind::System,
232 verified: true,
233 workspaces: vec![Membership::member(workspace.to_lowercase())],
234 ..User::default()
235 }
236 }
237
238 /// Whether this is g1t itself.
239 pub fn is_system(&self) -> bool {
240 self.kind == PrincipalKind::System
241 }
242
Merge email confirmation gate: a code and a link, nothing until confirmed (identity 0036)243 /// Whether this is a person whose account has not confirmed its email
244 /// address. Such an account can only confirm it (or change it, or sign
245 /// out): the site, the API, MCP and git refuse it everything else
246 /// ([`accounts::confirm_email_first`]).
247 pub fn awaits_confirmation(&self) -> bool {
248 self.kind == PrincipalKind::User && !self.verified
249 }
250
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API251 pub fn role_in(&self, slug: &str) -> Option<Role> {
252 self.workspaces
253 .iter()
254 .find(|membership| membership.slug == slug)
255 .map(|membership| membership.role)
256 }
257
258 pub fn is_member(&self, slug: &str) -> bool {
259 self.role_in(slug).is_some()
260 }
Merge main (membership, two-factor, GitHub repo roles) into tokens261
262 /// The membership in `slug`, if any.
263 pub fn membership(&self, slug: &str) -> Option<&Membership> {
264 self.workspaces.iter().find(|membership| membership.slug.eq_ignore_ascii_case(slug))
265 }
266
267 /// Whether this is a person who owns `slug`, or holds `role` in it.
268 pub fn owns_or_has(&self, slug: &str, role: OrgRole) -> bool {
269 self.membership(slug)
270 .is_some_and(|membership| membership.role == Role::Owner || membership.has(role))
271 }
272
273 /// Whether the user may manage `slug`'s billing: an owner or a billing
274 /// manager.
275 pub fn manages_billing(&self, slug: &str) -> bool {
276 self.owns_or_has(slug, OrgRole::BillingManager)
277 }
278
279 /// Whether the user may see and manage security across `slug`: an
280 /// owner or a security manager.
281 pub fn manages_security(&self, slug: &str) -> bool {
282 self.owns_or_has(slug, OrgRole::SecurityManager)
283 }
284
285 /// The workspace's member privileges as this user sees them: the
286 /// defaults when the membership does not say.
287 pub fn privileges_in(&self, slug: &str) -> MemberPrivileges {
288 self.membership(slug).and_then(|membership| membership.privileges).unwrap_or_default()
289 }
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API290}
291
292/// Who is asking. Every read and write in every service takes one.
293pub type Viewer = Option<User>;

This file's history is long; its oldest lines are credited to the oldest commit read.