An Inter workspace is the container for everything a company tracks: issues, teams, projects, and the agents connected to them (Vast.craft in the image above). Each workspace has a unique URL in the style inter.app/example, and when you log in, you log into one specific workspace. What sits inside that container matters more than it used to. An agent reads your issues the way a new hire reads onboarding docs, except it acts on them immediately and takes every word at face value. The structure around the issue decides whether that goes well.
A status the whole team can trust
The first thing structure buys you is an honest answer to
where is this?
. Issues move through workflows: ordered statuses defined per team, shown as groups on list views and as column headers on boards. Inter sets up a default workflow that you can customize in Settings. Agents move their issues through the same statuses people use, so one board answers the question for all work in flight, no matter who’s doing it.
| Name | Country | Born | Description |
|---|---|---|---|
| Mies van der Rohe | Germany | 1886 | Pioneer of modernism, less is moreminimalist |
| Le Corbusier | Switzerland | 1887 | Shaped modern urban living with bold concrete forms |
| Frank Lloyd Wright | USA | 1867 | Organic architecture blending buildings with nature |
| Alvar Aalto | Finland | 1898 | Humanist modernism in wood, brick, and light |
| Zaha Hadid | Iraq | 1950 | Flowing, futuristic curves that redefined form |
| Tadao Ando | Japan | 1941 | Master of concrete, light, and quiet space |
| Oscar Niemeyer | Brazil | 1907 | Sweeping curves that shaped Brasília |
| Renzo Piano | Italy | 1937 | Light, airy structures rooted in craft |
| Louis Kahn | USA | 1901 | Monumental forms with a spiritual sense of weight |
| Norman Foster | UK | 1935 | High-tech architecture with clean structural clarity |
A status is only trustworthy if it updates itself. Hand-moved tickets drift from reality within a day, so let integrations and automations do the moving. With agents in the loop this pays off twice: an agent that updates status as it works gives you a live progress report that nobody had to ask for and nobody could forget to send.
import React from 'react'import { View, ActivityIndicator } from 'react-native'import { useVehicleState, SyncStatus } from '@hooks/useVehicleState'import { Dashboard } from '@components/Dashboard'// this here is a commentexport const HomeScreen = () => {const { vehicleState, syncStatus } = useVehicleState()if (syncStatus === SyncStatus.PENDING) {return <ActivityIndicator size="large" />}return (<View><Dashboard state={vehicleState} syncStatus={syncStatus} /></View>)}
Our GitHub and GitLab integrations move an issue to _In Progress_ when the branch is created, whether by a person or an agent, and keep updating as the PR is drafted, opened, reviewed, and merged. Cycle automations move issues to and from the backlog, and issues can close and archive on their own so lists stay relevant.
Two filters for incoming work
- Backlog is a status category in Inter. Each team has its own backlog and can add additional backlog statuses to group issues down further.
- Triage is an optional status that holds new issues for review before they enter the backlog or a cycle. It earns its keep when agents and intake forms file issues on their own, since every incoming item gets a human look before it becomes work.
tooling feature
search databases
security api
databases performance infra
api reliability
api monitoring infra
api cleanup
databases tooling feature
databases bug
index.md+69-9
brand.css+32-12
home.css+6
api security feature
databases performance
Make a landing page based on attached docs explaining what we do
Read brand-guidelines.pdf
Thought 6s
customElements.define('ui-ext', {connectedCallback() {const el = this.querySelector('pre')const data = JSON.parse(el.textContent)render(this, data)}})
site/index.yaml+52
Done. Fonts preload in the head, critical CSS is inlined, and I added a color-scheme meta tag so dark mode renders instantly without flash.
Writing work an agent can run with
An agent doesn’t ask the follow-up questions a teammate would. Whatever context it needs has to be in the issue or reachable from it. The units below exist to make that context cheap to provide: the issue carries the instructions, the project carries the boundary, and the milestone carries the order of operations.
The issue carries the instructions
The most basic concept in Inter is the issue: a task described in plain language, owned by a single team, with an identifier like
ENG-123
. Only a title and status are required, which keeps issues quick to write. That plain-language description is exactly what the agent executes against, so the craft is in being specific about the outcome without dictating the approach. We collect what works in
write issues agents can act on
.
@layer base {@font-face {src: url(/font/ibm-plex-mono.woff2) format(woff2);font-family: 'Plex Mono';font-display: fallback;font-weight: 400;}code {border: 1px solid var(--lift-2);background-color: var(--lift-2);font-family: 'Plex Mono';display: inline-block;padding: .015em .3em;border-radius: .25em;font-size: 90%;}}
A workspace has one or many teams within it. Teams typically represent groups of people who work together frequently, though you can also structure them around parts of a product. Teams contain issues and can have team-specific projects, while projects can also be shared between teams.
Teams have their own settings for features like cycles, triage, and workflows, so each team can match how its work actually gets done. For an agent, the team is a working context: its workflow, its labels, and its conventions apply to everything the agent does there.
Issues support properties such as priority, estimate, label, due date, and assignee, where the assignee can be a person or an agent. Each property narrows what the agent has to infer. A priority tells it what to pick first, an estimate tells it how deep to go, a label tells it which conventions apply.
Relations carry context too. An issue marked as blocked tells the agent to stop and say so instead of guessing its way around the obstacle. Sub-issues let it break a large task down and report progress at a useful grain.
Everything beyond title and status stays optional. A person jotting down a quick bug gets no friction, and an agent picking up a fully-specified feature gets everything it needs. The issue scales to the work.
You can create issues from anywhere in the app. Try it - open any page and type C.
The project carries the boundary
Projects group issues towards a specific, time-bound deliverable, like launching a new feature. Each project has its own page showing all related issues, details, and graphs of progress and completion date ranges. For an agent, the project defines the edge of its assignment: the issues inside are its to touch, and everything outside is off limits until someone moves the boundary.
export function renderTable(str, classes) {const lines = str.trim().split('\n')const head = lines[1]?.startsWith('===') ? lines[0] : nullconst rows = lines.slice(head ? 2 : 0)function split(line) {return line.split(/ +/)}const ths = head && split(head).map(label => elem('th', format(label)))const trs = rows.map(line => {const tds = split(line).map(str => elem('td', dataFormat(str)))return elem('tr', tds)})return elem('table', [ths && elem('thead', elem('tr', ths)),elem('tbody', trs)], classes)}export function renderDeflist(data, classes) {if (typeof data == 'string') data = toObject(data)const arr = Object.entries(data).map(([key, val]) =>elem('dt', format(key)) + elem('dd', format(val)))return elem('dl', arr, classes)}export function toObject(str) {const map = {}for (const line of str.trim().split('\n')) {const [key, val = ''] = line.split(/ +/)if (key) map[key.trim()] = isNaN(val) ? val.trim() : +val}return map}
The milestone carries the order
Milestones split a project into stages of completion and put the issues in sequence, which tells an agent what must land before what. They also make review manageable. When an agent finishes a batch of issues, the milestone view shows the result as one coherent stage rather than a scattered list of closed items. The reviewer checks the diffs attached to each issue, then accepts the stage or sends parts back with comments the agent can act on directly.
$ bun test v1.3.10 (30e609e0)test/page.test.js:(pass) renderItem [0.77ms](pass) grid.visual [0.15ms](pass) renderSection [0.65ms](pass) hero.yaml [1.20ms](pass) renderMarketingPage [0.22ms](pass) renderBlogEntry [0.04ms](pass) renderDoc [0.06ms](pass) app page [0.03ms]
You can filter by milestone within a project and see how close each stage is to completion at any time. When the last one closes, the project is done, and the record of how it got there is sitting in the tracker.