Architecture - Nidvue Teamwork¶
Owner: Technical Writer.
Related: Home · Quickstart · CLI reference · CI pipeline · Team architecture
The frozen interface contract for the engine lives in the team's Architecture.md. This page describes the shipped package and runtime.
Three faces, one engine¶
| Face | Entry point | Contents |
|---|---|---|
| Skill | SKILL.md at the repository root |
SKILL.md, roles/*.md, references/*.md, templates/ |
| Python package | python -m teamwork / teamwork console script |
src/teamwork/ |
| Workspace format | <project>/.pi/Teamwork/Teams/<Team>/ |
Markdown + JSON |
The engine is a port of the original skill monolith with behaviour unchanged; the three faces share it.
Package layout¶
src/teamwork/
├── __init__.py # __version__ and lazy re-exports
├── __main__.py # python -m teamwork -> cli.main()
├── cli.py # build_parser() + main(argv) -> int
├── engine.py # the ported engine (single module)
├── resources.py # locate the skill bundle (checkout or wheel)
├── portable.py # Windows-safe process/path helpers
└── version.py # __version__ = "1.0.0"
scripts/teamwork.py is a thin compatibility shim that adds src/ to
sys.path and calls teamwork.cli.main, so the CLI runs from a checkout with
only the standard library.
Resource resolution¶
The engine needs SKILL.md, roles/, references/, templates/ and a runnable
engine path. resources.skill_root() resolves them in order, first hit wins:
$TEAMWORK_SKILL_DIR- explicit override (tests use it).teamwork/data/- the packaged bundle inside an installed wheel.<repo root>/- a normal git checkout.- The package's parent - a flattened copy next to the bundle.
Frozen public API:
skill_root() -> Path # directory holding SKILL.md + bundle folders
asset(*parts) -> Path # skill_root() joined with parts
self_invocation() -> str # how a teammate should invoke the CLI
has_asset(name: str) -> bool
self_invocation() prefers the teamwork console script, then
python3 scripts/teamwork.py from a checkout, then python -m teamwork.
Workspace format¶
A team's own tree is hidden and gitignored; project output is committed.
<project>/
├── AGENTS.md # team constitution (managed block)
├── docs/Team/ # committed project output
└── .pi/Teamwork/Teams/<Team>/ # hidden, gitignored
├── TeamMap.md Settings.json
├── Criteria.md Tests.md TestPlan.md
├── Reviews.md Disputes.md Skills.md
├── Ledger.jsonl # hash-chained audit trail
├── Global/ # CEO-owned shared memory
├── Roles/<Role>/ # shared by every instance of the role
├── Agents/<Instance>/ # private to one instance
└── Runtime/ # ephemeral locks, slots, worktrees
Memory and the task queue belong to the ROLE, not the instance. Role.md is per
role; only StartHere.md, WorkLog.md, Inbox.md, Artifacts/, Reports/
and Scratch/ are private to an instance.
Ledger¶
Every mutation is appended to Ledger.jsonl. Each record carries the previous
record's digest, so the chain is tamper-evident:
teamwork ledger verifyrecomputes the chain.teamwork ledger exportwrites an externally verifiable manifest.teamwork trace <id>follows one task, criterion, test or PR end to end.- A broken chain blocks
loopfrom reportingSTOP.
The record shape and digest function are frozen: changing them invalidates every existing workspace.
Portability and packaging¶
- Runtime: CPython 3.9 - 3.13 on Linux, macOS and Windows.
- No third-party import at runtime; file I/O is UTF-8 with
\nnewlines for byte-identical output. - Forbidden in the runtime path:
fcntl,termios,pwd,grp,os.fork,resource,shell=Trueand POSIX-only signal use. - Build backend:
hatchling; distributionteamwork-agents; import nameteamwork; console scriptteamwork. - The wheel force-includes the bundle at
teamwork/data/; the release script assertsteamwork/data/SKILL.mdandteamwork/data/templates/AGENTS.mdexist.