Not scheduled. This is a design record, parked deliberately so the local
daemon in #117 can ship without it and without being redone because of it.
Nothing here is implemented and nothing here is committed to; the decisions
below are where the discussion of 2026-08-28 landed, not a promise.
Team mode is the third tier of the service design in #117: hooks talk to a local
daemon, and the daemon — never the hook — talks to a shared team server.
procoder (client) ──socket──▶ procoder daemon ──HTTPS+token──▶ team server
many users
many repos
The daemon still runs every check on the local checkout. The team server has
nobody's files and can never run gofmt; asking it to would mean shipping
working trees over the network or silently running fewer checks in team mode
than locally. Both are worse than the problem.
The scope ladder gains a rung
internal/gate/adoption.go already decides between Universal (only what is
true regardless of house style) and Adopted (everything, because this
repository asked). Team mode is the third rung — Adopted plus a policy floor
set centrally. A repo may tighten the floor. It may not weaken it. That is the
one place D-OVERRIDE changes: the repo file still wins, but only upward.
Ownership moves; files do not
Team-owned artifacts still materialise as files under .procoder/, committed to
git. The daemon syncs them down and records the team version in a manifest. Every
domain that reads them today reads them unchanged, pull requests still show them,
CI and a fresh clone still work.
What changes is who may write them. A local edit to a team-owned file is a
drift finding at the gate, not an accepted change — the same shape as the
agent-layer drift check that already exists.
This is why #117's D7 survives contact with team mode. Git still holds the
content. The server holds the authority over it.
What is owned where
| Artifact |
Local mode |
Team mode |
config.toml, security/RULES.md, docs/RULES.md, github templates |
repo file wins (D-OVERRIDE) |
team baseline is a floor; repo may tighten only |
| specs |
repo, in git |
team-owned |
| backlog: milestones, epics, stories |
repo |
team-owned — a story can span repos |
| sprints |
repo |
team-owned — multi-person by definition |
| ask decisions and answers |
repo |
team-owned — an answered question is answered everywhere |
| lessons, glossary |
repo |
team-owned — cross-repo by nature |
| ADRs |
repo |
scoped — org ADRs from the team, repo ADRs stay local |
| claims, release versions, changelog |
repo / gitignored |
team-owned — coordination is meaningless with one person |
| plans |
repo |
stays repo — how this repo implements a story |
| todo |
repo |
stays repo |
| index, dispatch, handoff, bench baselines |
local |
stays local — derived or machine-specific |
| learn timings |
local |
local, aggregated to the team |
Where each check and gate runs
Checks are unchanged in both modes: they exec real tools against the working
tree, on the machine that holds it.
|
Local mode |
Team mode |
| format, lint, secrets, SAST, deps, complexity, debt, tests |
local daemon |
local daemon, team policy floor, verdict recorded team-side |
| audit / full-repo scan |
local, on demand |
runs local (it needs the tree), results aggregated team-side |
| commit gate |
local verdict, final |
local verdict + team leg; no team verdict, no green |
| todo close |
local |
local |
| story / epic close |
local |
team — requires approve on backlog |
| sprint open / close |
local |
team — requires approve on sprint |
| spec approve |
local |
team — requires approve on spec |
| release / version |
local |
team — version reserved centrally, changelog assembled team-side, requires approve on release |
| PR merge |
local (gh) |
team — consults the recorded team verdict |
RBAC
Resources: spec, backlog, sprint, adr, policy, release, lesson,
decision. Verbs: read, propose, approve, admin.
| Role |
Gets |
| viewer |
read everything, propose nothing |
| contributor |
read all; propose specs, stories, ADRs, decisions; close todos |
| maintainer |
approve specs, stories and ADRs; open and close sprints; release |
| admin |
policy, membership, repo registration |
Per-repo overrides: maintainer in one repo, viewer in another.
The client cannot enforce any of this, and this design does not pretend
otherwise. Anyone can edit a file locally or set mode = "off". What the
server enforces is whether an edit becomes team truth and whether the team gate
says yes; the local gate reports the divergence as drift. It is a boundary
against accident and a record of authority, not a wall against a determined
local user — the same stance internal/dispatch takes about parallelism claims.
Which is why RBAC works through propose/approve rather than client-side
refusal. "Cannot create a spec" does not mean the binary refuses. It means the
write lands server-side as proposed and someone holding approve promotes it.
That is P-CONTROL one tier up: procoder records, a person decides.
Decisions of 2026-08-28
| # |
Decision |
| T1 |
Team mode is the third rung of the scope ladder: Adopted plus a policy floor a repo may tighten but never weaken. |
| T2 |
Ownership moves, location does not. Team-owned artifacts materialise as files in .procoder/, committed to git, with a sync manifest recording which team version each came from. |
| T3 |
Checks never move to the server. Team mode supplies their policy and receives their evidence. |
| T4 |
Every write to a team-owned artifact lands server-side as proposed; a role holding approve promotes it. RBAC is enforced by the server and never by the client. |
| T5 |
RBAC is resources × verbs with four default roles and per-repo overrides — not a permission per command. |
| T6 |
In team mode the commit gate needs a team verdict to report green. Local legs still run and report; the overall verdict is NOT green without the team leg. |
| T7 |
All four tiers are team-owned by default when a repo joins a team: policy, planning, knowledge, coordination. |
| T8 |
Per-user identity is required. A single shared bearer token is not identity — every decision, lesson, answer and claim needs an author. |
Risks this design carries
- A team-server outage stops the team committing (T6). Deliberate — the team
floor is not optional — but it makes the server's availability a hard
dependency for everyone who joined a team.
- Approval queues can starve. T7 puts machine-written knowledge through
approval too: an answer recorded by procoder ask, a lesson harvested from a
copilot leak, a claim taken when work starts. If claims need approval, nobody
starts work while a maintainer is asleep. A direct-write carve-out for the
coordination tier is the most likely correction to this design.
- Drift becomes a routine finding. Every stale sync shows up at the gate. Too
noisy and people learn to ignore the gate, which is worse than not having the
check.
Open questions
- How does a repo join a team, and who may do it?
procoder init --team <name>
needs an admin on the other end registering the repo.
- Where do per-user identities come from — procoder-issued tokens, or OIDC
against whatever the team already uses?
- Conflict handling when the same story is edited team-side and locally in the
same window. The drift finding is the detection; the resolution path is
undefined.
- Does the approval queue need a carve-out for machine-written coordination
writes, claims especially? See the risks above.
- What happens to an in-flight release when the team server goes down midway —
is a reserved version released back, or held?
- Team-server schema and migrations: who owns the storage, and how does a version
upgrade land for a team that cannot restart everybody at once?
- novamem as the knowledge backing store — a separate question once this tier
exists.
Blocked on #117.
Team mode is the third tier of the service design in #117: hooks talk to a local
daemon, and the daemon — never the hook — talks to a shared team server.
The daemon still runs every check on the local checkout. The team server has
nobody's files and can never run
gofmt; asking it to would mean shippingworking trees over the network or silently running fewer checks in team mode
than locally. Both are worse than the problem.
The scope ladder gains a rung
internal/gate/adoption.goalready decides betweenUniversal(only what istrue regardless of house style) and
Adopted(everything, because thisrepository asked). Team mode is the third rung — Adopted plus a policy floor
set centrally. A repo may tighten the floor. It may not weaken it. That is the
one place D-OVERRIDE changes: the repo file still wins, but only upward.
Ownership moves; files do not
Team-owned artifacts still materialise as files under
.procoder/, committed togit. The daemon syncs them down and records the team version in a manifest. Every
domain that reads them today reads them unchanged, pull requests still show them,
CI and a fresh clone still work.
What changes is who may write them. A local edit to a team-owned file is a
drift finding at the gate, not an accepted change — the same shape as the
agent-layer drift check that already exists.
This is why #117's D7 survives contact with team mode. Git still holds the
content. The server holds the authority over it.
What is owned where
config.toml,security/RULES.md,docs/RULES.md, github templatesWhere each check and gate runs
Checks are unchanged in both modes: they exec real tools against the working
tree, on the machine that holds it.
approveonbacklogapproveonsprintapproveonspecapproveonreleasegh)RBAC
Resources:
spec,backlog,sprint,adr,policy,release,lesson,decision. Verbs:read,propose,approve,admin.Per-repo overrides: maintainer in one repo, viewer in another.
The client cannot enforce any of this, and this design does not pretend
otherwise. Anyone can edit a file locally or set
mode = "off". What theserver enforces is whether an edit becomes team truth and whether the team gate
says yes; the local gate reports the divergence as drift. It is a boundary
against accident and a record of authority, not a wall against a determined
local user — the same stance
internal/dispatchtakes about parallelism claims.Which is why RBAC works through propose/approve rather than client-side
refusal. "Cannot create a spec" does not mean the binary refuses. It means the
write lands server-side as proposed and someone holding
approvepromotes it.That is P-CONTROL one tier up: procoder records, a person decides.
Decisions of 2026-08-28
Adoptedplus a policy floor a repo may tighten but never weaken..procoder/, committed to git, with a sync manifest recording which team version each came from.approvepromotes it. RBAC is enforced by the server and never by the client.Risks this design carries
floor is not optional — but it makes the server's availability a hard
dependency for everyone who joined a team.
approval too: an answer recorded by
procoder ask, a lesson harvested from acopilot leak, a claim taken when work starts. If claims need approval, nobody
starts work while a maintainer is asleep. A direct-write carve-out for the
coordination tier is the most likely correction to this design.
noisy and people learn to ignore the gate, which is worse than not having the
check.
Open questions
procoder init --team <name>needs an
adminon the other end registering the repo.against whatever the team already uses?
same window. The drift finding is the detection; the resolution path is
undefined.
writes, claims especially? See the risks above.
is a reserved version released back, or held?
upgrade land for a team that cannot restart everybody at once?
exists.
Blocked on #117.