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.
| 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. | 1 | import assert from "node:assert/strict"; |
| 2 | import { test } from "node:test"; | |
| 3 | ||
| 4 | import type { DirectoryPerson, DirectoryTeam, PeopleDirectory } from "@g1t/contracts"; | |
| 5 | ||
| The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404. | 6 | import { codeAccessWords, directoryEntries, leads, ownsFromText } from "./people.ts"; |
| 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. | 7 | |
| 8 | const person = (username: string, extra: Partial<DirectoryPerson> = {}): DirectoryPerson => ({ | |
| 9 | user_id: `usr_${username}`, | |
| 10 | username, | |
| 11 | name: null, | |
| 12 | avatar: null, | |
| 13 | bio: null, | |
| 14 | location: null, | |
| 15 | pronouns: null, | |
| 16 | timezone: null, | |
| 17 | role: "member", | |
| 18 | title: null, | |
| 19 | owns: [], | |
| 20 | joined_at: "2026-10-01T00:00:00Z", | |
| 21 | ...extra, | |
| 22 | }); | |
| 23 | ||
| 24 | const team = (slug: string, name: string, extra: Partial<DirectoryTeam> = {}): DirectoryTeam => ({ | |
| 25 | slug, | |
| 26 | name, | |
| 27 | description: null, | |
| 28 | visibility: "visible", | |
| 29 | parent: null, | |
| 30 | lead: null, | |
| 31 | channel: null, | |
| 32 | people: [], | |
| 33 | repos_count: 0, | |
| 34 | ...extra, | |
| 35 | }); | |
| 36 | ||
| 37 | const directory: PeopleDirectory = { | |
| 38 | people: [ | |
| 39 | person("chase", { name: "Chase Pierce", title: "Founder", role: "owner" }), | |
| Merge branch 'rm-orgchart-getstarted' | 40 | person("sofia", { name: "Sofia Reyes", title: "Head of Sales", owns: ["the forecast"] }), |
| 41 | person("jordan", { name: "Jordan Lee", title: "Account Executive", owns: ["Halcyon", "Bluebird"] }), | |
| 42 | person("kai", { name: "Kai Nakamura", title: "Product Designer" }), | |
| 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. | 43 | ], |
| 44 | teams: [ | |
| 45 | team("sales", "Sales", { | |
| 46 | lead: { kind: "user", username: "sofia", name: "Sofia Reyes", avatar: null }, | |
| 47 | people: [ | |
| 48 | { username: "sofia", role: "maintainer" }, | |
| 49 | { username: "jordan", role: "member" }, | |
| 50 | ], | |
| 51 | repos_count: 0, | |
| 52 | }), | |
| 53 | team("design", "Design", { people: [{ username: "kai", role: "maintainer" }], repos_count: 2 }), | |
| The contracts no longer describe g1t's own agents, and workspaces can keep their AI providers. Every consumer had already stopped using them, so the TypeScript and Rust contracts drop the workspace-agent, ability, look, skill-library, context, runner-agent and mention modules, the chat and docs RPCs agents posted and read through, the folio agent methods, the agent_waiting notification, agent.asked and memory.changed events, AI credit, token and gateway billing types, model routes and sessions, team agents, agent tokens, plan, review, message and confidence types, command rules, cost caps and confidence rules. The agents:run and models:* scopes are no longer offered by any preset, OAuth default or permission form, but a stored token or grant that names them still reads; and the removed operations are gone from the scope table, so the API's check that every operation has exactly one scope is strict again. What stored data needs in order to parse (old run and credential kinds, an agent team lead, retired rules and webhook events, old guardrail and integration settings) still parses, and a run's token is still PrincipalKind::Agent, which now means a run's token and the @g1t rows written before. The customize, marketplace, skills and claude-plugin contracts stay only until the mobile app drops its Customize screens. | 54 | team("night-shift", "Night shift", { lead: { kind: "agent", agent_id: "agt_atlas" } }), |
| 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. | 55 | ], |
| 56 | base_permission: "read", | |
| 57 | can_manage: true, | |
| 58 | }; | |
| 59 | ||
| The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404. | 60 | test("a team's lead is a person; an old agent lead is nobody's", () => { |
| 61 | assert.equal(leads(directory.teams[0]!.lead, { username: "sofia" }), true); | |
| 62 | assert.equal(leads(directory.teams[0]!.lead, { username: "jordan" }), false); | |
| 63 | assert.equal(leads(directory.teams[2]!.lead, { username: "atlas" }), false); | |
| 64 | assert.equal(leads(null, { username: "sofia" }), false); | |
| An agent is on teams the way a person is: through team membership, with no team or department of its own. Add it to teams when you create it, from its profile or from the team's page; the Agents sidebar groups agents by the teams they're on, with those on none last; what an agent is told about its teammates, team budgets, skills reach, Spend's By team and the People pages all read memberships. Agents with an old team name matching a team are moved onto it once; the rest are left off a team. Templates name a role only. The agents, teams and people guides say how. | 65 | }); |
| 66 | ||
| The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404. | 67 | test("the directory lists people, in one search", () => { |
| People lists people. The directory, its counts and its search cover the workspace's people only; agents keep their page under Agents, where the Profile tab now also says what each agent is told about its teams, and the old address of an agent under People sends you there. Agents still join teams beside people: a team's members page groups them under its people with an agent badge, and the org chart shows them as members of the team beside its lead. The people and teams, agents, teams and workspaces guides say so. | 68 | const names = (query: string) => directoryEntries(directory, query).map((e) => e.person.username); |
| 69 | assert.deepEqual(names(""), ["chase", "sofia", "jordan", "kai"]); | |
| 70 | assert.deepEqual(names("sales"), ["sofia", "jordan"]); | |
| 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. | 71 | assert.deepEqual(names("halcyon"), ["jordan"]); |
| People lists people. The directory, its counts and its search cover the workspace's people only; agents keep their page under Agents, where the Profile tab now also says what each agent is told about its teams, and the old address of an agent under People sends you there. Agents still join teams beside people: a team's members page groups them under its people with an agent badge, and the org chart shows them as members of the team beside its lead. The people and teams, agents, teams and workspaces guides say so. | 72 | assert.deepEqual(names("owner"), ["chase"]); |
| The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404. | 73 | // A team with no people on it is no one's team in the directory. |
| People lists people. The directory, its counts and its search cover the workspace's people only; agents keep their page under Agents, where the Profile tab now also says what each agent is told about its teams, and the old address of an agent under People sends you there. Agents still join teams beside people: a team's members page groups them under its people with an agent badge, and the org chart shows them as members of the team beside its lead. The people and teams, agents, teams and workspaces guides say so. | 74 | assert.deepEqual(names("night shift"), []); |
| 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. | 75 | assert.equal(names("nobody here").length, 0); |
| The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404. | 76 | // Every entry is a person with their teams. |
| People lists people. The directory, its counts and its search cover the workspace's people only; agents keep their page under Agents, where the Profile tab now also says what each agent is told about its teams, and the old address of an agent under People sends you there. Agents still join teams beside people: a team's members page groups them under its people with an agent badge, and the org chart shows them as members of the team beside its lead. The people and teams, agents, teams and workspaces guides say so. | 77 | const sofia = directoryEntries(directory, "sofia")[0]!; |
| 78 | assert.deepEqual(Object.keys(sofia), ["person", "teams"]); | |
| 79 | assert.deepEqual(sofia.teams.map((t) => t.slug), ["sales"]); | |
| 80 | }); | |
| 81 | ||
| 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. | 82 | test("forms read plainly", () => { |
| 83 | assert.deepEqual(ownsFromText("storefront\n the release process ,, billing"), ["storefront", "the release process", "billing"]); | |
| 84 | }); | |
| 85 | ||
| 86 | test("access to Code says where it comes from", () => { | |
| 87 | assert.equal(codeAccessWords({ role: "owner" }, "read", []).summary, "Admin on every repository, as an owner"); | |
| 88 | const kai = codeAccessWords({ role: "member" }, "read", [directory.teams[1]!]); | |
| 89 | assert.equal(kai.summary, "Read on every repository, the workspace's base permission"); | |
| 90 | assert.deepEqual(kai.through, ["Roles on 2 repositories through Design"]); | |
| 91 | assert.equal(codeAccessWords({ role: "member" }, "none", []).summary, "Only repositories they're given a role on"); | |
| 92 | }); |
This file's history is long; its oldest lines are credited to the oldest commit read.