Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions changes/2026-10-23-issue-59-role-and-team-config/brainstorm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Brainstorm

> **Issue 59 role and team config** · `2026-10-23-issue-59-role-and-team-config` · stage `brainstorm`
> **Optional stage** — skip if one approach is obvious:
> `sdd skip brainstorm -r "single approach is clear"`

## Goal of exploration

-

## Approach A

### Idea

-

### Pros

-

### Cons / risks

-

## Approach B

### Idea

-

### Pros

-

### Cons / risks

-

## Approach C (optional)

### Idea

-

### Pros

-

### Cons / risks

-

## Comparison

| Criterion | A | B | C |
|-----------|---|---|---|
| Complexity | | | |
| Risk | | | |
| Fit to constraints | | | |

## Recommendation for design stage

-

## Open questions (feed clarify / design)

-
30 changes: 30 additions & 0 deletions changes/2026-10-23-issue-59-role-and-team-config/clarify-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Clarify

> **Issue 59 role and team config** · `2026-10-23-issue-59-role-and-team-config` · stage `clarify_design`
> **Optional stage** — skip if nothing is ambiguous:
> `sdd skip clarify_design -r "no open questions"`

## Context

What just finished? What is about to start?

-

## Clarifying questions

1. **Q:**
**A:**

2. **Q:**
**A:**

3. **Q:**
**A:**

## Decisions / constraints captured

-

## Ready for next stage?

- [ ] No blocking unknowns remain (or explicitly accepted risks)
30 changes: 30 additions & 0 deletions changes/2026-10-23-issue-59-role-and-team-config/clarify-intent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Clarify

> **Issue 59 role and team config** · `2026-10-23-issue-59-role-and-team-config` · stage `clarify_intent`
> **Optional stage** — skip if nothing is ambiguous:
> `sdd skip clarify_intent -r "no open questions"`

## Context

What just finished? What is about to start?

-

## Clarifying questions

1. **Q:**
**A:**

2. **Q:**
**A:**

3. **Q:**
**A:**

## Decisions / constraints captured

-

## Ready for next stage?

- [ ] No blocking unknowns remain (or explicitly accepted risks)
30 changes: 30 additions & 0 deletions changes/2026-10-23-issue-59-role-and-team-config/clarify-tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Clarify

> **Issue 59 role and team config** · `2026-10-23-issue-59-role-and-team-config` · stage `clarify_tasks`
> **Optional stage** — skip if nothing is ambiguous:
> `sdd skip clarify_tasks -r "no open questions"`

## Context

What just finished? What is about to start?

-

## Clarifying questions

1. **Q:**
**A:**

2. **Q:**
**A:**

3. **Q:**
**A:**

## Decisions / constraints captured

-

## Ready for next stage?

- [ ] No blocking unknowns remain (or explicitly accepted risks)
55 changes: 55 additions & 0 deletions changes/2026-10-23-issue-59-role-and-team-config/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Design

> **Issue 59 role and team config** · `2026-10-23-issue-59-role-and-team-config`

## Approach

Extend the role file the current parser already reads. Add the new fields as string lists. Leave them off the file when they are empty, so a role created with only a label and a job stays the same shape. Put the team in `.sdd/team.yaml`, validated by a Zod schema in `packages/core/src/role/schema.ts`. Ship templates as files under `packages/core/defaults/teams/<name>/`.

## Team file

```yaml
template: software
branch: bot/{bot}/{change}
rooms:
commit: false
bots:
- name: developer
role: developer
wip: 1
humans:
- name: Ada Lovelace
role_wip:
developer: 2
```

`branch` must include `{bot}`. Bot names are unique. `wip` is a positive integer. `rooms.commit` is the rooms commit switch and is false in every shipped template. `role_wip` is optional. Humans are names compared with `git config user.name` by exact match after trim. Init fills `humans` from that git name only when the template list is empty.

## Commands

| Command | Result |
|---|---|
| `sdd team init --template software` | Writes the team file and each role. Refuses when `.sdd/team.yaml` or any of those role files already exists, and writes nothing in that case. |
| `sdd team show` | Prints the template, branch, rooms switch, bots, humans, and role limits. A matching git name is marked `(you)`. |
| `sdd role create <name> --template software/developer` | Copies that role under the new name. `--name` still works. `--label` and `--job` override the template. |
| `sdd role create --name <name> --label <label> --job <job>` | Unchanged. Label and job stay required when there is no template. |

`developer` matches `software/developer` and `solo/developer`, so the command asks for one of those ids. `product-manager` and `researcher` are unique and work as short names.

## Templates

| Template | Roles |
|---|---|
| software | product-manager, architect, product-owner, dev-lead, developer |
| solo | developer |
| research | researcher |

Each role's `never` list includes accepting a spec. `approvers` contains `human`, which means the people in `team.yaml`.

## Host stubs

`SDD_AGENT_ROLES` gains four lines on each of `sdd`, `sdd-planner`, `sdd-implementer`, and `sdd-reviewer`: Owns, Never, Checks, and Ask when. The previous rules stay. The concise-body check moves from 1200 to 1400 characters because the router stub now carries those four lines.

## Failure

A bad `team.yaml` prints `team.yaml is invalid:` and the first schema path. A missing team prints the init command. An unknown template lists the names that exist.
38 changes: 38 additions & 0 deletions changes/2026-10-23-issue-59-role-and-team-config/feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Feature

> **Issue 59 role and team config** · `2026-10-23-issue-59-role-and-team-config` · 2026-10-23

## Problem / opportunity

A role file only stores a label, a job, and a few flags. Nothing says what the role owns, what it reads, what it produces, or who approves it. There is no team file, so later work cannot tell bots, human approvers, work-in-progress limits, or the branch pattern apart. The four host stubs are two or three lines each.

## Users & value

Someone who wants their own team, not a fixed one, runs one command and gets a working team from a template. They add, remove, or rename roles by editing plain files. Later steps read this config.

## Scope

- Role files at `.sdd/roles/<name>.md` can store job, owns, inputs, outputs, collaborates, reviews, approvers, never, ask_human_when, skills, rules, and goals.
- `.sdd/team.yaml` lists bots, human approvers by name, a work-in-progress limit per bot and optionally per role, the rooms commit switch, and the bot branch pattern.
- `sdd team init --template <name>`, `sdd team show`, and `sdd role create <name> --template <t>`. `sdd role show` already prints a role file.
- Shipped templates: software (product-manager, architect, product-owner, dev-lead, developer, plus a human), solo, and research.
- The host stubs `sdd`, `sdd-planner`, `sdd-implementer`, and `sdd-reviewer` state owns, never, checks, and ask when.

## Non-goals

- Rooms, the router, model selection, evidence by SHA, and approval enforcement. Those are later issues. This change stores the rooms commit switch and does not open a room.
- An `sdd agent create` alias.
- Overwriting an existing team file or an existing role file.

## Success criteria

- `sdd team init --template software` writes `.sdd/team.yaml` and the five role files. A second run writes nothing.
- A human whose name matches `git config user.name` is marked `(you)` by `sdd team show`.
- `sdd role create builder --template product-manager` writes that role. `developer` alone names both software and solo.
- A plain `sdd role create` file does not grow empty list fields. Editing the job keeps owns.
- Each host stub contains Owns, Never, Checks, and Ask when.

## Risks / open questions

- A template role name that already exists blocks the whole init, including roles that are new. That is the chosen fail-before-write rule.
- The approver value `human` means the people listed in `team.yaml`, not a role file of that name.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Local test plan

> **Issue 59 role and team config** · `2026-10-23-issue-59-role-and-team-config`

Node on this machine is v20.19.3. The `EBADENGINE` warning for `engines.node >= 24` is expected.

| # | Check | Expected |
|---|--------|----------|
| 1 | `pnpm --filter @structured-vibe-coding/core exec vitest run src/__tests__/team.test.ts src/__tests__/role.test.ts src/__tests__/agents.test.ts` | Pass. Software init, no overwrite, template create, plain role, stub lines. |
| 2 | `pnpm --filter @structured-vibe-coding/core test` | Pass. |
| 3 | `pnpm --filter @structured-vibe-coding/cli test -- src/__tests__/cli.integration.test.ts` | Pass, including team init and role create from a template. |
| 4 | `pnpm exec biome check` on the touched TypeScript, and `tsc --noEmit` for core and cli | Pass. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Local test results

> **Issue 59 role and team config** · `2026-10-23-issue-59-role-and-team-config`

Node v20.19.3. `EBADENGINE` warnings for `engines.node >= 24` are expected.

| # | Result |
|---|--------|
| 1 | PASS. `team.test.ts`, `role.test.ts`, and `agents.test.ts` — 38 tests, exit 0. |
| 2 | PASS. Full core vitest, 281 tests, exit 0. |
| 3 | PASS. CLI integration, 30 tests, exit 0, including `installs a team template and creates a role from one (#59)`. |
| 4 | PASS. `tsc --noEmit` for core and cli. `biome check` on the touched TypeScript, exit 0. |

The feature workflow's `verify.commands` is empty, so `sdd verify` reports NOT RUN. The checks above are the verification.

Using `sdd` from main (`sdd new`, `sdd next`, `sdd skip`) advanced this change to local verify. No separate CLI defect showed up.
38 changes: 38 additions & 0 deletions changes/2026-10-23-issue-59-role-and-team-config/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
id: 2026-10-23-issue-59-role-and-team-config
title: Issue 59 role and team config
workflow: feature
created: 2026-10-23T09:02:16.874Z
updated: 2026-10-23T09:10:09.436Z
status: in_progress
stage: local_verify
epic: issue-58
depends: []
flags: {}
overrides:
skip_stages:
- clarify_intent
- brainstorm
- clarify_design
- clarify_tasks
gates: {}
extra_stages: []
skipped:
- stage: clarify_intent
reason: The issue states the fields, commands, and templates.
at: 2026-10-23T09:08:43.569Z
- stage: brainstorm
reason: Extend the current role file and add team.yaml. One approach.
at: 2026-10-23T09:08:45.139Z
- stage: clarify_design
reason: The schema, commands, and fail-before-write rule are in design.md.
at: 2026-10-23T09:08:46.981Z
- stage: clarify_tasks
reason: The six tasks name the files and the commands.
at: 2026-10-23T09:08:48.777Z
gates: {}
verify_results:
local_verify:
ok: false
status: not_run
at: 2026-10-23T09:10:09.436Z
results: []
50 changes: 50 additions & 0 deletions changes/2026-10-23-issue-59-role-and-team-config/metrics.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"version": 1,
"phases": [
{
"phase": "intent",
"startedAt": "2026-10-23T09:02:16.874Z",
"endedAt": "2026-10-23T09:08:34.076Z"
},
{
"phase": "clarify_intent",
"startedAt": "2026-10-23T09:08:34.076Z",
"endedAt": "2026-10-23T09:08:43.574Z"
},
{
"phase": "brainstorm",
"startedAt": "2026-10-23T09:08:43.574Z",
"endedAt": "2026-10-23T09:08:45.140Z"
},
{
"phase": "design",
"startedAt": "2026-10-23T09:08:45.140Z",
"endedAt": "2026-10-23T09:08:45.931Z"
},
{
"phase": "clarify_design",
"startedAt": "2026-10-23T09:08:45.931Z",
"endedAt": "2026-10-23T09:08:46.982Z"
},
{
"phase": "tasks",
"startedAt": "2026-10-23T09:08:46.982Z",
"endedAt": "2026-10-23T09:08:47.888Z"
},
{
"phase": "clarify_tasks",
"startedAt": "2026-10-23T09:08:47.888Z",
"endedAt": "2026-10-23T09:08:48.777Z"
},
{
"phase": "implement",
"startedAt": "2026-10-23T09:08:48.777Z",
"endedAt": "2026-10-23T09:08:49.580Z"
},
{
"phase": "local_verify",
"startedAt": "2026-10-23T09:08:49.580Z"
}
],
"requests": []
}
10 changes: 10 additions & 0 deletions changes/2026-10-23-issue-59-role-and-team-config/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Tasks

> **Issue 59 role and team config** · `2026-10-23-issue-59-role-and-team-config`

1. Add the role list fields to the parser and the renderer. Omit empty lists.
2. Add `TeamSchema` and `sdd team init` / `sdd team show`.
3. Ship the software, solo, and research templates under `packages/core/defaults/teams/`.
4. Add `sdd role create <name> --template <id>`, including the ambiguous `developer` name.
5. Add Owns, Never, Checks, and Ask when to the four host stubs.
6. Cover init, refuse-on-existing, template create, plain roles, invalid team files, and the stub lines with Vitest. Document the commands in `docs/reference/cli.md`.
Loading
Loading