Repository navigation
Rollout Ordering
A plan isn't just a list. It's a sequence. Change a price and you want Stripe updated before the website advertises it, and the App Store IAP before the listing that quotes it. orderSteps in core/order.ts turns the actionable impact items into the Order: line of every plan, using explicit after/blocks edges first and a per-adapter priority second. This page covers the priority table, the edge semantics, cycle breaking and the waitsFor data.
Only actionable items: classes auto, review, manual, retire, break and code. Tests and info items are left out. That means code items (anchored symbols) are in the order, alongside world artifacts.
- Build a dependency set for each item from
afterandblocksedges between items in this plan. Edges that point outside the plan are ignored. - Repeat until every item is placed:
- ready = unplaced items whose dependencies are all placed;
- sort ready items by priority (lower first), then id (alphabetical);
- place the first one, recording
waitsFor= its dependencies.
- If nothing is ready, there's a cycle. Take all remaining items, sort them the same way, place the first one anyway (its
waitsForkeeps only dependencies already placed), and record the remaining set incycles.
Only one item is placed per round, and the ready set is recomputed each time. An item unblocked by the last placement competes on priority with everything else that's ready.
Money systems first, then stores, then code, then the public web, then outbound messaging. Code-layer items always get the code priority; artifacts use their binding's adapter; artifacts with no binding or an unlisted adapter get 55.
| Adapter | Priority |
|---|---|
stripe |
10 |
revenuecat |
20 |
appstore |
30 |
playstore |
30 |
code (any code-layer item) |
40 |
fs |
50 |
| (no binding / unknown adapter) | 55 |
url |
60 |
cms |
60 |
email |
70 |
youtube |
80 |
tiktok |
80 |
Several of these (revenuecat, playstore, cms, email, youtube, tiktok) have no adapter yet. The priority applies anyway when you use them as binding labels.
| You write | Meaning |
|---|---|
A after B (on artifact A: after: [B]) |
B runs before A. |
B blocks A (on artifact B: blocks: [A]) |
B runs before A. |
Both are edge types with propagation none: they never add items to a plan, only order items already in it. Declare them on artifacts or in an edges: section (any two node ids work, including code nodes).
The demo has one ordering edge: appstore:listing/description is after: [appstore:iap/pro-monthly]. Impact of a price change:
Order: stripe:price/pro-monthly → appstore:iap/pro-monthly → appstore:listing/description → appstore:screenshots/6.9/03 → symbol:ios/Pricing.proUSD → symbol:ios/StarchartFacts.AddonPro.Price.usd → symbol:web/lib/starchart-facts#ADDON_PRO_PRICE_USD → symbol:web/lib/stripe#PRICE_PRO_MONTHLY → email:onboarding-day-3 → web:landing-hero → web:messages-en → web:og-pro → web:pricing-page → web:live-pricing → reel:spring-2026
Stripe (10), App Store (30), code symbols (40), fs artifacts (50), the url-bound live page (60), the YouTube reel (80). Inside a priority band, alphabetical.
Say the pricing page must ship before the Stripe price changes (maybe it has to announce the new price first):
# .starchart/order.yaml
edges:
- { from: web:pricing-page, to: stripe:price/pro-monthly, type: blocks }Order: appstore:iap/pro-monthly → appstore:listing/description → appstore:screenshots/6.9/03 → symbol:ios/Pricing.proUSD → symbol:ios/StarchartFacts.AddonPro.Price.usd → symbol:web/lib/starchart-facts#ADDON_PRO_PRICE_USD → symbol:web/lib/stripe#PRICE_PRO_MONTHLY → email:onboarding-day-3 → web:landing-hero → web:messages-en → web:og-pro → web:pricing-page → stripe:price/pro-monthly → web:live-pricing → reel:spring-2026
Stripe now waits for the pricing page. The JSON output (-f json) shows each step's waitsFor:
[
{ "id": "appstore:listing/description", "class": "manual", "waitsFor": ["appstore:iap/pro-monthly"] },
{ "id": "stripe:price/pro-monthly", "class": "manual", "waitsFor": ["web:pricing-page"] },
{ "id": "web:live-pricing", "class": "manual", "waitsFor": ["web:pricing-page"] }
](Filtered to steps with a non-empty waitsFor.)
Add web:pricing-page after web:live-pricing, while the demo already says web:live-pricing after web:pricing-page:
edges:
- { from: web:pricing-page, to: web:live-pricing, type: after }Order: stripe:price/pro-monthly → … → web:og-pro → reel:spring-2026 → web:pricing-page → web:live-pricing
Cycle broken deterministically: web:pricing-page, web:live-pricing
Everything outside the cycle is placed first, even the priority-80 reel, because cycle breaking only kicks in once nothing is ready. Then the lowest-priority-number item in the cycle (web:pricing-page, fs 50) is placed with an empty waitsFor, which unblocks web:live-pricing. cycles in the JSON output lists the stuck set: [["web:pricing-page","web:live-pricing"]].
- The
Order:line inimpactandplantext output, andstepsin JSON and markdown. -
starchart applyrunsautosteps in this order (Apply, Revert and Journals). Generated constants sit in the code band (40), so codegen runs before the fs writes; it runs once, at the first generated symbol, and later generated symbols reuse that result. - After an apply or
ack,plandrops artifacts that are already in sync, so theOrder:line shrinks to what's left. After the demo apply:stripe:price/pro-monthly → appstore:iap/pro-monthly → appstore:listing/description → appstore:screenshots/6.9/03 → symbol:ios/Pricing.proUSD → symbol:web/lib/stripe#PRICE_PRO_MONTHLY → web:landing-hero → web:live-pricing → reel:spring-2026.
Release choreography with approval gates between steps isn't built yet.
★ STARCHART
☠ a Space Pirate Zero joint
STARCHART Every dependency. Code to cosmos.
Guides
Concepts
- Three-Layer Model
- Facts and Entities
- Artifacts and Bindings
- Edge Types
- Node IDs
- Impact Analysis
- Lockfile and Drift
- Rollout Ordering
Authoring
Code layer
Commands & API
Adapters & engine
- Adapters Overview
- Adapter: fs
- Adapter: url
- Adapter: Stripe
- Adapter: App Store Connect
- Writing an Adapter
- Audit and Break Detection
- Apply, Revert and Journals
- Future Universe Preview
- Viewer and Serve
- Reality X-Ray
Rules & analysis
Integrations
Project