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

Commit

An issue no longer says whether it is queued for a g1t agent: Issue.queued was read from queued_by, which nothing has written since g1t stopped running agents of its own, so it was always false; it is gone from the issue in the API, the contracts and the API reference's examples, and the column stays in work's D1. The work service no longer serves start_checks (always refused, kept for runners from before checks were workflows), list_assigned_issues or stall over RPC, none of which anything called; stalling a pull request g1t is seeing through stays inside the service. Opening an issue or a pull request no longer takes the by_g1t flag of hosted agents in forks, which every caller passed as false. Repository settings, auto-merge and agent approvals are described without g1t's agents, and the runner settings' reference note says agents_on_self_hosted and agent_labels now send checks, merge checks and the merge queue to your runners, where it said agent work still used g1t's model proxy. Checked: cargo test for g1t-work (103), g1t-contracts (306), g1t-api (201) and g1t (102 and 41), the wasm builds of work and the API, the OpenAPI document regenerated (the CLI's operations and reference are unchanged), the TypeScript typecheck and the contracts' 48 tests.

syntaqxcommitted Parente031b88Browse files
9 files+22−1450/9 viewed
+1−10
11011101 "comment_count": 0,
11021102 "assignees": [],
11031103 "blocked_by": [],
1104− "queued": false,
11051104 "agent": "claude-code",
11061105 "milestone": null
11071106 }
11441143 "comment_count": 0,
11451144 "assignees": [],
11461145 "blocked_by": [],
1147− "queued": false,
11481146 "agent": null,
11491147 "milestone": null
11501148 },
11801178 "comment_count": 0,
11811179 "assignees": [],
11821180 "blocked_by": [],
1183− "queued": false,
11841181 "agent": null,
11851182 "milestone": null
11861183 },
13391336 "syntaqx"
13401337 ],
13411338 "blocked_by": [9],
1342− "queued": false,
13431339 "agent": null,
13441340 "milestone": {
13451341 "number": 3,
13791375 "comment_count": 0,
13801376 "assignees": [],
13811377 "blocked_by": [],
1382− "queued": false,
13831378 "agent": null,
13841379 "milestone": null
13851380 }
14131408 "comment_count": 0,
14141409 "assignees": [],
14151410 "blocked_by": [],
1416− "queued": false,
14171411 "agent": null,
14181412 "milestone": null
14191413 }
17011695 "comment_count": 0,
17021696 "assignees": [],
17031697 "blocked_by": [],
1704− "queued": false,
17051698 "agent": "claude-code",
17061699 "milestone": null
17071700 },
28552848 "blocked_by": [
28562849 9
28572850 ],
2858− "queued": false,
28592851 "agent": null,
28602852 "milestone": {
28612853 "number": 3,
42594251 "fork_pull_requests": false,
42604252 "inherited": false
42614253 },
4262− "notes": "Agent work on your runners still uses g1t's model proxy, paid as before, unless the workspace has its own model provider."
4254+ "notes": "`agents_on_self_hosted` and `agent_labels` keep their names from before g1t ran agents of its own: they now send g1t's own work (checks, merge checks and the merge queue) to your runners with those labels."
42634255 },
42644256 "list_runner_groups": {
42654257 "params": {
93109302 "syntaqx"
93119303 ],
93129304 "blocked_by": [],
9313− "queued": false,
93149305 "agent": null,
93159306 "milestone": {
93169307 "number": 3,
+0−0

Binary or large file; its contents are not shown.

+15−59
345345 /// worked on.
346346 #[serde(default)]
347347 pub blocked_by: Vec<u32>,
348− /// Whether a g1t agent takes it as soon as it can: at once, or when
349− /// what it is blocked by has merged.
350− #[serde(default)]
351− pub queued: bool,
352348 /// The agent working on it now: the one behind its newest pull request
353349 /// that is still in progress in a fork, such as `g1t`.
354350 #[serde(default)]
580576 /// Who is recorded as opening an issue or a pull request that `actor`
581577 /// opens, and who asked for it: `(author, requested_by)`.
582578 ///
583−/// - g1t's agent, acting for someone through its token (an issue it files
584−/// while at work): g1t, requested by that person.
585−/// - A person having g1t make the change (`by_g1t`: a hosted g1t agent in
586−/// a fork of its own): g1t, requested by them.
579+/// - g1t's retired agent, acting for someone through a token of its own
580+/// that still works: g1t, requested by that person.
587581 /// - Anyone else, and g1t's own work that nobody asked for: the actor, and
588582 /// nobody asking.
589−pub fn authorship(actor: &User, by_g1t: bool) -> (User, Option<User>) {
583+pub fn authorship(actor: &User) -> (User, Option<User>) {
590584 let person = |id: &str, username: &str| User {
591585 id: id.to_owned(),
592586 username: username.to_owned(),
601595 .filter(|on_behalf_of| !crate::system::is_system_id(&on_behalf_of.id))
602596 .map(|on_behalf_of| person(&on_behalf_of.id, &on_behalf_of.username));
603597 return (g1t_author(), asked);
604− }
605− if by_g1t && actor.kind != crate::PrincipalKind::System {
606− return (g1t_author(), Some(person(&actor.id, &actor.username)));
607598 }
608599 let author = User {
609600 id: actor.id.clone(),
12201211 NeedsYou,
12211212 }
12221213
1223−/// Where a pull request made by a g1t agent stands. See [`Stage`].
1214+/// Where a pull request g1t's retired agents made stands, for those still
1215+/// open. See [`Stage`].
12241216 #[derive(Clone, Debug, Serialize, Deserialize)]
12251217 pub struct Lifecycle {
12261218 pub stage: Stage,
12531245 #[derive(Clone, Debug, Serialize, Deserialize)]
12541246 #[serde(rename_all = "camelCase", default)]
12551247 pub struct RepoSettings {
1256− /// Land a g1t agent's pull request without a person once it is ready:
1257− /// required checks passed and approved as the settings below require.
1248+ /// Land a pull request g1t is seeing through without a person once it
1249+ /// is ready: required checks passed and approved as the settings below
1250+ /// require.
12581251 pub auto_merge: bool,
12591252 /// The checks that must pass on a pull request's head before it may
12601253 /// merge into the default branch, by name: a workflow's name (`CI`), or
12681261 /// How many approving reviews a pull request needs before it may
12691262 /// merge. A reviewer who has since asked for changes blocks it.
12701263 pub required_approvals: u32,
1271− /// Whether a g1t agent's approval counts towards `required_approvals`.
1264+ /// Whether an agent's approval counts towards `required_approvals`.
12721265 pub count_agent_approvals: bool,
12731266 /// Whether someone who may merge can bypass required checks that have
12741267 /// not passed, by saying so as they merge.
13151308 pub settings: RepoSettings,
13161309 }
13171310
1318−/// `stall`: records that a step could not be carried out, so that g1t
1319−/// stops and a person is asked. Returns `bool`.
1311+/// What the work service records when a step could not be carried out, so
1312+/// that g1t stops and a person is asked. Not served over RPC.
13201313 #[derive(Debug, Serialize, Deserialize)]
13211314 #[serde(rename_all = "camelCase")]
13221315 pub struct StallArgs {
16391632 /// Needs the Write role.
16401633 #[serde(default)]
16411634 pub base: Option<String>,
1642−}
1643−
1644−/// `start_checks`: always refused now; a pull request's checks are the
1645−/// workflows run on it. Kept so that a runner from before is answered.
1646−/// Returns `Outcome<CheckJob>`.
1647−#[derive(Debug, Serialize, Deserialize)]
1648−#[serde(rename_all = "camelCase")]
1649−pub struct StartChecksArgs {
1650− pub pull_id: String,
16511635 }
16521636
1653−/// What a sandbox needs to carry out a check run.
1654−#[derive(Debug, Serialize, Deserialize)]
1655−#[serde(rename_all = "camelCase")]
1656−pub struct CheckJob {
1657− pub run_id: String,
1658− /// Lets the sandbox, and nothing else, report this run's results.
1659− pub token: String,
1660− pub commands: Vec<String>,
1661− /// The repository holding the commit: the fork, or the repository itself.
1662− pub source: RepoPath,
1663− pub commit: String,
1664− /// Who the pull request is for ([`Pull::owner`]: whoever asked g1t for
1665− /// it, or its author), and so can read its source.
1666− pub author: User,
1667− /// Username of whoever wrote the checks: the issue's author.
1668− pub requested_by: String,
1669− pub repo: RepoPath,
1670− pub number: u32,
1671−}
1672−
16731637 /// `report_checks`: what a sandbox says about its run. With no results and
16741638 /// no error it has started. `skip` forgets the run, for one that will not
16751639 /// be carried out. Returns `Outcome<CheckRun>`.
22582222 pull.author = author;
22592223 pull.requested_by = requested_by;
22602224 pull
2261− }
2262−
2263− #[test]
2264− fn a_change_a_person_has_g1t_make_is_g1t_s_requested_by_them() {
2265− let (author, asked) = authorship(&person(), true);
2266− assert_eq!((author.id.as_str(), author.username.as_str(), author.kind), (AGENT_ID, "g1t", PrincipalKind::Agent));
2267− let asked = asked.expect("the person asked for it");
2268− assert_eq!((asked.id.as_str(), asked.username.as_str(), asked.kind), ("usr_1", "syntaqx", PrincipalKind::User));
22692225 }
22702226
22712227 #[test]
22722228 fn what_g1t_s_agent_files_at_work_is_g1t_s_requested_by_whoever_it_works_for() {
2273− let (author, asked) = authorship(&agent_for("usr_1", "syntaqx"), false);
2229+ let (author, asked) = authorship(&agent_for("usr_1", "syntaqx"));
22742230 assert_eq!(author.id, AGENT_ID);
22752231 assert_eq!(asked.map(|user| user.username), Some("syntaqx".into()));
22762232 }
22782234 #[test]
22792235 fn nobody_asked_for_g1t_s_own_work() {
22802236 // A run g1t started itself acts for g1t, not for a person.
2281− let (author, asked) = authorship(&agent_for(crate::system::ID, "g1t"), false);
2237+ let (author, asked) = authorship(&agent_for(crate::system::ID, "g1t"));
22822238 assert_eq!(author.id, AGENT_ID);
22832239 assert!(asked.is_none());
22842240 // A security update g1t opens is g1t's own, as before.
2285− let (author, asked) = authorship(&User::system("acme"), true);
2241+ let (author, asked) = authorship(&User::system("acme"));
22862242 assert_eq!((author.id.as_str(), author.kind), (crate::system::ID, PrincipalKind::System));
22872243 assert!(asked.is_none());
22882244 }
22892245
22902246 #[test]
22912247 fn anyone_else_opens_their_own() {
2292− let (author, asked) = authorship(&person(), false);
2248+ let (author, asked) = authorship(&person());
22932249 assert_eq!((author.id.as_str(), author.kind), ("usr_1", PrincipalKind::User));
22942250 assert!(asked.is_none());
22952251 // Nothing but who they are is kept.
+0−3
469469 call("add_comment", { actor, repo, number, ...comment }),
470470 editComment: (actor, repo, commentId, body) => call("edit_comment", { actor, repo, commentId, body }),
471471 deleteComment: (actor, repo, commentId) => call("delete_comment", { actor, repo, commentId }),
472− startChecks: (pullId) => call("start_checks", { pullId }),
473472 reportChecks: (runId, token, report) =>
474473 call("report_checks", { runId, token, ...report }),
475474 startMergecheck: (pullId) => call("start_mergecheck", { pullId }),
476475 failMergecheck: (pullId, token, error) => call("report_mergecheck", { pullId, token, error }),
477476 advance: (pullId) => call("advance", { pullId }),
478− stall: (pullId, reason) => call("stall", { pullId, reason }),
479477 managedPulls: (repoId) => call("managed_pulls", { repoId }),
480478 queue: (repo, viewer) => call("queue", { repo, viewer }),
481479 queueBuild: (repoId) => call("queue_build", { repoId }),
520518 listActivePulls: (viewer) => call("list_active_pulls", { viewer }),
521519 byAuthor: (username, viewer, filter = {}) => call("by_author", { username, viewer, ...filter }),
522520 contributions: (username, viewer) => call("contributions", { username, viewer }),
523− listAssignedIssues: (viewer) => call("list_assigned_issues", { viewer }),
524521 appendSession: (actor, repo, number, entries) =>
525522 call("append_session", { actor, repo, number, entries }),
526523 readSession: (repo, number, viewer, afterSeq = 0) =>
+0−31
5858 /** The numbers of the issues that have to be merged before this one is worked on. */
5959 blockedBy: number[];
6060 /**
61− * Whether a g1t agent takes it as soon as it can: at once, or when what it
62− * is blocked by has merged.
63− */
64− queued: boolean;
65− /**
6661 * The agent working on it now: the one behind its newest pull request
6762 * that is still in progress in a fork, such as `g1t`.
6863 */
335330 verdict?: Verdict;
336331 };
337332
338−/** What a sandbox needs to carry out a check run. */
339−export type CheckJob = {
340− runId: string;
341− /** Lets the sandbox, and nothing else, report this run's results. */
342− token: string;
343− commands: string[];
344− /** The repository holding the commit: the fork, or the repository itself. */
345− source: RepoPath;
346− commit: string;
347− /** Who the pull request is for (`workOwner`: whoever asked g1t for it, or its author), and so can read its source. */
348− author: User;
349− /** Username of whoever wrote the checks: the issue's author. */
350− requestedBy: string;
351− repo: RepoPath;
352− number: number;
353−};
354−
355333 export type CheckReport = { results?: CheckResult[]; error?: string; skip?: boolean };
356334
357335 export type SessionEntryKind = "prompt" | "message" | "tool_call" | "tool_result" | "note" | "skill";
736714 deleteComment(actor: User, repo: RepoPath, commentId: string): Promise<Result<boolean>>;
737715
738716 /**
739− * Always refused now: a pull request's checks are the workflows run on
740− * it. Kept for a runner from before.
741− */
742− startChecks(pullId: string): Promise<Result<CheckJob>>;
743− /**
744717 * What a sandbox says about a run from before checks were workflows: so
745718 * one still finishing is recorded.
746719 */
760733 * however often this is called. For the runner service.
761734 */
762735 advance(pullId: string): Promise<Advance>;
763− /** Records that a step could not be carried out, so a person is asked. */
764− stall(pullId: string, reason: string): Promise<boolean>;
765736 /** Ids of the open pull requests g1t is seeing through. */
766737 managedPulls(repoId?: string): Promise<string[]>;
767738
881852 contributions(username: string, viewer: Viewer): Promise<Result<Contributions>>;
882853
883854
884− /** Open issues assigned to the viewer, most recently changed first. */
885− listAssignedIssues(viewer: Viewer): Promise<Issue[]>;
886855
887856 appendSession(actor: User, repo: RepoPath, number: number, entries: NewSessionEntry[]): Promise<Result<{ count: number }>>;
888857 readSession(repo: RepoPath, number: number, viewer: Viewer, afterSeq?: number): Promise<Result<SessionEntry[]>>;
+0−9
112112 .collect())
113113 }
114114
115− /// Commands written on issues are no longer run: a pull request's
116− /// checks are the workflows run on it, and the default branch's
117− /// protection says which must pass. Refused, for a runner from before.
118− pub(crate) async fn start_checks(&self, _: StartChecksArgs) -> Result<Outcome<CheckJob>> {
119− Ok(refused(
120− "Checks are the workflows run on a pull request; there are no commands to run.",
121− ))
122− }
123−
124115 /// Records what a sandbox reports for its run: that it has started, its
125116 /// results, that it could not run, or that the run should be forgotten.
126117 /// The run's token is the only credential, and a finished run accepts
+2−26
514514 let id = new_id("iss", now);
515515 let number = self.next_number(&repo.id).await?;
516516 let timestamp = rfc3339(now);
517− let (author, requested_by) = authorship(&a.actor, false);
517+ let (author, requested_by) = authorship(&a.actor);
518518 self.db
519519 .prepare(
520520 "INSERT INTO issues
787787 assignees.push(name);
788788 }
789789 Ok(Outcome::Ok(assignees))
790− }
791−
792− /// Open issues assigned to the viewer, in every repository. Callers
793− /// show only those in repositories the viewer can still see.
794− async fn list_assigned_issues(&self, a: ViewerArgs) -> Result<Vec<Issue>> {
795− let Some(viewer) = a.viewer else {
796− return Ok(Vec::new());
797− };
798− let rows = self
799− .db
800− .prepare(format!(
801− "SELECT {ISSUE_COLUMNS} FROM issues
802− WHERE state = 'open' AND EXISTS (
803− SELECT 1 FROM json_each(issues.assignees) WHERE json_each.value = ?)
804− ORDER BY updated_at DESC LIMIT 50"
805− ))
806− .bind(&[viewer.username.into()])?
807− .all()
808− .await?
809− .results::<IssueRow>()?;
810− Ok(rows.into_iter().map(Issue::from).collect())
811790 }
812791
813792 async fn close_issue(&self, a: IssueActionArgs) -> Result<Outcome<Issue>> {
13111290
13121291 let number = self.next_number(&repo.id).await?;
13131292 let timestamp = rfc3339(now);
1314− let (author, requested_by) = authorship(&a.actor, false);
1293+ let (author, requested_by) = authorship(&a.actor);
13151294 self.db
13161295 .prepare(
13171296 "INSERT INTO pulls
27352714 "add_comment" => reply(&work.add_comment(args(body)?).await?),
27362715 "edit_comment" => reply(&work.edit_comment(args(body)?).await?),
27372716 "delete_comment" => reply(&work.delete_comment(args(body)?).await?),
2738− "start_checks" => reply(&work.start_checks(args(body)?).await?),
27392717 "seen_checks" => reply(&work.seen_checks(args(body)?).await?),
27402718 "report_checks" => reply(&work.report_checks(args(body)?).await?),
27412719 "set_commit_status" => reply(&work.set_commit_status(args(body)?).await?),
27542732 "request_check_action" => reply(&work.request_check_action(args(body)?).await?),
27552733 "commit_checks" => reply(&work.commit_checks(args(body)?).await?),
27562734 "advance" => reply(&work.advance(args(body)?).await?),
2757− "stall" => reply(&work.stall(args(body)?).await?),
27582735 "managed_pulls" => reply(&work.managed_pulls(args(body)?).await?),
27592736 "queue" => reply(&work.queue(args(body)?).await?),
27602737 "queue_build" => reply(&work.queue_build(args(body)?).await?),
27792756 "list_active_pulls" => reply(&work.list_active_pulls(args(body)?).await?),
27802757 "by_author" => reply(&work.by_author(args(body)?).await?),
27812758 "contributions" => reply(&work.contributions(args(body)?).await?),
2782− "list_assigned_issues" => reply(&work.list_assigned_issues(args(body)?).await?),
27832759 "append_session" => reply(&work.append_session(args(body)?).await?),
27842760 "read_session" => reply(&work.read_session(args(body)?).await?),
27852761 // Decision records (decisions.rs).
+0−3
6060 pub assignees: String,
6161 /// JSON array of issue numbers.
6262 pub blocked_by: String,
63− /// JSON of who queued it for a g1t agent, if anyone has.
64− pub queued_by: Option<String>,
6563 pub agent: Option<String>,
6664 /// The number of its milestone, and that milestone's title.
6765 #[serde(default)]
9795 comment_count: row.comment_count,
9896 assignees: serde_json::from_str(&row.assignees).unwrap_or_default(),
9997 blocked_by: serde_json::from_str(&row.blocked_by).unwrap_or_default(),
100− queued: row.queued_by.is_some(),
10198 agent: row.agent,
10299 milestone: milestone_ref(row.milestone, row.milestone_title),
103100 }
+4−4
1−//! A repository's settings for how g1t's agents handle its pull requests,
1+//! A repository's settings for how its pull requests are handled,
22 //! and the branch protection settings that are now its "Default branch
33 //! protection" ruleset (rulesets.rs).
44 //!
5757 }
5858
5959 impl Work {
60− /// A repository's stored settings, by its id: how g1t's agents handle
61− /// its pull requests. Defaults if none were set. Branch protection is
60+ /// A repository's stored settings, by its id: how its pull requests are
61+ /// handled. Defaults if none were set. Branch protection is
6262 /// its rules': see `settings_on`.
6363 pub(crate) async fn settings(&self, repo_id: &str) -> Result<RepoSettings> {
6464 if let Some(found) = self.prefetched_repo(repo_id) {
8484 Ok(Outcome::Ok(self.timing.db(3, self.default_branch_settings(&repo)).await?))
8585 }
8686
87− /// Replaces a repository's settings: how g1t's agents work, kept here,
87+ /// Replaces a repository's settings: how pull requests are handled, kept here,
8888 /// and the branch protection ones, written to its "Default branch
8989 /// protection" ruleset (made when it has none and they protect
9090 /// anything). Rules that only rulesets have stay as they are.

Comments

Sign in to comment.