Skip to content

Teams & Shared Learning

How to group your repos into teams, choose what the knowledge viewer shows, and share what coding learned with teammates. The design behind it is in Per-Repo Tenancy.

Group repos into teams

Open localhost:3032/teams (the people icon at the top right of the dashboard). Every repo coding found on this machine is a row; every team is a column. Tick a box to put a repo in a team.

Dashboard โ†’ Teams

The chips under Active teams are the selection the knowledge viewer shows. Saved to ~/.coding/teams.yaml.

See it in the viewer

The viewer's Teams / Views rail starts from the same selection and changes it both ways โ€” toggle a team here and the dashboard follows.

Viewer Teams rail

Share with a teammate

coding sync --push       # you: push what was learned (asks first)

Your teammate starts coding in their checkout of the same repo and gives your <repo>-history URL at the first-launch prompt. From then on their launches pull your knowledge, and yours pull theirs.

The Teams tab

Part What it does
Active teams chips the selection the viewer shows (click to toggle)
Repos on this machine the discovery scan of $HOME (depth 4): git repos with a .coding/ (or a legacy, not yet migrated .specstory/history)
Learning repo column where that repo's learned data is pushed; โ€” means no choice yet (asked at the next coding launch there)
team columns membership โ€” a repo may be in several teams
Rescan re-runs discovery now (it otherwise refreshes every 10 minutes)

Add team creates your own team; its delete button removes a team of yours (shipped teams cannot be deleted). Only ~/.coding/teams.yaml is written; the shipped config/teams.yaml declares no memberships.

What a selection changes โ€” and what it does not

Surface Uses
Knowledge viewer (graph, rail counts, History, LSL strip) the active selection
Dashboard pages that read obs-api with ?teams= the teams requested
Knowledge injection into an agent the teams of the repo the agent runs in โ€” not the selection

So narrowing the viewer to one team never hides knowledge from an agent working elsewhere. A repo that is in no team gets only its own project's knowledge.

The viewer

Unified viewer with the Teams rail

The rail lists Projects (repos), Teams and Views; the number next to each is the count of entities it admits. The line at the top names the dashboard's selection and links there. The canvas redraws only when the selection actually changes.

Choosing what runs: the Features tab

The settings icon next to Teams opens Features: the installed tier as a profile, and a switch per feature. Dependencies are explained inline ("Turning this off also switches off โ€ฆ"), and the chip next to each says when a change takes effect โ€” on save, or for new sessions only.

Dashboard โ†’ Features

The same from a shell: coding-features status, coding-features profile learning, coding-features set performance off.

Sharing, step by step

  1. You work in repo X. Learned data lands in X/.coding/ and is committed locally at session end and every 30 minutes.
  2. coding sync lists every learning repo with commits to push; the status line shows [P:n] while n of them are waiting.
  3. coding sync --push asks, then pushes.
  4. A teammate launches coding in X and pastes your X-history URL at the prompt (or Enter, if their default already points at it). The repo is cloned into their X/.coding/.
  5. Every later launch pulls; obs-api merges what arrived and the next prompt can use it.

For a repo they do not have checked out, add the remote to a team instead:

# ~/.coding/teams.yaml
teams:
  raas:
    repos:
      - https://bmw.ghe.com/alice/rapid-automations-history.git

It appears under Shared learning repos on the Teams tab; Clone N missing (or POST /teams/sync on the coordinator) clones it read-only under ~/.coding/data/<scope>/var/shared/, and coding sync pull keeps it current.

Commands

coding sync                   # what each learning repo has to push / pull
coding sync pull --repo .     # pull one repo now
coding sync commit            # commit everywhere, push nothing
coding sync --push [--yes]    # push (asks unless --yes)

How the selection stays in sync

One writer: the health coordinator (:3034, PUT /teams) owns ~/.coding/teams.yaml. Both front-ends go through it.

From Path Reads back
Dashboard โ†’ Teams /api/teams-config on the dashboard, reverse-proxied to the coordinator refetches on window focus and every 15 s; its store assigns only fields that changed
Viewer Teams rail PUT /api/teams/active on obs-api (debounced), forwarded to the coordinator polls GET /api/teams every 15 s

The viewer remembers what it last wrote, so reading its own write back is not mistaken for a dashboard change, and a poll answer that started before a click (or while the click's write was pending) is ignored. A poll that brings nothing new writes nothing into the store โ€” which is why the graph does not redraw while you look at it.

Discovery

lib/teams/discover.mjs: roots discovery.roots (default ~), depth 4, skipping dot-dirs, symlinks and an ignore list, never descending into a repo it has classified. A repo counts when it is a git repo with .coding/ or a legacy .specstory/history (one not yet migrated). The result is cached in <data home>/var/projects.json for 10 minutes; Rescan (POST /teams/discover) refreshes it now. Inside the coding-services container the cache is read through the data-home mount and $HOME/Agentic/โ€ฆ is mapped to /workspace/โ€ฆ.

The learning-repo column

It shows the remote recorded in ~/.coding/repos.yaml for each repo; โ€” means the first coding launch there has not happened yet (or was unattended, so nothing was decided). To change a recorded remote, edit repos.yaml and point the checkout at it:

git -C <repo>/.coding remote set-url origin <url>
coding sync --push --repo <repo>

Shared learning repos

A repos: entry that is only a remote is listed under Shared learning repos with its state (local = you have the checkout, shared = cloned, missing). Clone N missing calls POST /teams/sync, which clones into <data home>/var/shared/<X>/ (lib/teams/shared.mjs). Shared clones are pull-only: coding sync pull discards local changes in them first, and obs-api reads them but never writes there.

Endpoints

Endpoint Server Does
GET /teams ยท PUT /teams coordinator :3034 read / patch ~/.coding/teams.yaml (teams, active)
POST /teams/discover coordinator rescan repos
POST /teams/sync coordinator clone missing shared repos
/api/teams-config/* dashboard :3032 proxy of the three above
GET /api/teams obs-api :12436 teams with resolved projects and active (the viewer's source)
PUT /api/teams/active obs-api the viewer's write path, forwarded to the coordinator
?teams=a,b obs-api read routes filter entities, observations, digests, insights, LSL sessions

Status line

[P:n] appears while n learning checkouts have local commits nobody pushed. It reads <data home>/var/sync-state.json, which the coordinator refreshes every 30 minutes and every coding sync rewrites โ€” never git directly, so the status line stays fast.