Lineage

There is no pipeline object to maintain. Every producer of a dataset declares what it reads: a Python transform through its Input, Output, Model and Connection bindings, a SQL transform through the FROM references of its query, a sync through its connection. The platform reads those declarations, from the code it scans and from the resources, and derives a graph of who feeds whom:
The graph is what the Atlas interface shows as lineage, what a build walks, and what GET /orchestration/lineage/{id}?direction= answers. The binding names are therefore part of the contract with the platform: a transform is registered from its decorators, not from a separate manifest.
An Output can never be an Input of the same transform. That would be a cycle, and the catalog refuses it. A transform that needs its own previous output uses an incremental transform.

Builds

A build runs a producer on the platform: the repository checked out at a pinned commit, the SQL text pinned when the build was created, the identity of whoever triggered it. Building a dataset builds every producer upstream of it first, in the order of the graph, whether its data changed or not; a change at a source propagates to what depends on it. Inside a build, the library needs no key, model paths resolve without a network call, and an incremental transform receives the rows added since its last run. How to drive builds, propagations and schedules is on Workflows; what a build hands your code is on Builds.

Branches

A data branch is a named view of a dataset where writes land without touching the trunk. A build run on a branch writes its outputs there, and checks out the git branch of the same name when the repository has one, so a change can be tested end to end on real data and only then promoted. See Data branches.