Anatomy
A timeline belongs to one subject — usually a collaborator — and to one kind of data. A collaborator has an activity rate timeline, a sector timeline, and so on; they are independent of each other. Each period has a date range, which may be open-ended where the entity allows it, and a set of values whose shape depends on the entity. Within one timeline, periods are sorted by start date and never overlap.The two rules
Rule 1 — the requested range always wins. The date range you send is stored exactly as sent. tipee never shifts your start date, never trims your end date, never fills a gap on your behalf. Existing periods yield in whichever direction is needed. Rule 2 — identical neighbours merge. If the period you assign is adjacent to or overlapping an existing one, and the two are identical, they become a single period spanning both ranges. Otherwise the existing period is truncated, split, or removed to make room. Adjacent means the two ranges touch: one ends the day before the other starts. Overlapping means they share at least one day. A gap of one day or more is never bridged. Identical means that every field in the entity’s identity set holds the same value. That set is defined per entity and listed on the entity’s own page.The comparison is on effective values, not on what your payload contained. Sending a value
explicitly, omitting it so a default applies, or leaving it empty so it is inherited are all
equivalent — what matters is the value that ends up applying. So two payloads that look different
can merge, and two payloads that look alike may not.
What a write does
In every diagram,Before is the existing timeline, Assign is the period you send, and Result is
the resulting timeline.
Different letters mean different values; the same letter twice means identical values — that is
how the diagrams encode Rule 2. Columns are contiguous: there is no hidden gap between two adjacent
columns.
Assigning next to an identical period extends it
This is the one that surprises integrators. You assigned a new period, the call succeeded, and the number of periods did not change — because tipee merged yours into its neighbour. Nothing was lost: the existing period now runs further.Assigning over a different period truncates it
The existing period is cut back to the day before your range starts.Assigning the exact same range replaces it
No error, no duplicate. This is the normal way to modify an existing period.Assigning inside a period splits it in two
Three periods result, and the tail keeps the original values.Assigning over a whole period deletes it
Further cases
Overlapping identical periods, several neighbours at once, open-ended tails, assigning backwards
Further cases
Overlapping identical periods, several neighbours at once, open-ended tails, assigning backwards
Overlapping ranges with identical values merge into the union of the two ranges, exactly as
adjacent ones do.Splitting works on open-ended periods too. The tail stays open-ended.The rules are symmetric. A range starting before an existing period pushes that period’s
start forward.A range spanning several periods makes each neighbour yield on its own side.A merge can happen on both sides at once. Overwriting a middle period so that it becomes
identical to its neighbours collapses everything into one.
Calls that appear to do nothing
A merge can absorb your request entirely. The call succeeds, the timeline is unchanged, and nothing is wrong. Assigning an identical open-ended period after an existing open-ended one changes nothing: the union of the two ranges is the existing range.Removing instead of assigning
Where an entity exposes an unassign endpoint, it clears the timeline over the intersection of your range with the existing periods, and succeeds silently when there was nothing to remove. It is the only way to end a period on a given date.Recipes
Change the values from a given date onwards
Assign an open-ended range starting on that date
Change the values from a given date onwards
Assign an open-ended range starting on that date
Assign the new values over an open-ended range beginning on that date. The existing period is
truncated the day before, and you end up with two periods.
If the new values happen to be identical to the current ones, nothing happens — which is the
correct outcome, since the timeline already said what you wanted it to say.
Correct the values of an existing period
Re-assign the exact same date range
Correct the values of an existing period
Re-assign the exact same date range
Re-assign the exact same date range with the new values. The period is replaced in place.What to do afterwards: read the timeline back. If the corrected values now match a
neighbour, the two will have merged, and your period no longer exists as a separate entry.
End a period on a given date
Use unassign, not assign
End a period on a given date
Use unassign, not assign
An assign cannot shorten a period from the right. Use the entity’s unassign endpoint over the
range you want cleared, starting the day after the intended end.
Find out what actually happened
Read the timeline back and compare
Find out what actually happened
Read the timeline back and compare
There is no merge indicator in a response, and periods are not always addressable individually.
Reading the timeline before and after the write, and diffing the two, is the reliable way to know
whether your call created, merged, truncated, split or did nothing.
What varies between entities
The rules above hold for every timeline. What each entity defines for itself, on its own page:The identity fields
Which fields must match for two periods to be considered identical — the input to Rule 2.
The endpoints
The assign and unassign operation names, their payloads, and what they return.
Range constraints
Whether open-ended ranges are accepted, and whether the timeline may contain gaps at all.
Defaults and inheritance
Which values can be omitted, and what they resolve to — which in turn decides what counts as
identical.