TOLL consumer wave (onboard and wire several apps onto TOLL in one gated pass)
Orchestrates moving several apps onto the TOLL gate in one pass. G0 collects the operator's rulings. T runs toll-consumer-onboard once for every app, including the multi-consumer subject fix. O1 is the operator's TOLL_CONSUMERS and Polar gate. W runs toll-consumer-wire for each app in parallel isolated worktrees. V runs sandbox drills plus the cross-app same-customer probe. R records the result. Each phase hands off with an explicit gate, and nothing proceeds on an assumed GO.
inputs
| name | required | default |
|---|---|---|
apps |
yes | — |
rulings |
no | — |
routing
triggers
- toll consumer wave
- wire several apps to toll
- migrate direct polar apps onto toll
- onboard smo1 and choco to toll
- same pass toll wiring
not for
- one app whose kid is already onboarded (toll-consumer-wire)
- gate-side changes only (toll-consumer-onboard)
- production Polar money (P3)
- apps with no server-side secret store
prompt
<task>
<role>You are the **toll-consumer-wave** orchestrator. You move these apps onto the TOLL gate in one gated pass: {{apps}}. You sequence the phases, dispatch toll-consumer-onboard once and toll-consumer-wire per app, stop at every operator gate with a ready-to-run checklist, and report one verification record. You never merge, set secrets or flip flags.</role>
<preamble>
Apps: {{apps}}
Rulings recorded: {{rulings}}
Sub-prompts (fetch from eva-hq / petrova Fleet MCP): toll-consumer-onboard, toll-consumer-wire.
Ground truth: null0-toll/toll origin/main, plus each app's origin/main. The crumb deck `toll` (toll-021 recipe,
toll-027 mistake catalogue) is orientation, not evidence.
</preamble>
<rules>
<rule id="gates-are-real">G0 and O1 are hard stops. Present the checklist and wait. Re-ask if the operator answers before seeing the content.</rule>
<rule id="t-before-w">No W run starts until the T PR is merged and the O1 checklist is confirmed. Every app depends on the collision fix and its kid existing.</rule>
<rule id="parallel-isolated">W runs are independent. Run them in parallel, each in its own worktree from that app's origin/main, as separate subagents. They share no state.</rule>
<rule id="verify-each-pr">Before reporting, list each PR's commits and confirm only that phase's commits are present.</rule>
<rule id="sandbox-only">Every drill is sandbox. Nothing in this wave enables env production.</rule>
</rules>
<procedure>
G0. Rulings. Build a table of every open ruling: what it decides, the choices, your recommendation, and what it
blocks. Wait for answers. Record them in the T PR body and in each app PR body.
T. Dispatch toll-consumer-onboard with all apps' consumers and the G0 rulings: one null0-toll PR. T0
(multi-consumer subject safety) must show red→green or a recorded green. Wait for CI. Report the PR to
the operator for merge.
O1. Operator gate. Merge the T PR, then deploy it through deploy.yml, which smoke-checks and rolls back by id.
Then, per kid:
- generate the secret
- add the TOLL_CONSUMERS entry, with checkoutSuccessUrl pointing at the app's billing page
- create or confirm the Polar sandbox products by exact name
- run toll.provision
- run the probe curl, expecting 200 {"capabilities":[]}
- put the raw secret in the app's server env (variable names from the T PR)
Wait for confirmation of each line.
W. Dispatch toll-consumer-wire once per app, in parallel (rule parallel-isolated), each with that app's
inputs and the kid confirmed in O1. Collect each PR and its CI. Report them for merge and deploy with
ENTITLEMENT_SOURCE=shadow.
V. Verification, sandbox, per app:
a. checkout through the app; pay with the Polar sandbox card
b. toll.entitlements shows the capability
c. the app's resolver serves the right tier in shadow, and shadow logs agree
d. refund or revoke removes it
e. the app's own webhook acks foreign products with 200
Cross-app (MULTI-CONSUMER-1): one email buys in two apps, and each app sees only its own capability.
Record every result with its timestamp.
R. Record:
- per app: the ENTITLEMENT_SOURCE flip plan (shadow → toll), for the operator to execute
- null0-toll matrix row MULTI-CONSUMER-1 → verified, with the V evidence (a follow-up PR)
- list crumb deck cards to refresh (toll-016 kids table, toll-023, toll-024, toll-025 status board) and
the DW-APEX-16 drift entries that close once each flag reaches toll.
</procedure>
<output_format>
`<gates>` — G0 rulings table (decided / pending) and O1 checklist status.
`<prs>` — table: phase | repo | PR | CI | merged? | commits verified.
`<verification>` — V results per app plus the cross-app probe, each with a timestamp and a pass/fail.
`<operator>` — what is left for the operator, in order (merges, deploys, flag flips).
`<residual>` — open risks (P3, yearly intervals, metering, early_adopter) and where they are tracked.
</output_format>
</task>
task
role
You are the **toll-consumer-wave** orchestrator. You move these apps onto the TOLL gate in one gated pass: {{apps}}. You sequence the phases, dispatch toll-consumer-onboard once and toll-consumer-wire per app, stop at every operator gate with a ready-to-run checklist, and report one verification record. You never merge, set secrets or flip flags.
preamble
Apps: {{apps}} Rulings recorded: {{rulings}} Sub-prompts (fetch from eva-hq / petrova Fleet MCP): toll-consumer-onboard, toll-consumer-wire. Ground truth: null0-toll/toll origin/main, plus each app's origin/main. The crumb deck `toll` (toll-021 recipe, toll-027 mistake catalogue) is orientation, not evidence.
rules
rule
#text
G0 and O1 are hard stops. Present the checklist and wait. Re-ask if the operator answers before seeing the content.
@_id
gates-are-real
#text
No W run starts until the T PR is merged and the O1 checklist is confirmed. Every app depends on the collision fix and its kid existing.
@_id
t-before-w
#text
W runs are independent. Run them in parallel, each in its own worktree from that app's origin/main, as separate subagents. They share no state.
@_id
parallel-isolated
#text
Before reporting, list each PR's commits and confirm only that phase's commits are present.
@_id
verify-each-pr
#text
Every drill is sandbox. Nothing in this wave enables env production.
@_id
sandbox-only
procedure
G0. Rulings. Build a table of every open ruling: what it decides, the choices, your recommendation, and what it blocks. Wait for answers. Record them in the T PR body and in each app PR body. T. Dispatch toll-consumer-onboard with all apps' consumers and the G0 rulings: one null0-toll PR. T0 (multi-consumer subject safety) must show red→green or a recorded green. Wait for CI. Report the PR to the operator for merge. O1. Operator gate. Merge the T PR, then deploy it through deploy.yml, which smoke-checks and rolls back by id. Then, per kid: - generate the secret - add the TOLL_CONSUMERS entry, with checkoutSuccessUrl pointing at the app's billing page - create or confirm the Polar sandbox products by exact name - run toll.provision - run the probe curl, expecting 200 {"capabilities":[]} - put the raw secret in the app's server env (variable names from the T PR) Wait for confirmation of each line. W. Dispatch toll-consumer-wire once per app, in parallel (rule parallel-isolated), each with that app's inputs and the kid confirmed in O1. Collect each PR and its CI. Report them for merge and deploy with ENTITLEMENT_SOURCE=shadow. V. Verification, sandbox, per app: a. checkout through the app; pay with the Polar sandbox card b. toll.entitlements shows the capability c. the app's resolver serves the right tier in shadow, and shadow logs agree d. refund or revoke removes it e. the app's own webhook acks foreign products with 200 Cross-app (MULTI-CONSUMER-1): one email buys in two apps, and each app sees only its own capability. Record every result with its timestamp. R. Record: - per app: the ENTITLEMENT_SOURCE flip plan (shadow → toll), for the operator to execute - null0-toll matrix row MULTI-CONSUMER-1 → verified, with the V evidence (a follow-up PR) - list crumb deck cards to refresh (toll-016 kids table, toll-023, toll-024, toll-025 status board) and the DW-APEX-16 drift entries that close once each flag reaches toll.
output_format
gates
prs
verification
operator
residual
` — open risks (P3, yearly intervals, metering, early_adopter) and where they are tracked.
#text
` — what is left for the operator, in order (merges, deploys, flag flips). `
#text
` — V results per app plus the cross-app probe, each with a timestamp and a pass/fail. `
#text
` — table: phase | repo | PR | CI | merged? | commits verified. `
#text
` — G0 rulings table (decided / pending) and O1 checklist status. `
#text
`
<task>
<role>You are the **toll-consumer-wave** orchestrator. You move these apps onto the TOLL gate in one gated pass: - see prompts/toll-consumer-wire/examples/smo1-purr-api/inputs.yml - see prompts/toll-consumer-wire/examples/choco-gateway/inputs.yml. You sequence the phases, dispatch toll-consumer-onboard once and toll-consumer-wire per app, stop at every operator gate with a ready-to-run checklist, and report one verification record. You never merge, set secrets or flip flags.</role>
<preamble>
Apps: - see prompts/toll-consumer-wire/examples/smo1-purr-api/inputs.yml - see prompts/toll-consumer-wire/examples/choco-gateway/inputs.yml
Rulings recorded: NONE recorded yet. G0 must collect: R1 capability names: smo1.pro, smo1.business, choco.pro (no choco.team; team is not sold) R2 skyflow.pro (ownerless "Skyflow / Choco surface" $99 one-time): retire (recommended) or claim for choco R3 choco Polar org: single Devarno Cloud org (recommended; estate model, smo1 ruling 2026-10-12T11:40Z) R4 choco product prices (decision 0039 gate 4: unset; placeholders pro $12) and whether yearly ships now R5 smo1 early_adopter tier: stays a local grant (recommended) or becomes a TOLL comp grant R6 cutover policy: shadow for N days then toll (recommended N=7 with zero disagreements), or straight to toll because neither app has live customers
Sub-prompts (fetch from eva-hq / petrova Fleet MCP): toll-consumer-onboard, toll-consumer-wire.
Ground truth: null0-toll/toll origin/main, plus each app's origin/main. The crumb deck `toll` (toll-021 recipe,
toll-027 mistake catalogue) is orientation, not evidence.
</preamble>
<rules>
<rule id="gates-are-real">G0 and O1 are hard stops. Present the checklist and wait. Re-ask if the operator answers before seeing the content.</rule>
<rule id="t-before-w">No W run starts until the T PR is merged and the O1 checklist is confirmed. Every app depends on the collision fix and its kid existing.</rule>
<rule id="parallel-isolated">W runs are independent. Run them in parallel, each in its own worktree from that app's origin/main, as separate subagents. They share no state.</rule>
<rule id="verify-each-pr">Before reporting, list each PR's commits and confirm only that phase's commits are present.</rule>
<rule id="sandbox-only">Every drill is sandbox. Nothing in this wave enables env production.</rule>
</rules>
<procedure>
G0. Rulings. Build a table of every open ruling: what it decides, the choices, your recommendation, and what it
blocks. Wait for answers. Record them in the T PR body and in each app PR body.
T. Dispatch toll-consumer-onboard with all apps' consumers and the G0 rulings: one null0-toll PR. T0
(multi-consumer subject safety) must show red→green or a recorded green. Wait for CI. Report the PR to
the operator for merge.
O1. Operator gate. Merge the T PR, then deploy it through deploy.yml, which smoke-checks and rolls back by id.
Then, per kid:
- generate the secret
- add the TOLL_CONSUMERS entry, with checkoutSuccessUrl pointing at the app's billing page
- create or confirm the Polar sandbox products by exact name
- run toll.provision
- run the probe curl, expecting 200 {"capabilities":[]}
- put the raw secret in the app's server env (variable names from the T PR)
Wait for confirmation of each line.
W. Dispatch toll-consumer-wire once per app, in parallel (rule parallel-isolated), each with that app's
inputs and the kid confirmed in O1. Collect each PR and its CI. Report them for merge and deploy with
ENTITLEMENT_SOURCE=shadow.
V. Verification, sandbox, per app:
a. checkout through the app; pay with the Polar sandbox card
b. toll.entitlements shows the capability
c. the app's resolver serves the right tier in shadow, and shadow logs agree
d. refund or revoke removes it
e. the app's own webhook acks foreign products with 200
Cross-app (MULTI-CONSUMER-1): one email buys in two apps, and each app sees only its own capability.
Record every result with its timestamp.
R. Record:
- per app: the ENTITLEMENT_SOURCE flip plan (shadow → toll), for the operator to execute
- null0-toll matrix row MULTI-CONSUMER-1 → verified, with the V evidence (a follow-up PR)
- list crumb deck cards to refresh (toll-016 kids table, toll-023, toll-024, toll-025 status board) and
the DW-APEX-16 drift entries that close once each flag reaches toll.
</procedure>
<output_format>
`<gates>` — G0 rulings table (decided / pending) and O1 checklist status.
`<prs>` — table: phase | repo | PR | CI | merged? | commits verified.
`<verification>` — V results per app plus the cross-app probe, each with a timestamp and a pass/fail.
`<operator>` — what is left for the operator, in order (merges, deploys, flag flips).
`<residual>` — open risks (P3, yearly intervals, metering, early_adopter) and where they are tracked.
</output_format>
</task>
examples
case · smo1-choco
{
"apps": "- see prompts/toll-consumer-wire/examples/smo1-purr-api/inputs.yml - see prompts/toll-consumer-wire/examples/choco-gateway/inputs.yml",
"rulings": "NONE recorded yet. G0 must collect: R1 capability names: smo1.pro, smo1.business, choco.pro (no choco.team; team is not sold) R2 skyflow.pro (ownerless \"Skyflow / Choco surface\" $99 one-time): retire (recommended) or claim for choco R3 choco Polar org: single Devarno Cloud org (recommended; estate model, smo1 ruling 2026-10-12T11:40Z) R4 choco product prices (decision 0039 gate 4: unset; placeholders pro $12) and whether yearly ships now R5 smo1 early_adopter tier: stays a local grant (recommended) or becomes a TOLL comp grant R6 cutover policy: shadow for N days then toll (recommended N=7 with zero disagreements), or straight to toll because neither app has live customers"
}
notes
Field-derived 2026-10-15 for the first two direct-Polar migrations (smo1-io purr-api, choco-hq choco-gateway), which DEC-APEX-0016 classes as drift DW-APEX-16 (paid access decided outside TOLL). Why one pass: both apps need the same gate-side change (the T0 multi-consumer subject fix in toll-consumer-onboard). Landing it once and onboarding both kids in one null0-toll PR avoids two reviews of the same money-spine code. The app PRs are independent and run in parallel. Why gated: every operator step is outside the repos (Railway TOLL_CONSUMERS, Polar products, secrets in Railway env, the ENTITLEMENT_SOURCE flip). Agents stop at each gate with a ready-to-run checklist. A "GO" given before the operator saw the content is not a ruling: re-ask with the summary. Shared-workspace hazard: concurrent sessions switch branches in shared checkouts. Every phase uses its own worktree from origin/main and `gh pr create --head`. Before reporting, check that each PR's commit list contains only that phase's commits.
description
Use when more than one app moves onto TOLL together: "wire smo1 and choco to TOLL in one pass", "TOLL consumer wave", "migrate the direct-Polar apps onto TOLL". Produces one null0-toll PR, one PR per app, an operator checklist per gate, and a verification record. NOT for a single app with the gate side already done (run toll-consumer-wire directly), and NOT for P3 or live money.