A team within the organisation
A team is the durable, cross-functional group that owns a slice of the product end to end: the people who design, build, and run something together, accountable for an outcomeOutcomeStrategyA desired business or user outcomeView reference → rather than a hand-off.
The cross-functional product team displaced the older model of separate design, engineering, and QA departments passing work between them. Amazon's "two-pizza team" rule, the idea that a team should be small enough to feed with two pizzas, became the most quoted heuristic for keeping a group small enough to move fast and stay coordinated. The principle is about communication overhead: every person added multiplies the lines of coordination, and past a point the team spends more energy syncing than shipping.
The sharpest current model is Team Topologies, by Matthew Skelton and Manuel Pais (2019), which names four team types: stream-aligned, platform, enabling, and complicated-subsystem (Team Topologies). A stream-aligned team owns a value streamValue StreamStrategyAn end-to-end flow delivering value to the customerView reference → end to end with no hand-offs; a platform team builds self-service capabilityCapabilityStrategyAn ability that enables value deliveryView reference → that lightens the load on the others; an enabling team boosts a skill and then moves on; a complicated-subsystem team holds deep specialist knowledge (IT Revolution).
The organising idea beneath those types is cognitive load. Skelton and Pais argue you should size and bound a team so the system it owns fits within what the team can actually hold, and use the platform and enabling types to keep stream-aligned teams from drowning. That reframes team design from an org-chart exercise into a question of how much complexity any group can carry, which is where the discipline has landed.
Cagan's Empowered (2020) addresses a parallel question: not how teams are structured but what they are authorised to do. He distinguishes an empowered product team — cross-functional (product manager, designer, engineer), given a problem to solve and accountable for an outcome — from a featureFeatureProduct SpecificationA product capability or featureView reference → team that merely executes a pre-specified roadmapRoadmapProduct SpecificationA strategic plan of features and milestonesView reference →. The empowered model requires the team to address four product risksRiskComplianceA risk to the product or businessView reference → together: value (will anyone choose this?), usability (can they figure it out?), feasibility (can the team build it?), and business viability (does it work for the company?). That four-risk mandate is what makes outcome accountability meaningful rather than nominal; a team handed a backlog of requirements carries none of those risks, which is Cagan's sharpest objectionObjectionGo-To-MarketA common sales objectionView reference → to the feature-team model.
A fifty-engineer product organisation keeps shipping late, and the diagnosis is overload: three stream-aligned teams each own a customer-facing area but also maintain the shared deploymentDeploymentEngineeringA deployment eventView reference → pipeline, the auth system, and the data platform between them. Every team carries extraneous load that has nothing to do with its value stream.
They reorganise on Team Topologies lines. A platform team forms to own deployment and auth, exposing them as self-service so the stream teams stop maintaining infrastructure. An enabling team spends a quarter raising the stream teams' testing practice, then disbands. The data platform, genuinely specialist, becomes a complicated-subsystem team. The stream-aligned teams shed the load that was not theirs, and lead time on customer features drops because each team now reasons about a system that fits inside its head.
departmentDepartmentTeam & OrganisationAn organisational departmentView reference → may contain many teams via department_contains_teamDepartmentcontainsTeamhierarchy, but a department ships nothing on its own; a team does.In the Unified Product Graph, a team is a container in the Operations & Quality region, within the team and organisation domain. A product connects to its team via Productstaffed byTeamhierarchy, and a department holds teams through product_staffed_by_teamDepartmentcontainsTeamhierarchy. Coupling shows through two dependency edges: department_contains_teamDependencydepends onTeamcross-domain names a team a piece of work relies on, and dependency_depends_on_teamDependencyblocksTeamcross-domain names a team held up by an unmet need. Modelling those dependency edges on the team is what surfacesSurfaceExperience DesignA place inside a screen, the features that occupy it, and the rule that decides who wins itView reference → the cognitive-load problem structurally: a team tangled in inbound and outbound dependencies is visibly not the autonomous, stream-aligned unit Team Topologies argues for, and the graph makes that coupling queryable.dependency_blocks_team
Two things about a team changed at 0.33.0. It gained key_prefix, the string a tracker mints citable node keys from (ENTP giving ENTP-1, ENTP-2, and so on), taking over from the same field on the product. The move is not cosmetic. The prefix was always described as the namespace a tracker calls a team, and a product with two teams has two namespaces, which one string on the product could never hold. A product prefix is now ignored whenever any team in the product declares one. The team also became reachable from a person, through Personmember ofTeamsemantic. Between that edge, person_member_of_teamDepartmentcontainsTeamhierarchy above it, and department_contains_teamTeamcontainsTeamhierarchy for nesting, the team is the tier the org chart actually hangs from: departments stay flat by design, and depth is expressed by nesting teams rather than by inventing a division.team_contains_team
Type-specific fields on BaseNode
team_typeenumFunctional area of the team
sizenumberNumber of people on the team
missionstringTeam's mission statement
key_prefixstringPrefix this team mints node keys with (e.g. `"ENTP"`, giving `ENTP-1`, `ENTP-2`, ...). @example "ENTP"
SUPERSEDES `product.key_prefix` FOR THIS PRODUCT, AND NOTHING ELSE (normative, narrowed in 0.34.0). The moment any team declares a prefix, the PRODUCT-LEVEL prefix stops being consulted. A product-level prefix that still resolved would win on order alone, and a multi-team product would then silently mint everything under it, which is the defect this field exists to end. THE CANDIDATE SET IS THE UNION OF DECLARED AND OBSERVED PREFIXES. A declaration adds a candidate; it does not remove one. A prefix stops being offered only when something claims it or when nothing has ever minted under it, and while more than one candidate stands the create surface keeps asking. WHY THIS WAS NARROWED, stated because 0.33.0 shipped the wider reading and an implementer built against it. The paragraph above made ANY declaration replace the candidate set outright, and its own stated rationale is entirely about `product.key_prefix`: a SINGLE STRING, declared once, that cannot represent two teams. An OBSERVED prefix is not that. It is evidence of a namespace already in active use. Suppressing it reproduces the precise defect this field exists to end, inside one product, and does so silently. Measured on the only keyed graph in the estate: it carries two observed prefixes, 370 keys under one and 662 under the other, and declares neither. Under the wider reading, one team declaring the smaller prefix collapses the candidate set to it, the picker disappears, and every later create mints under it, including the 662 keys' worth of work belonging to the other namespace. The sentence over-reached beyond its own reason, and this narrows it back to that reason. Shipped as a CHANGE in 0.34.0 rather than as a patch correction. Read as a correction it is defensible, but implementers had already built to the wider text, and moving a contract under them in a patch is how a patch becomes a surprise. A DECLARED PREFIX IS A CANDIDATE BEFORE IT IS OBSERVED. Candidates derived only from keys that already exist cannot see a team's first create, which is the one that most needs asking about. That is why declaration ADDS to the candidate set; it is not a reason for it to subtract. UNIQUENESS IS PRODUCT-SCOPED, AND A TEAM PREFIX DOES NOT WIDEN IT. The key sequence runs per product across entity types, so two teams in one product share one number line and never collide with each other. A team prefix names a team WITHIN that scope; it does not create a sequence that spans products. MINTING IS PRODUCT-SCOPED (normative, 0.33.0). `team` is `portfolio_shared`, so one team node can be referenced from two products. Minting is not portfolio-scoped with it. The rule, and it is a requirement rather than a recommendation: 1. A portfolio-shared team's prefix is NOT a minting candidate in a second product. The first product a team mints under is the only product that prefix mints in. 2. Refusal is NO-KEY. The node is created without a key. Refusal MUST NOT be an exception: a keyless create is a legal outcome everywhere else in the ladder, and throwing here would break creates that succeed today on every surface. Throwing stays reserved for a broken invariant, not for policy. 3. The rule applies on the MINT path, not the picker path, and it covers the INFERRED case. A prefix that was never requested by anyone, and was derived from keys that already exist in the second product, is refused on the same terms as one a caller named. A guard that only inspects an explicitly requested prefix misses the quiet path, and the quiet path is the one a fixture reproduces. WHY THE SCOPE STOPS AT THE PRODUCT. Key uniqueness is enforced by a `(product_id, key)` index, which permits the same key under two product ids by construction. A prefix that minted in two products would therefore run two independent sequences under one name and hand two different nodes the same citation, with nothing objecting. Portfolio-shared team minting is DEFERRED until a supra-product uniqueness design exists, rather than approximated. HOW RULE 1 IS DECIDED: THE EVIDENCE RULE (normative, 0.34.0). Rule 1 names a first product without saying how a minter knows which one it is. It is decided by EVIDENCE, not by a stored marker: at mint, if any other IN-SCOPE product already holds a key under the prefix, refuse. Evidence is derivable from the graphs themselves, needs no migration, cannot go stale, and cannot disagree with the keys. A durable home marker could do all three, and would mint state for a fact the graph already carries. The cost is stated rather than hidden: evidence is SCOPE-DEPENDENT, which is why the scope is ruled below in the same breath rather than left open. THE UNDECIDABLE CASE: NEITHER MINTS (normative, 0.34.0). When two products already hold keys under one prefix and nothing establishes which was first, NEITHER mints. No tiebreak is invented. Creation order is not recorded, and `max(existing)` measures import volume rather than precedence, so any tiebreak would be a guess wearing a rule, and a silent one, since it would attribute a namespace to a product with nothing to say it was wrong. Refusing both is the NO-KEY outcome rule 2 already sanctions, and it is recoverable: once either product declares the prefix, the other is unambiguous and a backfill can run. WHAT "IN SCOPE" MEANS: ENGINE-DEFINED, WITH A FLOOR AND A CEILING (normative, 0.34.0). The scope over which the evidence rule looks is defined by the engine, bounded on both sides. FLOOR. It MUST include every product the engine can enumerate for this caller. An engine that looks at fewer products than it can see is choosing not to notice a collision it could have seen. CEILING. It MUST NEVER include a product the caller could not otherwise read. A wider read is a cross-tenant information channel: refusing a mint because of a key in a graph the caller cannot see leaks that the graph exists and what is in it. This half is a security constraint and is not negotiable. PORTFOLIO ALTITUDE IS THE WRONG NORMATIVE ALTITUDE, and it was measured rather than argued: deleting the portfolio document changes nothing about minting, because no minter consults the portfolio seam. Stating the invariant there states it where nobody looks. In practice the local engine's scope is every graph in the workspace folder and the cloud engine's is the caller's own product list. THE HONEST CONSEQUENCE, which belongs in the text rather than in a later surprise: the invariant is SCOPE-RELATIVE. Two engines can legitimately disagree about whether one mint is safe, because they can legitimately see different sets of products. That is a real limitation of the evidence rule and the price of the ceiling. IMMUTABLE ONCE ANYTHING HAS MINTED UNDER IT, PER PRODUCT (normative, 0.34.0). Once any key exists under this prefix IN A GIVEN PRODUCT, the declaration cannot be edited for that product. Refusal-shaped and NO-KEY, matching rule 2: never an exception, because a keyless create is legal everywhere else in the ladder. SCOPED PER PRODUCT, NOT PER TEAM, and the reason is that `team` is `portfolio_shared`: a team that has never minted in product B must still be free to declare there. A per-team global lock would strand it. WHAT IT PREVENTS. Without it, a team edits its prefix after four hundred mints and one product silently carries two number lines under two names, with nothing recording that they were ever one sequence. RENAMING STAYS POSSIBLE BY THE HONEST ROUTE: a migration that rewrites the existing keys. That is a deliberate act with a visible cost, which is the difference between renaming a namespace and forking it by accident. THE PICKER MAY OFFER WHAT THE MINT REFUSES, AND THE SURFACE OWNS THE DIVERGENCE (0.34.0). Rule 3 applies on the MINT path and not the picker path, which is deliberate: the picker cannot cheaply know the answer, since knowing it requires reading other products. The consequence is that a surface can present a choice that then fails. The owner is named here rather than left implicit: A CREATE SURFACE THAT OFFERS A PREFIX THE MINT MAY REFUSE MUST BE ABLE TO REPORT THE REFUSAL, AND MUST BE ABLE TO PRESENT NO-KEY AS AN OUTCOME RATHER THAN AS AN ERROR. This is a design obligation on the surface, not a spec mechanic: the spec cannot fix a UX gap and should not pretend to. The union ruling above shrinks the divergence considerably, because the picker now keeps asking in exactly the case that would otherwise resolve wrongly. This rule states the CONTRACT. The behaviour belongs to whatever mints keys, which is not this package: see `UPGBaseNode.key`.
idstringrequiredUnique identifier (UUID)
typeNodeTyperequiredDiscriminator for the entity type
titlestringrequiredDisplay name
descriptionstringOptional detailed description
statusstringLifecycle status
tagsstring[]Freeform tags for filtering
18 edge types connected to this entity.
team_staffed_with_roleteam_targets_team_okrteam_reflects_in_retrospectiveteam_depends_on_dependencyteam_skilled_in_skillteam_practices_ceremonyteam_planned_via_capacity_planteam_decides_decisionteam_contains_teamdependency_blocks_teamdependency_depends_on_teamperson_member_of_teamceremony_involves_teamconstraint_owned_by_teamreport_distributed_to_team1 framework use this entity type.