@nidvue/teamwork 0.0.0-stage → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +343 -0
  2. package/LICENSE +661 -0
  3. package/NOTICE +16 -0
  4. package/README.md +462 -2
  5. package/SECURITY.md +64 -0
  6. package/package.json +71 -4
  7. package/prompts/teamwork-pulse.md +12 -0
  8. package/prompts/teamwork-review.md +16 -0
  9. package/skills/teamwork/AGENTS.md +462 -0
  10. package/skills/teamwork/SKILL.md +795 -0
  11. package/skills/teamwork/references/Adapters.md +112 -0
  12. package/skills/teamwork/references/Audit.md +120 -0
  13. package/skills/teamwork/references/Concurrency.md +160 -0
  14. package/skills/teamwork/references/Dissent.md +85 -0
  15. package/skills/teamwork/references/Docs.md +74 -0
  16. package/skills/teamwork/references/Engineering.md +410 -0
  17. package/skills/teamwork/references/Evidence.md +140 -0
  18. package/skills/teamwork/references/Remotes.md +144 -0
  19. package/skills/teamwork/references/Roles.md +201 -0
  20. package/skills/teamwork/references/State.md +64 -0
  21. package/skills/teamwork/references/Testing.md +144 -0
  22. package/skills/teamwork/roles/architect.md +153 -0
  23. package/skills/teamwork/roles/ceo.md +218 -0
  24. package/skills/teamwork/roles/cfo.md +150 -0
  25. package/skills/teamwork/roles/coo.md +147 -0
  26. package/skills/teamwork/roles/cto.md +162 -0
  27. package/skills/teamwork/roles/data-engineer.md +120 -0
  28. package/skills/teamwork/roles/designer.md +349 -0
  29. package/skills/teamwork/roles/developer.md +166 -0
  30. package/skills/teamwork/roles/product-manager.md +151 -0
  31. package/skills/teamwork/roles/project-manager.md +159 -0
  32. package/skills/teamwork/roles/release-engineer.md +245 -0
  33. package/skills/teamwork/roles/reviewer.md +254 -0
  34. package/skills/teamwork/roles/security-auditor.md +157 -0
  35. package/skills/teamwork/roles/technical-writer.md +121 -0
  36. package/skills/teamwork/roles/tester.md +180 -0
  37. package/skills/teamwork/scripts/build_pi_package.py +200 -0
  38. package/skills/teamwork/scripts/privacy_scan.py +1185 -0
  39. package/skills/teamwork/scripts/sync_skill.py +108 -0
  40. package/skills/teamwork/scripts/teamwork.py +28 -0
  41. package/skills/teamwork/scripts/verify_release.py +502 -0
  42. package/skills/teamwork/src/teamwork/__init__.py +18 -0
  43. package/skills/teamwork/src/teamwork/__main__.py +10 -0
  44. package/skills/teamwork/src/teamwork/bundle.py +157 -0
  45. package/skills/teamwork/src/teamwork/cli.py +16 -0
  46. package/skills/teamwork/src/teamwork/config.py +396 -0
  47. package/skills/teamwork/src/teamwork/engine.py +10119 -0
  48. package/skills/teamwork/src/teamwork/gitutil.py +172 -0
  49. package/skills/teamwork/src/teamwork/imaging.py +124 -0
  50. package/skills/teamwork/src/teamwork/io.py +144 -0
  51. package/skills/teamwork/src/teamwork/layout.py +253 -0
  52. package/skills/teamwork/src/teamwork/names.py +191 -0
  53. package/skills/teamwork/src/teamwork/portable.py +79 -0
  54. package/skills/teamwork/src/teamwork/records.py +1220 -0
  55. package/skills/teamwork/src/teamwork/resources.py +120 -0
  56. package/skills/teamwork/src/teamwork/version.py +13 -0
  57. package/skills/teamwork/templates/AGENTS.md +460 -0
  58. package/skills/teamwork/templates/Docs/Architecture.md +40 -0
  59. package/skills/teamwork/templates/Docs/Archive.md +8 -0
  60. package/skills/teamwork/templates/Docs/Board.md +28 -0
  61. package/skills/teamwork/templates/Docs/Costs.md +30 -0
  62. package/skills/teamwork/templates/Docs/Decisions.md +26 -0
  63. package/skills/teamwork/templates/Docs/Design.md +106 -0
  64. package/skills/teamwork/templates/Docs/Plan.md +24 -0
  65. package/skills/teamwork/templates/Docs/Project.md +40 -0
  66. package/skills/teamwork/templates/Docs/Release.md +43 -0
  67. package/skills/teamwork/templates/Docs/Research.md +36 -0
  68. package/skills/teamwork/templates/Docs/Risks.md +18 -0
  69. package/skills/teamwork/templates/TeamMap.md +100 -0
  70. package/skills/teamwork-pi/SKILL.md +77 -0
@@ -0,0 +1,112 @@
1
+ # Adapters - running the team on any agent host
2
+
3
+ The team is a **protocol**, not a product feature. Everything normative in this
4
+ skill - the workspace format, acceptance-criteria records, the two-stage gate,
5
+ the hash-chained ledger, the test-layer matrix, `AGENTS.md` - is host-independent
6
+ and lives in files the team owns. Only six operations need a host to provide a
7
+ mechanism, and this file maps each one to the concrete tool of a given host.
8
+
9
+ Never hard-code a host tool in a normative step. Name the operation, then use the
10
+ adapter. If a host cannot provide an operation, use its documented degraded mode -
11
+ the gates still hold, only the concurrency drops.
12
+
13
+ This file is the only **adoption surface** that names a concrete host. Every other surface
14
+ (`SKILL.md`, README, install guide, quickstart) describes one generic protocol and
15
+ points here, so a new host is a new column, never a rewrite of the instructions.
16
+
17
+ ## The six operations
18
+
19
+ | # | Operation | What the team needs |
20
+ |---|---|---|
21
+ | 1 | **Spawn a teammate** | start a long-lived agent with a persona and its own context |
22
+ | 2 | **Delegate one-shot work** | run a bounded, isolated task and take its result |
23
+ | 3 | **Message an agent** | send a direct or broadcast instruction |
24
+ | 4 | **Inspect teammate state** | see who is idle, busy, stuck; read their last output |
25
+ | 5 | **Re-wake on a schedule** (pulse) | periodic trigger to feed idle lanes |
26
+ | 6 | **Close the team** | stop the teammates and release the lanes |
27
+
28
+ ## Host mapping
29
+
30
+ | Operation | Pi | Claude Code | opencode | Codex / Cursor / Windsurf / Gemini CLI | Generic (no agent runtime) |
31
+ |---|---|---|---|---|---|
32
+ | 1 spawn | `subagent({agent, task})` - one call per lane, `async: true` keeps the CEO free while it runs; a *persistent* teammate needs a teams-style extension, the default host gives bounded runs | `Agent`/`Task` tool with a `.claude/agents/<name>.md` persona | `.opencode/agent/<name>.md` + the Task tool | run the CLI as a subprocess (`codex exec`, `cursor-agent`) | `bash` background process + a prompt file |
33
+ | 2 one-shot | `subagent({agent,task})` | `Task` tool, single agent | Task tool / a separate `opencode run` | `codex exec "<task>"` | one `bash` invocation, result to a file |
34
+ | 3 message | child to parent: `contact_supervisor` / `subagent_supervisor({action:"reply"})`; parent to child: `subagent({action:"steer"/"resume", id, message})` | `SendMessage` / prompt injection | agent-to-agent message | write to the agent's inbox file | append to `Agents/<Name>/Inbox.md` |
35
+ | 4 inspect | `subagent({action:"status", id})` and `subagent_supervisor({action:"list"/"pending"})` for the runs | agent status / task list | session list | process list + worklog | `teamwork.py board` + `pulse` + `WorkLog.md` |
36
+ | 5 pulse | `subagent({action:"schedule.create", options:{every:"5m"}})` | no built-in scheduler: `Bash` background loop, `/loop`, or host `cron` running `claude -p` | no scheduler: `cron`/systemd running `opencode run` | host `cron` / `watch` / CI schedule | `cron`, `systemd` timer, or a `while` loop running `teamwork.py pulse --commit` |
37
+ | 6 close | a bounded run ends with its own task; stop a live one with `subagent({action:"stop", id})` and list what still runs with `subagent_supervisor({action:"list"})` | stop the subagents / end the session | stop sessions | kill the processes | `pkill` the lanes, `teamwork.py clean` |
38
+ | skill install | `~/.pi/agent/skills/<name>/SKILL.md` | `.claude/skills/<name>/SKILL.md` (Agent Skills format - this file already matches: `name` + `description` frontmatter) | `AGENTS.md` + `.opencode/command/<name>.md` | `AGENTS.md` (every one of these reads it) | `AGENTS.md` + this directory |
39
+
40
+ The Pi column was verified against the installed `pi-subagents` package on
41
+ 2026-10-19 (pi 1.3.0): it exposes `subagent`, `subagents_enable`,
42
+ `subagent_supervisor`, `contact_supervisor` and `structured_output`, and **no
43
+ `teams(...)` tool**. A host that does provide a teams-style tool maps the same
44
+ four operations to
45
+ `teams({action:"delegate"/"message_dm"/"member_status"/"team_done"})`.
46
+
47
+ `AGENTS.md` at the project root is the universal contract: Claude Code, opencode,
48
+ Codex, Cursor, Windsurf, Gemini CLI, Aider and Pi all read it. Write the team
49
+ constitution there once (`teamwork.py agents-md`) and every host inherits it.
50
+
51
+ ## Degraded modes (still complete, just slower)
52
+
53
+ - **No scheduler** (operation 5): run `teamwork.py pulse --commit` on a host `cron`
54
+ entry, or have the CEO re-issue the pulse prompt at milestones, or simply have
55
+ each lane self-serve with `teamwork.py task next <name>` between turns. The rule
56
+ "never let an idle lane sit while runnable work exists" is unchanged; only the
57
+ automation of the wake-up differs.
58
+ - **No teammate tool** (operation 1/2): the same role charters are executed
59
+ sequentially by one agent that switches hats, claiming tasks from the same
60
+ shared queues. The evidence gates, the Reviewer separation and the ledger are
61
+ unaffected - which is the point: the protocol does not depend on parallelism.
62
+ - **No message tool** (operation 3): the mailbox is already a file
63
+ (`Agents/<Name>/Inbox.md`); writing to it is a valid message on every host.
64
+ - **No `teams` tool**: spawn with the host's own CLI in a `bash` job and point it
65
+ at `Agents/<Name>/StartHere.md` - the startup routine is identical.
66
+ - **Only bounded runs** (Pi's `subagent`, a CLI job): fan the lanes out as
67
+ concurrent calls instead of persistent teammates - one Reviewer instance per
68
+ call, each starting from its own `StartHere.md`. Bounded runs cannot see each
69
+ other, so the **board is what keeps them apart**: the CEO fans deliverables out
70
+ with `pulse --commit` and every lane takes work with
71
+ `review ... --claim --by <lane>` / `task next`, which is exactly why a claim is
72
+ a record and not a handshake. Two Reviewer lanes that skip the claim will
73
+ review the same deliverable twice.
74
+
75
+ ## Host detection also drives model routing
76
+
77
+ The same detection that picks the adapter picks the model: `teamwork.py model auto`
78
+ reads the host (pi, claude, opencode, codex, cursor, gemini) and the model that host
79
+ exposes, then routes the strongest available model to the decision lanes and the
80
+ economy model to the mechanical lanes; `TEAMWORK_AGENT_HOST` pins the detection when
81
+ the markers are ambiguous. Policy: [Concurrency](Concurrency.md).
82
+
83
+ ## The skill copy is the thing that runs
84
+
85
+ Every host reads a *copy* of this skill from its skills directory, so the copy has
86
+ to follow the remote. One command owns that on every host:
87
+
88
+ ```sh
89
+ teamwork refresh # fetch origin/main, then mirror into the host's skills dir
90
+ teamwork refresh --check # drift only, writes nothing, exit 1 when stale
91
+ teamwork refresh --dest ~/.agents/skills/teamwork # another host's directory
92
+ teamwork refresh --mirror --repo <url> # no checkout yet: create the mirror once
93
+ ```
94
+
95
+ Measured failure this prevents: a host copy with an old `SKILL.md` and eight
96
+ engine modules missing - the engine imported `config`/`gitutil`/`records` fine
97
+ from the checkout and failed from the installed copy. A dirty checkout is
98
+ mirrored, never reset; files the source dropped are deleted; a host reload is
99
+ required after a write and the command says so.
100
+
101
+ ## Rules
102
+
103
+ 1. **The engine is the constant.** `teamwork.py` (stdlib only, Python 3.9-3.13) is
104
+ the only thing a host must be able to run. It never calls a host API.
105
+ 2. **State lives in git and in `.pi/`.** Nothing important lives in a host's
106
+ private memory: a teammate that dies and is respawned on another host resumes
107
+ from `StartHere.md`, the task queue and the ledger.
108
+ 3. **One voice to the user** stays true on every host: only the CEO reports.
109
+ 4. **A missing capability is not a red line.** Record the adapter used and the
110
+ degradation in the task evidence; never fake a tool call that the host lacks.
111
+ 5. **Adding a host** means adding a column here plus a smoke test that the six
112
+ operations exist in some form - not changing the protocol.
@@ -0,0 +1,120 @@
1
+ # Recording, traceability and audit
2
+
3
+ Reference for the /teamwork skill. Loaded on demand.
4
+
5
+ Related: [Evidence](Evidence.md) | [Roles](Roles.md) | [Engineering](Engineering.md) | [State](State.md) | [Docs](Docs.md) | [Testing](Testing.md) | [Concurrency](Concurrency.md)
6
+
7
+ ## What is recorded
8
+
9
+ Every piece of state is a record with provenance, not a note in a chat:
10
+
11
+ | Record | Where | Provenance |
12
+ |---|---|---|
13
+ | Memory entry | `Roles/<Role>/ShortTermMemory.md`, `LongTermMemory.md` | `by`, `src`, `rev` on every entry |
14
+ | Task | `Roles/<Role>/TaskQueue.md` | `claimed_by`, `branch`, `pr`, `area`, `evidence`, `reviewer`, `merge_commit`, `forced` |
15
+ | Acceptance criterion | `Criteria.md` | owner + the verifying instance and its evidence |
16
+ | Test layer | `Tests.md`, `TestPlan.md` | owner role, runner, command, evidence, revision |
17
+ | Review / PR | `Reviews.md` | author, branch, reviewer, verdict, merge revision |
18
+ | Dispute | `Disputes.md` | raiser, opponent, every round, signatures, ruling |
19
+ | Decision | `docs/Team/Decisions.md` | decider, evidence, falsifier, consequences |
20
+ | Accepted result | `docs/Team/Archive.md` | what shipped, by which instance, verified how, at which revision |
21
+ | **Every mutation** | `Ledger.jsonl` | timestamp, actor, role, action, target, detail, revision |
22
+
23
+ Nothing is written without naming who wrote it and what it came from.
24
+
25
+ ## The ledger
26
+
27
+ `Ledger.jsonl` is append-only. Each line is one record:
28
+
29
+ ```json
30
+ {"ts":"2026-10-17T20:08:43","n":7,"actor":"developer-1","role":"developer",
31
+ "action":"commit","target":"T-0001","detail":"feat(auth): src/auth.py | 2 file(s) e257f69",
32
+ "rev":"e257f69","prev":"<hash of record 6>","hash":"<sha256(prev + canonical record)>"}
33
+ ```
34
+
35
+ `hash = sha256(prev_hash + canonical_json(record))`, so records are chained: editing
36
+ or deleting any line breaks every hash after it.
37
+
38
+ Actions cover the whole lifecycle: `memory.add|update|promote|drop|merge|evict`,
39
+ `task.add|claim|status|evidence|reclaim`, `selfcheck`, `review.pass|fail`,
40
+ `pr.open|merge`, `branch.start|retire`, `criteria.add|verify`, `tests.add|run`,
41
+ `dispute.open|round|escalate|sign|resolve`, `decision.add`, `commit`, `ledger.export`.
42
+
43
+ Memory maintenance is logged too, so a fact never disappears silently: promotion,
44
+ dropping, key-merging and archive eviction each write a record with the entry key.
45
+
46
+ ## Internal audit
47
+
48
+ ```sh
49
+ teamwork.py trace <T-id|AC-id|TS-id|P-id> # one claim, end to end
50
+ teamwork.py ledger show --tail 40 [--action review.pass] [--actor reviewer-1]
51
+ teamwork.py ledger verify # recompute the chain
52
+ teamwork.py audit # trail health + provenance + coverage
53
+ teamwork.py loop # a broken trail blocks STOP
54
+ ```
55
+
56
+ `trace` joins the task, its commits, the PR, the review, the tests, the criteria and
57
+ the ledger events into one chronological view: claim -> evidence -> commit -> review
58
+ -> merge -> archive.
59
+
60
+ `audit` reports: chain problems, memory entries without `by` provenance, decisions
61
+ without evidence, a ledger that shrank since the last export, plus the usual gates,
62
+ coverage and branch checks.
63
+
64
+ ## External audit
65
+
66
+ `teamwork.py ledger export` writes two committed artifacts that a third party can
67
+ check **without trusting the team**:
68
+
69
+ - `docs/Team/AuditManifest.json` - team, project, git revision and branch, ledger
70
+ record count and head hash, a sha256 digest for every committed state artifact
71
+ except `docs/Team/Archive.md` (append-only: it gains an entry when a review
72
+ passes, so a digest committed beside it would be stale by construction; its
73
+ entries are followed through the ledger), and the exact verification steps.
74
+ - `docs/Team/AuditReport.md` - the human summary of the same facts.
75
+
76
+ Verification procedure (reproducible by anyone with the repository):
77
+
78
+ ```sh
79
+ teamwork.py ledger verify --reconcile # recompute the chain; a head cache left
80
+ # behind by a crash is repaired, a removal
81
+ # of records is reported
82
+ teamwork.py ledger repair --by <instance> --reason "<why>" # drop a torn tail
83
+ sha256sum -c <(jq -r '.artifacts[] | "\(.sha256) \(.path)"' docs/Team/AuditManifest.json)
84
+ git cat-file -t <git.head> # the reviewed revision still exists
85
+ teamwork.py trace <T-id> # follow any individual claim
86
+ ```
87
+
88
+ What each check proves:
89
+
90
+ | Check | Proves |
91
+ |---|---|
92
+ | hash chain + head hash | the trail was not edited, reordered or truncated after export |
93
+ | `verify --reconcile` | a crash artefact is distinguishable from tampering: a stale cache is repaired, a *shrinking* ledger is reported |
94
+ | `ledger repair` | a torn tail is recoverable, and the repair itself is a logged record |
95
+ | artifact digests | the records themselves are byte-identical to the reviewed state |
96
+ | git revision | the work that was accepted is the work that exists |
97
+ | per-record provenance | every claim can be attributed to an instance, a role and a revision |
98
+
99
+ The manifest separates **externally verifiable** artifacts (committed project
100
+ output under `docs/Team/`) from **local_state** (hidden working state under
101
+ `.pi/`, only checkable on the machine that produced it). The export records its own
102
+ `ledger.export` event *before* capturing the checkpoint, so `ledger verify` after
103
+ an export matches the manifest exactly.
104
+
105
+ `AuditManifest.json` should be committed with the milestone it covers (the Reviewer
106
+ can include it in the `chore(records)` commit), so the head hash becomes a
107
+ checkpoint in git history - and a later truncation of the ledger is then detected
108
+ by comparing against it.
109
+
110
+ ## Honest limits
111
+
112
+ - The ledger is tamper-**evident**, not tamper-**proof**: anyone with write access
113
+ can rebuild it, but they cannot reproduce the exported head hash without also
114
+ rewriting the committed manifest, and the manifest's git history is append-only.
115
+ - Identity is accountability, not cryptography: `--by` names an existing instance,
116
+ and every action it performs is recorded against it. It does not prove which OS
117
+ process typed the command.
118
+ - A record proves that something was declared, with the evidence that was given.
119
+ Whether the evidence proves the claim is what the Reviewer and `criteria verify`
120
+ are for: both require an independent role.
@@ -0,0 +1,160 @@
1
+ # Concurrency and reuse
2
+
3
+ Reference for the /teamwork skill. Loaded on demand; `SKILL.md` keeps the
4
+ operating procedure.
5
+
6
+ Related: [Engineering](Engineering.md) | [Evidence](Evidence.md) | [Docs](Docs.md) | [State](State.md) | [Concurrency](Concurrency.md) | [Roles](Roles.md) | [Testing](Testing.md) | [Audit](Audit.md)
7
+
8
+ ## Concurrency budget and resource reuse
9
+
10
+ Run everything as parallel as the providers allow, never past their caps.
11
+
12
+ | Provider | Concurrent agents | Use it for |
13
+ |---|---|---|
14
+ | Ollama Cloud | 64 | focused reasoning lanes: architecture, review, disputes, analysis |
15
+ | DeepSeek official API | ~2500 | wide independent fanout: many developer/tester/designer sub-tasks, bulk docs and research |
16
+
17
+ Caps live in `.pi/Teamwork/Teams/<Team>/Settings.json` and are overridable with
18
+ `TEAMWORK_PROVIDER_LIMITS="ollama-cloud=64,deepseek=2500"`.
19
+
20
+ ### Slots are leases
21
+
22
+ Every model-heavy task holds a lease in `.pi/Teamwork/Teams/<Team>/Runtime/Slots/<provider>/`.
23
+ Leases expire after `TEAMWORK_SLOT_TTL_MINUTES` (90) so a crashed lane cannot
24
+ leak capacity.
25
+
26
+ ```sh
27
+ teamwork.py slot acquire --agent developer-3 --provider deepseek --task T-0012
28
+ teamwork.py slot renew --agent developer-3 # every ~60 min on long work
29
+ teamwork.py slot release --agent developer-3
30
+ teamwork.py slot list # used / cap / free per provider
31
+ teamwork.py slot reap # expire dead leases
32
+ ```
33
+
34
+ At the cap, `slot acquire` fails with exit 3 instead of blocking. The lane then
35
+ does work that needs no slot (read, plan, review a peer's output), fans out on
36
+ another provider, or waits for a lane to release - it never stalls the team.
37
+
38
+ ### Plan the parallelism
39
+
40
+ ```sh
41
+ teamwork.py parallel
42
+ # - focused reasoning lanes (ollama-cloud): 7 free
43
+ # - bulk fanout lanes (deepseek): 2496 free
44
+ # - start up to 7 new lane(s) now (ready tasks: 12)
45
+ # - 3 lane(s) already hold a slot: hand the next task to a running lane first
46
+ # - independent sub-tasks only: one writer per file
47
+ ```
48
+
49
+ The CEO uses this before every dispatch round: fill every free slot with
50
+ independent ready work, and scale `developer-N` / `tester-N` / `designer-N`
51
+ instances to the available capacity rather than to a fixed number.
52
+
53
+ ### Work-in-progress, not lane count, is the throughput
54
+
55
+ A lane that holds one task and waits for its review is idle capacity. The engine
56
+ therefore schedules on **capacity**, not on idleness:
57
+
58
+ | Concept | Default | Where |
59
+ |---|---|---|
60
+ | `LANE_WIP` - units one lane may hold (`doing` + `selfcheck`) | 2 | `engine.LANE_WIP` |
61
+ | Reviewer claims per lane | 1 | `review --claim` lease |
62
+ | Provider capacity | `Settings.json` (`ollama-cloud` 64, `deepseek` 2500) | `parallel`, `pulse` |
63
+
64
+ `task next <lane> --capacity N` claims N executable tasks at once; `pulse
65
+ --commit` tops every lane back up to its limit and refuses to plan more work than
66
+ there are free provider slots, printing the shortfall. A claim that is still live
67
+ blocks its lane; an expired claim is open for take-over, which is exactly what the
68
+ next pulse hands out.
69
+
70
+ ### Stream the dependencies
71
+
72
+ `deps: role:T-id` waits for `done` and is the slowest possible edge. Two earlier
73
+ release points exist and should be used for every contract-shaped dependency:
74
+
75
+ | Dep form | Releases when | Use it for |
76
+ |---|---|---|
77
+ | `role:T-id@started` | the owner has picked the task up | shadow work, fixtures, environment setup |
78
+ | `role:T-id@review` | the work is submitted for review | testing and docs against a frozen interface |
79
+ | `role:T-id` (default) | the task is `done` and merged | anything that needs the merged artifact |
80
+
81
+ Using `@review` on every interface dependency is what lets the tester, the writer
82
+ and the next developer start in the same hour rather than after a full review
83
+ cycle.
84
+
85
+ ### Reuse before you recompute
86
+
87
+ - Reuse a **running lane** before spawning a new one - the teammate already holds
88
+ its memory, role and context.
89
+ - Reuse **evidence**: if a verification already passed on the same revision, cite
90
+ it (`BUILD ECONOMY`) instead of re-running.
91
+ - Reuse **research and artifacts**: read global memory, long-term memory and
92
+ `docs/Team/` before producing anything new; update in place, never duplicate.
93
+ - Reuse **build/test caches**; never rebuild from scratch for a clean slate.
94
+ - Reuse **the same artifact across lanes**: a frozen interface, fixture or script
95
+ is shared, not re-created per task.
96
+ - Deduplicate before dispatch: `teamwork.py audit` flags near-identical tasks.
97
+
98
+ ### Parallelism rules (non-negotiable)
99
+
100
+ - One writer per file/worktree. Concurrency never means two agents editing the
101
+ same file.
102
+ - Only independent tasks run together; dependent tasks queue on their `deps`.
103
+ - The Reviewer, the Project Manager and the CEO are lanes too - keep them fed.
104
+ - **Review concurrency is the number of lanes, not the depth of the queue.**
105
+ `pulse --commit` fans unclaimed deliverables out one per idle Reviewer lane and
106
+ records a `review.claim` lease (`SlotTtlMinutes`, default 90 min) on each: the
107
+ holder counts as busy, another lane is refused while the lease is live, a verdict
108
+ or `--release` clears it, and an expired lease is open for take-over. So staff at
109
+ least `reviewer-1` and `reviewer-2`, and never stack the backlog on one lane.
110
+ - Never exceed a provider cap to "go faster": the extra lanes fail, and the
111
+ failure costs more than the parallelism gains.
112
+
113
+
114
+ ## Per-agent model configuration
115
+
116
+ The skill does **not** ship a model and does not call an LLM API itself. Each
117
+ agent runs through the host's own API, so the model is a property of the *agent*,
118
+ not of the project, and every lane can pick one independently:
119
+
120
+ ```sh
121
+ teamwork.py model set reviewer --provider anthropic --model <strong> # role default
122
+ teamwork.py model set developer-1 --provider deepseek --model <cheap> # instance override
123
+ teamwork.py model get developer-1
124
+ teamwork.py model list
125
+ ```
126
+
127
+ - An **instance** setting wins over the **role** default; an unset agent uses the
128
+ host's own default and records `unset`.
129
+ - Give the reasoning-heavy lanes the stronger model (Reviewer, Architect,
130
+ Security Auditor) and the mechanical ones a cheaper or faster one (bulk edits,
131
+ formatting, link checks). Cost and latency are a per-lane choice, not a global one.
132
+ - A model change is a recorded act (`Settings.json` + the ledger); the CEO sets the
133
+ lanes at intake, and an agent never changes another agent's model.
134
+ - Model choice never changes the protocol: the evidence gates, the two-stage
135
+ review and the ledger hold whatever model produced the work.
136
+
137
+ ### Automatic cost-aware routing
138
+
139
+ ```sh
140
+ teamwork.py model auto # dry run: the plan, per lane
141
+ teamwork.py model auto --apply # write it into Settings.json
142
+ teamwork.py model auto --json
143
+ ```
144
+
145
+ `model auto` reads the *runtime environment* - which agent host is running (Pi,
146
+ Claude Code, opencode, Codex, Cursor, Gemini CLI) and which model that host already
147
+ exposes - and routes **the strongest available model to the lanes where a mistake
148
+ is expensive** (Reviewer, Architect, Security Auditor, CEO, CTO) and **the economy
149
+ model to the mechanical lanes** (developers, testers, writers, formatting, link
150
+ checks). Quality where it compounds, cheapness where it does not.
151
+
152
+ - It never invents a model id: `TEAMWORK_MODEL_STRONG` (or the host's own
153
+ `ANTHROPIC_MODEL` / `PI_MODEL` / `OPENCODE_MODEL` / ...) supplies the strong tier,
154
+ `TEAMWORK_MODEL_ECONOMY` the cheap one, and a lane with neither is reported as
155
+ `unset` together with the variable to set.
156
+ - `--apply` is explicit: the plan is a dry run by default, and applying it is
157
+ recorded in the ledger.
158
+ - Re-run it when the host or the budget changes; it is idempotent.
159
+ - `TEAMWORK_AGENT_HOST=claude|pi|opencode|codex|cursor|gemini` overrides
160
+ detection when the markers are ambiguous (CI, wrapper scripts).
@@ -0,0 +1,85 @@
1
+ # Decisions, dissent and the tribunal
2
+
3
+ Reference for the /teamwork skill. Loaded on demand; `SKILL.md` keeps the
4
+ operating procedure.
5
+
6
+ Related: [Engineering](Engineering.md) | [Evidence](Evidence.md) | [Docs](Docs.md) | [State](State.md) | [Concurrency](Concurrency.md) | [Roles](Roles.md) | [Testing](Testing.md) | [Audit](Audit.md)
7
+
8
+ ## Decision and dissent protocol
9
+
10
+ The team's decisions are independent and evidence-based, not consensus by
11
+ deference.
12
+
13
+ **Every agent decides independently.** A decision is only valid with an evidence
14
+ chain: claim, data/measurement (command, file, benchmark, revision, source+date),
15
+ reasoning from evidence to conclusion, rejected alternatives, the bet you are
16
+ making, and the test that would falsify it. "I think", "should be fine" and
17
+ "best practice" are not evidence. Prefer measuring over debating; when a
18
+ measurement is impossible, label the decision provisional.
19
+
20
+ **Dissent is mandatory, not optional.** An agent that finds a design or decision
21
+ unreasonable must challenge the owner with counter-evidence instead of silently
22
+ complying or working around it:
23
+
24
+ ```sh
25
+ python3 "$SKILL/scripts/teamwork.py" dispute open \
26
+ --by developer-1 --against architect --topic "sync DB calls in request path" \
27
+ --position "will not meet the p99 target" \
28
+ --evidence "bench: 12ms/query x8 = 96ms @abc123 > 50ms budget" --task T-0007
29
+ python3 "$SKILL/scripts/teamwork.py" dispute round D-0001 --by architect \
30
+ --message "pooling measured at 14ms total @def456"
31
+ ```
32
+
33
+ **3-round cap, then the tribunal.** The two agents get at most three rounds. If
34
+ they still disagree, the dispute escalates to the **CEO + CTO + CFO tribunal**,
35
+ which discusses it and issues a final, binding ruling:
36
+
37
+ ```sh
38
+ python3 "$SKILL/scripts/teamwork.py" dispute escalate D-0001 --by developer-1
39
+ python3 "$SKILL/scripts/teamwork.py" dispute sign D-0001 --by ceo # and cto, cfo
40
+ python3 "$SKILL/scripts/teamwork.py" dispute resolve D-0001 --by ceo \
41
+ --decision "pool + 20ms timeout + load-test gate"
42
+ ```
43
+
44
+ The tool enforces this: a 4th round is refused, an escalated dispute cannot be
45
+ resolved until all three tribunal members have signed, and `audit` flags any open
46
+ dispute at the round cap. The ruling is recorded in `docs/Team/Decisions.md` and
47
+ is final - the losing side implements it and says so in its report. A dispute
48
+ never blocks unrelated work; keep going on everything not contested.
49
+
50
+ ## Parallel lanes
51
+
52
+ The team is a set of lanes, not a queue:
53
+
54
+ - **Lane 0 (blocking, short):** requirements -> acceptance criteria -> frozen
55
+ interfaces -> task graph. Everyone else starts the moment this lands.
56
+ - **Lane A (code):** developers implement against the contract; unit tests are
57
+ part of each change.
58
+ - **Lane B (verification):** testers build integration/E2E suites from the same
59
+ contract in parallel with implementation, then run and monitor them.
60
+ - **Lane C (design):** designers produce specs and copy from the contract, then
61
+ review the merged UI.
62
+ - **Lane D (research/ops/cost):** PM research, COO risk and process, CFO cost,
63
+ running continuously and feeding lanes A-C.
64
+ - **Lane E (docs):** produced from merged code, scheduled last, never a gate.
65
+
66
+ Rules: one writer per file/worktree; interfaces frozen before parallel writers
67
+ start; interface changes require a `Decisions.md` entry plus notification to
68
+ every dependent lane; a lane that finishes takes the next unblocked task instead
69
+ of waiting.
70
+
71
+ ## Failure handling
72
+
73
+ - **Infrastructure failure** (spawn, tool, provider): stop the lane, record the
74
+ exact error, worktree state and partial diff, retry once cleanly, then report
75
+ to the CEO. Never silently switch execution mode.
76
+ - **Blocked on a dependency**: mark the task `blocked` with the exact unblock
77
+ action and owner, tell the Project Manager, and take other executable work.
78
+ - **Blocked on the user**: CEO asks one consolidated question; the lane keeps
79
+ working elsewhere meanwhile.
80
+ - **Contradictory evidence**: escalate to the CEO; record the resolution in
81
+ `Decisions.md` and global memory.
82
+ - **Repeated failure of the same task**: the CEO re-scopes, splits, or reassigns;
83
+ it is never marked done to make the board look green.
84
+ - **Red-line refusal**: expected and correct behaviour. Record it, escalate, and
85
+ continue with the rest of the plan.
@@ -0,0 +1,74 @@
1
+ # Documentation standard
2
+
3
+ Reference for the /teamwork skill. Loaded on demand; `SKILL.md` keeps the
4
+ operating procedure.
5
+
6
+ Related: [Engineering](Engineering.md) | [Evidence](Evidence.md) | [Docs](Docs.md) | [State](State.md) | [Concurrency](Concurrency.md) | [Roles](Roles.md) | [Testing](Testing.md) | [Audit](Audit.md)
7
+
8
+ ## Documentation standard (markdown, structured, linked)
9
+
10
+ Everything the team writes - memory, plans, designs, research, decisions, docs -
11
+ is **markdown**, structured for a human reader, and cross-linked both ways.
12
+ This is enforced: `teamwork.py links` fails on broken links, malformed URLs, bare
13
+ URLs and missing back-links, and `audit` includes link health.
14
+
15
+ ### Structure
16
+
17
+ - One `# H1` per file; the title states what the document is.
18
+ - A one-line `Owner:` line naming the role that maintains it.
19
+ - A `Related:` line directly under the header with relative links to every
20
+ document it interacts with (see the link graph below).
21
+ - Numbered `##` sections in reading order; `###` only when it earns its depth.
22
+ - Prefer tables and short bullets over paragraphs. One idea per bullet.
23
+ - Mark placeholders as `<like this>` so unfinished sections are obvious.
24
+
25
+ ### Be concise (hard)
26
+
27
+ Saved content is read by humans under time pressure. Every file must be short
28
+ enough to scan.
29
+
30
+ - Lead with the conclusion; put the detail under it, never before it.
31
+ - One fact per line. Prefer a table row or a bullet over a paragraph.
32
+ - Write the smallest text that is still unambiguous. Delete anything the reader
33
+ already knows, any restatement of the brief, and any sentence that only
34
+ announces what the next sentence does.
35
+ - No filler: no "as mentioned above", "it is important to note", "in order to",
36
+ "various", "several", "etc." Lists are exhaustive or they are not lists.
37
+ - Numbers over adjectives: "12ms p99", not "quite fast". `<command> -> <result>`,
38
+ not "we verified it".
39
+ - A memory entry is **one line**: the fact, plus a key. If it needs three
40
+ paragraphs, it belongs in a document, not in memory.
41
+ - Cap each section at roughly one screen. If it grows past that, split the
42
+ document or move detail to a linked file.
43
+ - Rewrite, do not append. Documents and memory entries are kept current, not
44
+ accumulated; stale text is deleted rather than left below new text.
45
+
46
+ ### Links
47
+
48
+ - **External references always carry a direct, working link plus an access date**:
49
+ `- [title](https://full-url) - accessed YYYY-MM-DD`. Never cite a search page,
50
+ a bare domain, or "the docs" without a URL. A claim without a link is
51
+ `UNVERIFIED` and cannot justify a decision.
52
+ - **Internal references are relative markdown links** to the file
53
+ (`[PLAN](Plan.md)`), never absolute paths and never bare file names in prose.
54
+ - **Bidirectional**: if A links to B, B links back to A. Put the back-link in the
55
+ `Related:` line, which is why every shared document has one.
56
+ - Every decision cites the evidence and the documents it affects; every research
57
+ claim cites its source; every task result cites the artifact and the command.
58
+
59
+ ### Link graph (committed docs, every edge bidirectional)
60
+
61
+ ```text
62
+ PROJECT ─ PLAN ─ BOARD ─ ARCHIVE
63
+ │ │ │ │
64
+ │ ├──────┴────────┴── RISKS ─ COSTS
65
+ │ │ │
66
+ ├── ARCHITECTURE ─ DESIGN │
67
+ │ │ │
68
+ ├── RESEARCH ─────────────────┘
69
+ └── DECISIONS (links to ARCHITECTURE, RESEARCH, RISKS, COSTS, ARCHIVE, PLAN)
70
+ ```
71
+
72
+ `teamwork.py links` verifies it. `.pi/` memory files link to `TaskQueue.md`,
73
+ `Role.md`, `ShortTermMemory.md`, `LongTermMemory.md`, global memory and the committed docs
74
+ they inform.