A named, dated interval work is scheduled into. Sprints, quarters, PIs and cooldowns are all one type.
A planning cycle is a bounded, dated interval of planned work: a sprint, iteration, quarter, cooldown, or Program Increment. It is the cadence axis the rest of the graph runs on. Where a featureFeatureProduct SpecificationA product capability or featureView reference → or epicEpicProduct SpecificationA large body of work that can be broken into storiesView reference → describes what is built, a planning cycle describes when: which work is committed to this interval, and which objectivesObjectiveStrategyA strategic goal (OKR)View reference → the interval serves. Its defining move is separation. The cycle a work item is scheduled into is orthogonal to where that item lives; the item keeps its feature and epic parent, and the cadence is a deliberate link laid across that structure rather than a new home for it.
The planning cycle formalises the time-boxing at the heart of agile delivery. The fixed-length iteration comes from Scrum and Extreme Programming in the 1990s; nesting sprints inside a longer cadence — the Program Increment — comes from the Scaled Agile Framework. Each treats a bounded interval as the unit that work is committed to and reviewed against.
The UPG's contribution is to make that interval a first-class node, orthogonal to the product breakdown and shared across a portfolioPortfolioPortfolioA grouping of products by strategic axisView reference →. Because a planning cycle is portfolio-shared, the same quarter or increment can be reasoned about across several products at once, instead of living implicitly inside one team's project-management tool.
A team creates a planning cycle for each real cadence box, sets cadence_kind to say how coarse it is, and nests finer cycles inside coarser ones: sprints inside a quarter, quarters inside a Program Increment. Work is scheduled into a cycle with planning_cycle_schedules_work_item, and the objectives the cycle serves are attached with objective_scoped_to_planning_cycle.
Scheduling used to reach only user storiesUser StoryProduct SpecificationA user's goal and the value they expect, in the "As a… I want… So that…" format. Now also a first-class plannable unit (priority, effort, assignee, due_date) that schedules into a planning_cycle, and it round-trips an external board's column via workflow_state.View reference →. From 0.32.0 it reaches the whole bounded work-item family, feature, epic, user story, taskTaskProduct SpecificationA unit of work within a story or epicView reference → and bugBugProduct SpecificationA defect or unexpected behaviourView reference →, because a story-only endpoint could not hold the task a real tracker import actually produces. The active cycle is simply the one whose status is active. There is no separate flag: a boolean beside the lifecycle would be a second source of truth for a fact the lifecycle already holds, and the two would drift. At most one cycle should be active per parent per cadence_kind, a rule that is documented and deliberately unenforced, because no graded corpus exists to defend a check against a portfolio legitimately running two products' iterations at once.
Rolling a cycle forward is a rule, not a property. To roll cycle N forward you set N to closed and re-point the unfinished work's planning_cycle_schedules_work_item edges at N+1. The edge means is scheduled in, present tense, so a rolled item ends with one edge and not two. The tempting alternative, keeping both edges plus a rolled_from marker, was rejected because it builds a provenance layer through a side door, and the measured corpus shows what it would record: six issues auto-rolled across five cycles with zero completions, which is five edges per issue recording that nothing happened. Whether the history of past scheduling is retained at all is deferred, deliberately, to the same place the rest of the provenance question is parked.
Scheduling and scoping are deliberate links, not containment. A task scheduled into Sprint 24 still belongs to its feature and epic; the sprint simply carries it for two weeks. This keeps two questions independent, how is this product structured and what is committed when, so neither distorts the other.
A product runs its planning cycles (product_runs_planning_cycle); cycles nest via planning_cycle_contains_planning_cycle; they schedule work with planning_cycle_schedules_work_item and scope objectives and strategic themesStrategic ThemeStrategyA high-level strategic focus area for a planning period. Its own time_horizon is now deprecated: promote the period to a planning_cycle and link the two with strategic_theme_scoped_to_planning_cycle, so themes share one dated, nestable interval instead of a drifting per-theme label.View reference →. Rolling a coarse cycle up through its children answers time-shaped questions, what is committed this quarter and which objectives this increment advances, in a single traversal.
0.33.0 turned a pattern here into a stated rule: a planning entity relates to time through the scheduling edge, not through a free-text field. A period written as a string on the entity is a display label. Nothing can schedule on it, join across it, or nest it, and two entities meaning the same quarter have no way to recognise each other. Accordingly the timeframe on an objective and the time_horizon on a strategic theme are both deprecated for removal at 1.0.0, and both already have the edge they needNeedUserA user need, pain, desire, or constraintView reference →. The rule has a boundary, and it is a test rather than a slogan: the class is the entities that can be scheduled in a cycle, meaning the ones that have or could have a scoped-to or schedules edge to one. Today that is objective and strategic_theme, and nothing else in the census. Six fields that look like the same mistake are deliberately exempt. The horizon on a strategic pillarStrategic PillarStrategyA foundational principle that guides decisionsView reference → is durable and open-ended rather than a dated box. A visionVisionStrategyA long-term aspirational statement of the future stateView reference →'s timeframe describes something never scheduled in a cycle. A roadmapRoadmapProduct SpecificationA strategic plan of features and milestonesView reference →'s timeframe belongs to a plan of cycles rather than a thing inside one. A roadmap itemRoadmap ItemProduct SpecificationAn item on the product roadmapView reference →'s quarter sits beside real start and target dates. A journey phaseJourney PhaseExperience DesignA named phase in a user journey that groups a sequence of actions the user performs to reach a milestone.View reference →'s timeframe is not a planning entity at all. And a market trendMarket TrendMarket IntelligenceAn emerging trend in the marketView reference →'s timeframe is a forecastForecastSales & RevenueA revenue forecastView reference → window for something the organisation does not schedule, which is the clearest exclusion of the six: nothing can be scoped to a cycle the organisation does not control.
The failure mode is the empty cadence box: a planning cycle that neither schedules a work item nor contains a finer sub-cycle. A date range with nothing flowing through it is a sprint nobody planned into, or a coarse period never broken down. Either schedule the work it carries or nest finer cycles inside it. Otherwise the interval is not yet a real cadence box.
Type-specific fields on BaseNode
cadence_kindenumMethodology-neutral granularity of this interval. `period` is a coarse container (quarter / PI / OKR-cycle scale); `iteration` is a fine execution box (sprint / cycle); `buffer` is between-box slack (cooldown). Required: it is the discriminator that lets one type stand in for every methodology.
cadence_labelstringThe source methodology term verbatim ("sprint", "cycle", "PI", "quarter", "cooldown"). The dual-band label: `cadence_kind` is the canonical granularity reasoned over; `cadence_label` preserves what the team actually calls it.
starts_onstringISO date the interval opens. A cycle is concretely dated, unlike a coarse `time_horizon` label.
ends_onstringISO date the interval closes.
sequencenumberThe cycle / iteration number (e.g. Sprint 47, PI 3).
goalstringThe interval's goal or focus: what this cadence box is for.
appetitestringShape Up appetite: the fixed time budget a cycle is willing to spend on a bet (e.g. "6 weeks", "2 weeks").
idstringrequiredUnique identifier (UUID)
typeNodeTyperequiredDiscriminator for the entity type
titlestringrequiredDisplay name
descriptionstringOptional detailed description
statusstringLifecycle status
tagsstring[]Freeform tags for filtering
3 phases, initial: planned
5 edge types connected to this entity.
product_runs_planning_cycleplanning_cycle_contains_planning_cycleplanning_cycle_contains_planning_cycleobjective_scoped_to_planning_cyclestrategic_theme_scoped_to_planning_cycle