@volter/twin-polar 2.0.37 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -27
- package/dist/generated/pack-facts.json +69 -0
- package/dist/journeys/coverage.json +223 -0
- package/dist/journeys/customer-life.json +1222 -0
- package/dist/journeys/customer-life.outline.md +69 -0
- package/dist/journeys/customer-life.outline.verdict.json +41 -0
- package/dist/journeys/customer-life.verdict.json +71 -0
- package/dist/journeys/decisions.json +149 -0
- package/dist/journeys/demand.json +45 -0
- package/dist/journeys/score.json +249 -0
- package/dist/journeys/unreachable.json +13 -0
- package/dist/journeys/vendor-examples.json +9621 -0
- package/dist/journeys/vendor-examples.verdict.json +33 -0
- package/dist/spec/SOURCE.md +25 -0
- package/dist/spec/doc-examples.json +681 -0
- package/dist/spec/openapi.json.gz +0 -0
- package/dist/spec/sources.json +71 -0
- package/dist/src/cli.js +7 -16
- package/dist/src/fetch.d.ts +2 -0
- package/dist/src/fetch.js +24 -0
- package/dist/src/generated/surface.gen.json +1 -0
- package/dist/src/generated/ui.gen.json +1 -0
- package/dist/src/index.d.ts +5 -9
- package/dist/src/index.js +10 -55
- package/dist/src/manifest.d.ts +2 -0
- package/dist/src/manifest.js +123 -0
- package/dist/src/screens/checkout.d.ts +2 -0
- package/dist/src/screens/checkout.js +25 -0
- package/dist/src/screens/portal.d.ts +2 -0
- package/dist/src/screens/portal.js +18 -0
- package/dist/src/semantics/around.d.ts +2 -0
- package/dist/src/semantics/around.js +25 -0
- package/dist/src/semantics/checkouts.d.ts +14 -0
- package/dist/src/semantics/checkouts.js +131 -0
- package/dist/src/semantics/clock.d.ts +2 -0
- package/dist/src/semantics/clock.js +22 -0
- package/dist/src/semantics/customer-sessions.d.ts +2 -0
- package/dist/src/semantics/customer-sessions.js +12 -0
- package/dist/src/semantics/customers.d.ts +9 -0
- package/dist/src/semantics/customers.js +61 -0
- package/dist/src/semantics/doors.d.ts +11 -0
- package/dist/src/semantics/doors.js +47 -0
- package/dist/src/semantics/events.d.ts +12 -0
- package/dist/src/semantics/events.js +60 -0
- package/dist/src/semantics/index.d.ts +2 -0
- package/dist/src/semantics/index.js +27 -0
- package/dist/src/semantics/orders.d.ts +4 -0
- package/dist/src/semantics/orders.js +11 -0
- package/dist/src/semantics/products.d.ts +5 -0
- package/dist/src/semantics/products.js +43 -0
- package/dist/src/semantics/shared.d.ts +82 -0
- package/dist/src/semantics/shared.js +327 -0
- package/dist/src/semantics/states.d.ts +27 -0
- package/dist/src/semantics/states.js +43 -0
- package/dist/src/semantics/subscriptions.d.ts +4 -0
- package/dist/src/semantics/subscriptions.js +15 -0
- package/dist/src/semantics/tenant.d.ts +2 -0
- package/dist/src/semantics/tenant.js +2 -0
- package/dist/src/semantics/webhooks.d.ts +4 -0
- package/dist/src/semantics/webhooks.js +30 -0
- package/dist/src/server.d.ts +7 -0
- package/dist/src/server.js +7 -0
- package/generated/pack-facts.json +69 -0
- package/journeys/coverage.json +223 -0
- package/journeys/customer-life.json +1222 -0
- package/journeys/customer-life.outline.md +69 -0
- package/journeys/customer-life.outline.verdict.json +41 -0
- package/journeys/customer-life.verdict.json +71 -0
- package/journeys/decisions.json +149 -0
- package/journeys/demand.json +45 -0
- package/journeys/score.json +249 -0
- package/journeys/unreachable.json +13 -0
- package/journeys/vendor-examples.json +9621 -0
- package/journeys/vendor-examples.verdict.json +33 -0
- package/package.json +19 -31
- package/spec/SOURCE.md +25 -0
- package/spec/doc-examples.json +681 -0
- package/spec/openapi.json.gz +0 -0
- package/spec/sources.json +71 -0
- package/src/cli.ts +7 -14
- package/src/fetch.ts +25 -0
- package/src/generated/surface.gen.json +1 -0
- package/src/generated/ui.gen.json +1 -0
- package/src/index.ts +11 -85
- package/src/manifest.ts +135 -0
- package/src/screens/checkout.ts +33 -0
- package/src/screens/portal.ts +20 -0
- package/src/semantics/around.ts +25 -0
- package/src/semantics/checkouts.ts +133 -0
- package/src/semantics/clock.ts +24 -0
- package/src/semantics/customer-sessions.ts +13 -0
- package/src/semantics/customers.ts +68 -0
- package/src/semantics/doors.ts +51 -0
- package/src/semantics/events.ts +62 -0
- package/src/semantics/index.ts +31 -0
- package/src/semantics/orders.ts +15 -0
- package/src/semantics/products.ts +45 -0
- package/src/semantics/shared.ts +352 -0
- package/src/semantics/states.ts +50 -0
- package/src/semantics/subscriptions.ts +18 -0
- package/src/semantics/tenant.ts +5 -0
- package/src/semantics/webhooks.ts +29 -0
- package/src/server.ts +8 -0
- package/dist/src/polar-budget.d.ts +0 -83
- package/dist/src/polar-budget.js +0 -413
- package/dist/src/polar-capabilities.d.ts +0 -4
- package/dist/src/polar-capabilities.js +0 -389
- package/dist/src/polar-conformance.d.ts +0 -7
- package/dist/src/polar-conformance.js +0 -25
- package/dist/src/polar-connector.d.ts +0 -113
- package/dist/src/polar-connector.js +0 -146
- package/dist/src/polar-server.d.ts +0 -14
- package/dist/src/polar-server.js +0 -52
- package/dist/src/polar-twin.d.ts +0 -24
- package/dist/src/polar-twin.js +0 -941
- package/src/polar-budget.ts +0 -459
- package/src/polar-capabilities.ts +0 -448
- package/src/polar-conformance.ts +0 -33
- package/src/polar-connector.ts +0 -172
- package/src/polar-server.ts +0 -57
- package/src/polar-twin.ts +0 -938
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# polar customer life: outline
|
|
2
|
+
|
|
3
|
+
## The customer
|
|
4
|
+
|
|
5
|
+
**Volter** takes its money in through one Polar organization (../journeys/demand.json). Two of its products call it.
|
|
6
|
+
**Volter World's platform** bills through its biller (twin-world `apps/billing` at `96ca4478bb39`, `@polar-sh/sdk`): at
|
|
7
|
+
boot it finds or makes its meters and its Team plan by name; an org upgrades on Polar's hosted checkout, its org id the
|
|
8
|
+
customer's external id; the biller reads an org's plan and usage from Polar's customer state by that id, reports usage
|
|
9
|
+
as events each carrying its own id so a retry never counts twice, and opens the customer portal for Manage billing.
|
|
10
|
+
**Open Autonomy** takes patronage (open-autonomy `apps/platform/src/polar.ts` at `0841076bed91`, REST over fetch): it
|
|
11
|
+
makes each project tier's monthly and one-time products, sends a patron to Polar's checkout, and learns of a paid order
|
|
12
|
+
twice, from the signed `order.paid` webhook and from its thanks page, which reads the checkout, its orders and the
|
|
13
|
+
order's customer back.
|
|
14
|
+
|
|
15
|
+
The World clock starts 2026-01-01. This organization, its credentials and records are in production; buyers receive only checkout URLs or their own session tokens.
|
|
16
|
+
|
|
17
|
+
## People and programs
|
|
18
|
+
|
|
19
|
+
| who | holds | how |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| Lena Ortiz, Volter's operator | authority over this organization's token and webhook settings | makes the platform's Organization Access Token (door), registers Open Autonomy's webhook endpoint (API) |
|
|
22
|
+
| the platform's biller | the organization's OAT, granted read/write scope over its meters, products, checkouts, customers, customer sessions and events | @polar-sh/sdk |
|
|
23
|
+
| Open Autonomy's platform | the organization's OAT, granted products/checkouts write, orders/customers read and webhook settings scope; endpoint secret for verification | fetch |
|
|
24
|
+
| Ada (Acme Robotics, Acme Labs), Globex's admin | their own org's billing page; authorization over only their checkout and customer session | the biller's checkout and Manage billing |
|
|
25
|
+
| Grace, Heidi | their card on Polar's page; authorization over only their checkout | Polar's hosted checkout, from Open Autonomy's give button |
|
|
26
|
+
|
|
27
|
+
## The arc
|
|
28
|
+
|
|
29
|
+
### 1. Setting up (Mon 5 Jan)
|
|
30
|
+
Lena makes the platform's token. The biller boots: it lists the meters (`meters:list`), finds none and makes `world_hours` (the sum of
|
|
31
|
+
each `world.hour` event's units) and `worlds_provisioned` (a count) (`meters:create`); it lists the products
|
|
32
|
+
(`products:list`), finds none and makes the Team plan (`products:create`): $49 a month, 2 cents a world-hour beyond
|
|
33
|
+
the plan on the hours meter, a 14-day trial. At its next boot it finds both by name.
|
|
34
|
+
|
|
35
|
+
### 2. An org upgrades (Tue 6 Jan)
|
|
36
|
+
The biller reads Acme's billing by its org id (`customers:get_state_external`): Polar has no such customer (404), so
|
|
37
|
+
Acme is on Free. Ada chooses Team: the biller opens a checkout with Acme's org id as the customer's external id
|
|
38
|
+
(`checkouts:create`); Ada opens its url, Polar's checkout page (`checkouts:client_get`), and supplies payment details
|
|
39
|
+
(`checkouts:client_confirm`), back to the billing page. The trial starts without an immediate charge. Acme's state now holds the Team subscription, trialing.
|
|
40
|
+
|
|
41
|
+
### 3. Usage (Wed 14 Jan)
|
|
42
|
+
Acme creates a World and the biller reports it. Two hours later the biller reports the completed world-hours (`events:ingest`); a retried tick sends the last hour again and
|
|
43
|
+
Polar counts it a duplicate. Acme's state shows two world-hours consumed.
|
|
44
|
+
|
|
45
|
+
### 4. Manage billing (Mon 2 Feb)
|
|
46
|
+
Ada opens Manage billing: the biller makes a customer session for Acme by its org id (`customer-sessions:create`), and
|
|
47
|
+
she follows its returned portal URL and sees her subscription, now active after its trial ended, and purchase history. Polar charged her when the trial ended on 20 January; calendar-month renewals create subsequent paid orders. Next day Globex, on Free, is refused a session the same way; support asks Lena to create Globex its customer by its org id; then the biller can create its session. The biller's isNotFound check accepts status 404 or an error message containing not found or 404. Polar documents this validation as 422; whether its fallback runs depends on the actual error message. This session error does not match, so support intervenes.
|
|
48
|
+
|
|
49
|
+
### 5. Patronage (Tue 10 to Thu 12 Feb)
|
|
50
|
+
Lena registers Open Autonomy's webhook endpoint when patronage launches, for order.created and order.paid; future events of the whole organization reach it, including billing orders it cannot settle without patronage metadata. Open Autonomy makes acme/rover's first tier, monthly and once (`products:create`). Grace gives once: Open Autonomy
|
|
51
|
+
opens her checkout (`checkouts:create`), back to its thanks page with `{CHECKOUT_ID}`; she leaves the tab for 25 hours while talking to the maintainer, tries to pay after expiry (410), returns to the application for a fresh checkout, pays and
|
|
52
|
+
returns on Wednesday 11 February with the checkout's id. Polar tells Open Autonomy the order was made and is paid (`order.created`,
|
|
53
|
+
`order.paid`, signed with the endpoint's secret). The thanks page reads the checkout back (`checkouts:get`), its orders
|
|
54
|
+
(`orders:list`) and the order's customer (`customers:get`). Next day, Thursday 12 February, Heidi gives monthly: her paid order is the first of a subscription.
|
|
55
|
+
|
|
56
|
+
### 6. A leaked token (Thu 16 Apr)
|
|
57
|
+
The platform's token is revoked on the settings page; the old one is refused and a new one works.
|
|
58
|
+
|
|
59
|
+
### 7. A vendor-backed refresh reads the organization back
|
|
60
|
+
With the new token, a World rooted at this organization reads back what the manifest refreshes: the webhook endpoints
|
|
61
|
+
(`webhooks:list_webhook_endpoints`, its secret), the checkouts newest first (`checkouts:list`: Heidi's succeeded), the
|
|
62
|
+
subscriptions the latest started first (`subscriptions:list`: Heidi's active, Acme's Team), the customers newest first
|
|
63
|
+
(`customers:list`) and the usage events (`events:list`: Acme's World and two hours, the
|
|
64
|
+
retried hour not a third).
|
|
65
|
+
|
|
66
|
+
## What the life does not do
|
|
67
|
+
The meters' and webhook endpoints' reads by id and changes, checkouts' update, orders' reads by id, the
|
|
68
|
+
subscriptions' changes, benefits, discounts, refunds, checkout links, the customer portal's email sign-in, settings, cancellation, invoices and payment-method changes, and its API, and every
|
|
69
|
+
other operation no application of the demand calls.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"sha256": "367d63fa0038e0258dc0e473b5adb706e45d5f210c86766a5ba8b6e0449973e6",
|
|
3
|
+
"plausible": true,
|
|
4
|
+
"bar": "829132787d94a2d4",
|
|
5
|
+
"judge": {
|
|
6
|
+
"agent": "Contributor 16",
|
|
7
|
+
"model": "GPT-6 (Codex)",
|
|
8
|
+
"review": "Independent read-only review, 2026-10-01; did not author these files"
|
|
9
|
+
},
|
|
10
|
+
"authors": [
|
|
11
|
+
"Contributor 39"
|
|
12
|
+
],
|
|
13
|
+
"rounds": 1,
|
|
14
|
+
"ruledSteps": [
|
|
15
|
+
"0",
|
|
16
|
+
"1",
|
|
17
|
+
"2",
|
|
18
|
+
"3",
|
|
19
|
+
"4",
|
|
20
|
+
"5",
|
|
21
|
+
"7"
|
|
22
|
+
],
|
|
23
|
+
"rulings": "REJECTED. Exhaustive one-round review against every item of the current judging bar and the vendored spec, published pages, and cached application commits.\nO0. Act 0 (frame): the actor table states what each actor holds but omits its grant. Add the organization's full operational grant for the OAT (the scopes of the served operations), Lena's authority over that organization's token and webhook settings, and each buyer's authorization solely over their checkout or customer session. State the environment consistently with the life. Do not give a buyer the organization's token.\nO1. Act 1: delete the two authentication refusals. Neither has a cause carried out in the story, and they draw the same authentication cause twice consecutively. Keep the legitimate token issuance and successful biller boot.\nO2. Act 2: delete the failed confirmation retry after the successful checkout in the same sitting; the bar explicitly rejects a failing repeat of a request that succeeded earlier in the sitting. Say Ada supplies payment details and starts the trial, without being charged yet (Polar Trials); remove the claim that she pays immediately.\nO3. Act 3: establish that Acme first creates its World, then two hours pass before the reported completed world-hours. The current life creates the World at 15:00 but reports hour identifiers for 10:00 and 11:00 on that same day, before the World existed. Retain the successful duplicate-event retry, which does not fail.\nO4. Act 4: delete the disconnected Acme Labs duplicate-email refusal. No preceding application action initiates a second organization's customer creation. Keep the Globex missing-session, support intervention and successful retry whose cause is carried out. Correct 'the biller only retries 404' to describe the actual isNotFound check at the cached commit: status 404 OR a message matching not found/404; whether a 422 invokes fallback depends on its actual message.\nO5. Act 5: checkout TTL is 24 hours in Polar's published config, read by models/checkout.py get_expires_at, not 1 hour. Make Grace leave the open page for 25 hours before submitting its displayed form; her fresh payment is Wednesday 11 February. Move Heidi to Thursday 12 February, retaining the later 16 April date. Delete the unknown-checkout refusal: the story gives no person or application a cause to manufacture that ID.\nO7. Act 7: keep one complete read per resource by the newly rooted World, which does not already hold the organization. Delete the extra customer-email and event-name filtered reads; after complete lists this same actor has no need for them, and they form an option tour rather than refresh work.\nAll other acts were checked. Sources: docs/contributing/architecture.md What a judge rejects and Writing a life; polar/spec/openapi.json.gz security and Checkout schemas; https://polar.sh/docs/features/subscriptions/trials; https://github.com/polarsource/polar/blob/main/server/polar/config.py CHECKOUT_TTL_SECONDS; https://github.com/polarsource/polar/blob/main/server/polar/models/checkout.py get_expires_at; cached twin-world 96ca4478bb39 apps/billing/src/polar.ts isNotFound/portalFor.",
|
|
24
|
+
"doubts": [
|
|
25
|
+
"The customer-life frame calls this a year although it ends in April, and the full life does not show leaving the vendor; this is a scope/wording doubt rather than a ruling under the explicit rejection list."
|
|
26
|
+
],
|
|
27
|
+
"applied": {
|
|
28
|
+
"from": "aab106c801689aad8142bf21fab02224423c1c5d8ff099f23977716ae893787c",
|
|
29
|
+
"wasPlausible": false,
|
|
30
|
+
"steps": [
|
|
31
|
+
"0",
|
|
32
|
+
"1",
|
|
33
|
+
"2",
|
|
34
|
+
"3",
|
|
35
|
+
"4",
|
|
36
|
+
"5",
|
|
37
|
+
"7"
|
|
38
|
+
],
|
|
39
|
+
"rulings": "REJECTED. Exhaustive one-round review against every item of the current judging bar and the vendored spec, published pages, and cached application commits.\nO0. Act 0 (frame): the actor table states what each actor holds but omits its grant. Add the organization's full operational grant for the OAT (the scopes of the served operations), Lena's authority over that organization's token and webhook settings, and each buyer's authorization solely over their checkout or customer session. State the environment consistently with the life. Do not give a buyer the organization's token.\nO1. Act 1: delete the two authentication refusals. Neither has a cause carried out in the story, and they draw the same authentication cause twice consecutively. Keep the legitimate token issuance and successful biller boot.\nO2. Act 2: delete the failed confirmation retry after the successful checkout in the same sitting; the bar explicitly rejects a failing repeat of a request that succeeded earlier in the sitting. Say Ada supplies payment details and starts the trial, without being charged yet (Polar Trials); remove the claim that she pays immediately.\nO3. Act 3: establish that Acme first creates its World, then two hours pass before the reported completed world-hours. The current life creates the World at 15:00 but reports hour identifiers for 10:00 and 11:00 on that same day, before the World existed. Retain the successful duplicate-event retry, which does not fail.\nO4. Act 4: delete the disconnected Acme Labs duplicate-email refusal. No preceding application action initiates a second organization's customer creation. Keep the Globex missing-session, support intervention and successful retry whose cause is carried out. Correct 'the biller only retries 404' to describe the actual isNotFound check at the cached commit: status 404 OR a message matching not found/404; whether a 422 invokes fallback depends on its actual message.\nO5. Act 5: checkout TTL is 24 hours in Polar's published config, read by models/checkout.py get_expires_at, not 1 hour. Make Grace leave the open page for 25 hours before submitting its displayed form; her fresh payment is Wednesday 11 February. Move Heidi to Thursday 12 February, retaining the later 16 April date. Delete the unknown-checkout refusal: the story gives no person or application a cause to manufacture that ID.\nO7. Act 7: keep one complete read per resource by the newly rooted World, which does not already hold the organization. Delete the extra customer-email and event-name filtered reads; after complete lists this same actor has no need for them, and they form an option tour rather than refresh work.\nAll other acts were checked. Sources: docs/contributing/architecture.md What a judge rejects and Writing a life; polar/spec/openapi.json.gz security and Checkout schemas; https://polar.sh/docs/features/subscriptions/trials; https://github.com/polarsource/polar/blob/main/server/polar/config.py CHECKOUT_TTL_SECONDS; https://github.com/polarsource/polar/blob/main/server/polar/models/checkout.py get_expires_at; cached twin-world 96ca4478bb39 apps/billing/src/polar.ts isNotFound/portalFor."
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"sha256": "43b29c38cd6db33bfe8abb8e733875726f0a56b8843c528297ce55230def4965",
|
|
3
|
+
"plausible": true,
|
|
4
|
+
"bar": "829132787d94a2d4",
|
|
5
|
+
"judge": {
|
|
6
|
+
"agent": "Contributor 16",
|
|
7
|
+
"model": "GPT-6 (Codex)",
|
|
8
|
+
"review": "Independent read-only review, 2026-10-01; did not author these files"
|
|
9
|
+
},
|
|
10
|
+
"authors": [
|
|
11
|
+
"Contributor 39"
|
|
12
|
+
],
|
|
13
|
+
"rounds": 1,
|
|
14
|
+
"ruledSteps": [
|
|
15
|
+
"2",
|
|
16
|
+
"3",
|
|
17
|
+
"14",
|
|
18
|
+
"15",
|
|
19
|
+
"16",
|
|
20
|
+
"19",
|
|
21
|
+
"20",
|
|
22
|
+
"21",
|
|
23
|
+
"23",
|
|
24
|
+
"26",
|
|
25
|
+
"35",
|
|
26
|
+
"36",
|
|
27
|
+
"37",
|
|
28
|
+
"39",
|
|
29
|
+
"40",
|
|
30
|
+
"46",
|
|
31
|
+
"47",
|
|
32
|
+
"48",
|
|
33
|
+
"49",
|
|
34
|
+
"51",
|
|
35
|
+
"60",
|
|
36
|
+
"62"
|
|
37
|
+
],
|
|
38
|
+
"rulings": "REJECTED. Exhaustive one-round review of original steps 0 through 62, including credentials, temporal state, captured paths, request content, demanded calls and refusals.\nL1. Steps 2,3: delete both uncaused authentication refusals (the same cause twice consecutively). Record any resulting defensive-branch coverage with a vendor-backed reason rather than contriving a replacement refusal.\nL2. Steps 14,15,16: in 14 capture the form action from the hosted page (the runner supports text:<regex>). In 15 submit that captured action instead of constructing co_url + /pay, and rename the action as supplying payment details and starting a free trial with no immediate charge. Delete 16: a failing repeat of the completed request in this sitting is expressly rejected by the bar; a 'lost response' written only in its title does not override that rule.\nL3. Steps 19,20,21,23: after 19 add a two-hour wait to let the newly created World run. In 20 report completed hour IDs for 2026-01-14T15 and 2026-01-14T16, not T10/T11 preceding creation at 15:00. In 21 retry the actual T16 event. Reduce 23's wait from 27030m to 26910m so it still reaches 2 February 09:30.\nL4. Step 26: delete the disconnected duplicate-email customer creation (no Labs billing/portal request causes it). Keep 28–30, whose refusal has a concrete missing-customer cause and subsequent support intervention.\nL5. Steps 35,36,37,39,40,47,48,49,51: after 35 GET its captured pco_url and capture its displayed Pay form action before Grace leaves the tab. Set 36's wait to 1500m (25 hours), reflecting the vendor's 24-hour TTL. Submit the captured stale form action in 37. In 39 GET pco_url returned by 38 rather than rebuilding buy.polar.sh from the secret; capture its new form action and submit it in 40. Set 47 to Thursday 12 February with wait 1380m (23 hours after Grace returns at Wednesday 11 February 10:30). After 48 GET its returned mco_url and capture the displayed form action; submit it in 49. Set 51's wait to 90720m to retain Thursday 16 April 09:30. The new page-read after 35 and after 48 belong to those original step numbers for apply-rulings. Fix the twin TTL along with the life, using Polar's published config/model source; never hide the twin's 1-hour expiry defect in expectations.\nL6. Step 46: delete the fabricated unknown-checkout refusal; no actor has caused this request beyond the author choosing a fake id.\nL7. Steps 60,62: delete the filtered email/name read-backs after this same refresh actor already retrieved the complete collections in 59/61. Preserve the full refresh lists 56–59,61.\nAll remaining original steps passed the bar. Vendor sources: polar/spec/openapi.json.gz CheckoutProductsCreate and CheckoutConfirmStripe; https://polar.sh/docs/features/checkout/session; https://polar.sh/docs/features/subscriptions/trials; https://github.com/polarsource/polar/blob/main/server/polar/config.py CHECKOUT_TTL_SECONDS = 24 hours; model checkout.py uses that value. Dates were independently calculated from 2026-01-01 and all waits. Demand verified from cached twin-world 96ca4478bb39 and open-autonomy 0841076bed91.",
|
|
39
|
+
"doubts": [
|
|
40
|
+
"The customer-life frame calls this a year although it ends in April, and the full life does not show leaving the vendor; this is a scope/wording doubt rather than a ruling under the explicit rejection list."
|
|
41
|
+
],
|
|
42
|
+
"applied": {
|
|
43
|
+
"from": "0e480c8fa63a647b2677bfd55a059975f365695fbcc86e89f64e8589b515559a",
|
|
44
|
+
"wasPlausible": false,
|
|
45
|
+
"steps": [
|
|
46
|
+
"2",
|
|
47
|
+
"3",
|
|
48
|
+
"14",
|
|
49
|
+
"15",
|
|
50
|
+
"16",
|
|
51
|
+
"19",
|
|
52
|
+
"20",
|
|
53
|
+
"21",
|
|
54
|
+
"23",
|
|
55
|
+
"26",
|
|
56
|
+
"35",
|
|
57
|
+
"36",
|
|
58
|
+
"37",
|
|
59
|
+
"39",
|
|
60
|
+
"40",
|
|
61
|
+
"46",
|
|
62
|
+
"47",
|
|
63
|
+
"48",
|
|
64
|
+
"49",
|
|
65
|
+
"51",
|
|
66
|
+
"60",
|
|
67
|
+
"62"
|
|
68
|
+
],
|
|
69
|
+
"rulings": "REJECTED. Exhaustive one-round review of original steps 0 through 62, including credentials, temporal state, captured paths, request content, demanded calls and refusals.\nL1. Steps 2,3: delete both uncaused authentication refusals (the same cause twice consecutively). Record any resulting defensive-branch coverage with a vendor-backed reason rather than contriving a replacement refusal.\nL2. Steps 14,15,16: in 14 capture the form action from the hosted page (the runner supports text:<regex>). In 15 submit that captured action instead of constructing co_url + /pay, and rename the action as supplying payment details and starting a free trial with no immediate charge. Delete 16: a failing repeat of the completed request in this sitting is expressly rejected by the bar; a 'lost response' written only in its title does not override that rule.\nL3. Steps 19,20,21,23: after 19 add a two-hour wait to let the newly created World run. In 20 report completed hour IDs for 2026-01-14T15 and 2026-01-14T16, not T10/T11 preceding creation at 15:00. In 21 retry the actual T16 event. Reduce 23's wait from 27030m to 26910m so it still reaches 2 February 09:30.\nL4. Step 26: delete the disconnected duplicate-email customer creation (no Labs billing/portal request causes it). Keep 28–30, whose refusal has a concrete missing-customer cause and subsequent support intervention.\nL5. Steps 35,36,37,39,40,47,48,49,51: after 35 GET its captured pco_url and capture its displayed Pay form action before Grace leaves the tab. Set 36's wait to 1500m (25 hours), reflecting the vendor's 24-hour TTL. Submit the captured stale form action in 37. In 39 GET pco_url returned by 38 rather than rebuilding buy.polar.sh from the secret; capture its new form action and submit it in 40. Set 47 to Thursday 12 February with wait 1380m (23 hours after Grace returns at Wednesday 11 February 10:30). After 48 GET its returned mco_url and capture the displayed form action; submit it in 49. Set 51's wait to 90720m to retain Thursday 16 April 09:30. The new page-read after 35 and after 48 belong to those original step numbers for apply-rulings. Fix the twin TTL along with the life, using Polar's published config/model source; never hide the twin's 1-hour expiry defect in expectations.\nL6. Step 46: delete the fabricated unknown-checkout refusal; no actor has caused this request beyond the author choosing a fake id.\nL7. Steps 60,62: delete the filtered email/name read-backs after this same refresh actor already retrieved the complete collections in 59/61. Preserve the full refresh lists 56–59,61.\nAll remaining original steps passed the bar. Vendor sources: polar/spec/openapi.json.gz CheckoutProductsCreate and CheckoutConfirmStripe; https://polar.sh/docs/features/checkout/session; https://polar.sh/docs/features/subscriptions/trials; https://github.com/polarsource/polar/blob/main/server/polar/config.py CHECKOUT_TTL_SECONDS = 24 hours; model checkout.py uses that value. Dates were independently calculated from 2026-01-01 and all waits. Demand verified from cached twin-world 96ca4478bb39 and open-autonomy 0841076bed91."
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"about": "polar's decision table (the P3 procedure). Polar is the money in of Volter's platform (twin-world apps/billing over @polar-sh/sdk) and of Open Autonomy's patronage (apps/platform/src/polar.ts over fetch): an organization's meters and products, checkouts paid on the hosted checkout page (which make the order and, for a recurring product, the subscription), customers and their state by the application's own id, customer sessions for the portal, usage events against the meters, and the signed webhooks of the organization's endpoints. The core serves the meters and the webhook endpoints' list (plain objects); every answer that embeds another object or write that makes others is a handler. Every other operation is the gap, those of a declared resource listed in the manifest's unmodeled.",
|
|
3
|
+
"decisions": [
|
|
4
|
+
{
|
|
5
|
+
"operation": "meters:list",
|
|
6
|
+
"demand": "Twin's biller finds its meters by name at boot (apps/billing/src/polar.ts:27)",
|
|
7
|
+
"mechanism": "core",
|
|
8
|
+
"why": "a plain list of stored meters, newest first, filtered by name"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"operation": "meters:create",
|
|
12
|
+
"demand": "Twin's biller makes a missing meter (apps/billing/src/polar.ts:32)",
|
|
13
|
+
"mechanism": "core",
|
|
14
|
+
"why": "a plain create: the meter as given, with what the server assigns (created_at, organization_id, archived_at, metadata)"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"operation": "products:list",
|
|
18
|
+
"demand": "Twin's biller finds its Team product by name at boot (apps/billing/src/polar.ts:40)",
|
|
19
|
+
"mechanism": "handler",
|
|
20
|
+
"why": "the full stored products, including minted full prices and their meter references, filtered by archive/recurrence/query"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"operation": "products:create",
|
|
24
|
+
"demand": "Twin's biller makes its Team product (apps/billing/src/polar.ts:43); Open Autonomy makes each tier's monthly and one-time product (apps/platform/src/polar.ts:40)",
|
|
25
|
+
"mechanism": "handler",
|
|
26
|
+
"why": "each price is given an id, a price of no known amount type is refused (422), and the product answers its prices by amount type"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"operation": "checkouts:create",
|
|
30
|
+
"demand": "Twin's biller opens the Team checkout for an org (apps/billing/src/polar.ts:93); Open Autonomy opens a patron's checkout (apps/platform/src/polar.ts:81)",
|
|
31
|
+
"mechanism": "handler",
|
|
32
|
+
"why": "the session for the first product at its first price, open for 24 hours, with its client secret and the hosted page's url; no product, an unknown one or an unknown customer is refused (422)"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"operation": "checkouts:get",
|
|
36
|
+
"demand": "Open Autonomy's thanks page reads the checkout back (apps/platform/src/polar.ts:129)",
|
|
37
|
+
"mechanism": "handler",
|
|
38
|
+
"why": "the stored whole checkout including its product, prices and URL; an unknown id is 404"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"operation": "checkouts:client_get",
|
|
42
|
+
"demand": "the hosted checkout page every checkout's url opens (Twin apps/billing/src/polar.ts:94, Open Autonomy apps/platform/src/polar.ts:88)",
|
|
43
|
+
"mechanism": "handler",
|
|
44
|
+
"why": "the page reads its session by the client secret, the organization beside it (CheckoutPublic)"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"operation": "checkouts:client_confirm",
|
|
48
|
+
"demand": "the hosted checkout page's Pay (the same flows)",
|
|
49
|
+
"mechanism": "handler",
|
|
50
|
+
"why": "the customer is found or made, the order made and paid (order.created, order.paid), a recurring product's subscription started (trialing through its trial), and the checkout stores succeeded while confirmation answers confirmed plus its customer session token; an expired checkout is 410, one not open 403"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"operation": "orders:list",
|
|
54
|
+
"demand": "Open Autonomy's thanks page lists the checkout's orders (apps/platform/src/polar.ts:133)",
|
|
55
|
+
"mechanism": "handler",
|
|
56
|
+
"why": "each order embeds its customer, product, subscription and items; filtered by checkout, customer, product, subscription and status"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"operation": "customers:create",
|
|
60
|
+
"demand": "Twin's biller makes an org's customer before its portal session (apps/billing/src/polar.ts:104)",
|
|
61
|
+
"mechanism": "handler",
|
|
62
|
+
"why": "an individual customer, its email required; an email or external id another customer holds is refused (422)"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"operation": "customers:get",
|
|
66
|
+
"demand": "Open Autonomy reads a paid order's customer for the patron's name (apps/platform/src/polar.ts:103)",
|
|
67
|
+
"mechanism": "handler",
|
|
68
|
+
"why": "the stored whole CustomerIndividual through ctx.own; an unknown id is 404"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"operation": "customers:get_state_external",
|
|
72
|
+
"demand": "Twin's biller reads an org's plan and usage (apps/billing/src/polar.ts:74)",
|
|
73
|
+
"mechanism": "handler",
|
|
74
|
+
"why": "computed: the customer with its active or trialing subscriptions and each meter's consumed units folded from its events; no customer with the id is 404 (the biller's Free)"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"operation": "customer-sessions:create",
|
|
78
|
+
"demand": "Twin's biller opens the customer portal for an org (apps/billing/src/polar.ts:100)",
|
|
79
|
+
"mechanism": "handler",
|
|
80
|
+
"why": "a token for the customer named by id or external id, an hour long, and its customer_portal_url; no such customer is refused (422, the validation error the spec documents)"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"operation": "events:ingest",
|
|
84
|
+
"demand": "Twin's biller reports usage (apps/billing/src/polar.ts:114)",
|
|
85
|
+
"mechanism": "handler",
|
|
86
|
+
"why": "a batch: an external_id already ingested is a duplicate, not a second event; the customer named by its external id; answers inserted and duplicates"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"operation": "webhooks:create_webhook_endpoint",
|
|
90
|
+
"demand": "Open Autonomy's order.paid and order.created webhooks (apps/platform/src/polar.ts:160) reach it only through the endpoint its operator registers, whose secret it is given (apps/platform/src/polar.ts:155)",
|
|
91
|
+
"mechanism": "handler",
|
|
92
|
+
"why": "the endpoint's signing secret is drawn from the World and answered once; url, format and events are required (422)"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"operation": "customers:list",
|
|
96
|
+
"demand": "the vendor-backed refresh reads customer back (the manifest's refresh of customer)",
|
|
97
|
+
"mechanism": "handler",
|
|
98
|
+
"why": "the customer's whole: Polar's id, the application's external id, its email; newest first, by email, query or a live subscription"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"operation": "events:list",
|
|
102
|
+
"demand": "the vendor-backed refresh reads event back (the manifest's refresh of event)",
|
|
103
|
+
"mechanism": "handler",
|
|
104
|
+
"why": "each usage event in its stored vendor shape with its resolved customer (UserEvent), newest first, by customer, name or a meter's filter"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"operation": "checkouts:list",
|
|
108
|
+
"demand": "the vendor-backed refresh reads Checkout back (the manifest's refresh of Checkout)",
|
|
109
|
+
"mechanism": "handler",
|
|
110
|
+
"why": "each checkout with its product and prices embedded (checkoutView, as checkouts:get answers it), newest first"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"operation": "subscriptions:list",
|
|
114
|
+
"demand": "the vendor-backed refresh reads Subscription back (the manifest's refresh of Subscription)",
|
|
115
|
+
"mechanism": "handler",
|
|
116
|
+
"why": "each subscription with its customer, product and prices embedded (subscriptionView), the latest started first"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"operation": "webhooks:list_webhook_endpoints",
|
|
120
|
+
"demand": "the vendor-backed refresh reads WebhookEndpoint back (the manifest's refresh of WebhookEndpoint)",
|
|
121
|
+
"mechanism": "core",
|
|
122
|
+
"why": "a plain object: the endpoint as its create stored and answered it, newest first (the manifest's order), paged by the core"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"operation": "door:accessTokens",
|
|
126
|
+
"demand": "every application's POLAR_ACCESS_TOKEN (Twin apps/billing/src/polar.ts:15, Open Autonomy apps/platform/src/polar.ts:20)",
|
|
127
|
+
"mechanism": "door",
|
|
128
|
+
"why": "an Organization Access Token is made on the organization's settings page; the API makes none"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"operation": "door:revokeToken",
|
|
132
|
+
"demand": "a token the organization no longer trusts, refused from then on",
|
|
133
|
+
"mechanism": "door",
|
|
134
|
+
"why": "a token is revoked on the settings page; the API revokes none"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"operation": "door:appCredentials",
|
|
138
|
+
"demand": "the token the World's application holds at boot (the descriptor's credentialDoor)",
|
|
139
|
+
"mechanism": "door",
|
|
140
|
+
"why": "the runtime issues the application's token as the settings page would make it"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"operation": "door:deliveries",
|
|
144
|
+
"demand": "what Open Autonomy's /webhooks/polar was sent (apps/platform/src/polar.ts:153)",
|
|
145
|
+
"mechanism": "door",
|
|
146
|
+
"why": "the webhooks the World delivered, as the receiving server got them (headers and body), in order"
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"measured": "the applications in scope (twin-world's generated/demand.json, vendor polar: Twin and Open Autonomy) read at the demand scan's clones (~/.cache/twin-demand): volter-ai/twin-world at 96ca4478bb39 (apps/billing, the Volter platform's biller over @polar-sh/sdk) and open-autonomy-org/open-autonomy at 0841076bed91 (apps/platform/src/polar.ts, patronage over Polar's REST API with fetch). Every other scoped application (RH2, Volter Harness, Substrate, Workbench, Volter Browsers, tabnode, almostcdp, localrouter, Volter Editor, the videogame.ai site, Dub, Rallly, Postiz, Twenty, LibreChat, Cal.com) names no Polar host, SDK or POLAR_ variable at run time (Dub's only match is a seed data file, LibreChat's its lockfile). Ruled out: Open Autonomy's apps/platform/test (a mock), world.ts (the World's seed: it names the twin's URL and signs no call), twin-world's scripts and cookbook (they stand the stack up; the calls are the biller's). The platform's own callers in twin-world (packages/, cookbook/, scripts/, docs/contributing/architecture.md) name the pack only to link it into a World and call no operation, door or screen of it.",
|
|
3
|
+
"applications": [
|
|
4
|
+
{
|
|
5
|
+
"name": "volter-ai/twin-world apps/billing",
|
|
6
|
+
"commit": "96ca4478bb39",
|
|
7
|
+
"client": "@polar-sh/sdk",
|
|
8
|
+
"backend": [
|
|
9
|
+
{ "call": "meters.list", "operation": "meters:list", "evidence": "apps/billing/src/polar.ts:27" },
|
|
10
|
+
{ "call": "meters.create", "operation": "meters:create", "evidence": "apps/billing/src/polar.ts:32" },
|
|
11
|
+
{ "call": "products.list", "operation": "products:list", "evidence": "apps/billing/src/polar.ts:40" },
|
|
12
|
+
{ "call": "products.create", "operation": "products:create", "evidence": "apps/billing/src/polar.ts:43" },
|
|
13
|
+
{ "call": "customers.getStateExternal", "operation": "customers:get_state_external", "evidence": "apps/billing/src/polar.ts:74" },
|
|
14
|
+
{ "call": "checkouts.create", "operation": "checkouts:create", "evidence": "apps/billing/src/polar.ts:93" },
|
|
15
|
+
{ "call": "customerSessions.create", "operation": "customer-sessions:create", "evidence": "apps/billing/src/polar.ts:100" },
|
|
16
|
+
{ "call": "customers.create", "operation": "customers:create", "evidence": "apps/billing/src/polar.ts:104" },
|
|
17
|
+
{ "call": "events.ingest", "operation": "events:ingest", "evidence": "apps/billing/src/polar.ts:114" }
|
|
18
|
+
],
|
|
19
|
+
"flows": [
|
|
20
|
+
{ "flow": "the hosted checkout: the org's admin is sent to the checkout's url, pays, and returns to the billing page", "evidence": "apps/billing/src/polar.ts:94" },
|
|
21
|
+
{ "flow": "the customer portal: the org's admin is sent to the session's customer_portal_url (Manage billing)", "evidence": "apps/billing/src/polar.ts:101" }
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "open-autonomy-org/open-autonomy apps/platform",
|
|
26
|
+
"commit": "0841076bed91",
|
|
27
|
+
"client": "fetch (Polar's REST API)",
|
|
28
|
+
"backend": [
|
|
29
|
+
{ "call": "POST /v1/products/", "operation": "products:create", "evidence": "apps/platform/src/polar.ts:40" },
|
|
30
|
+
{ "call": "POST /v1/checkouts/", "operation": "checkouts:create", "evidence": "apps/platform/src/polar.ts:81" },
|
|
31
|
+
{ "call": "GET /v1/customers/{id}", "operation": "customers:get", "evidence": "apps/platform/src/polar.ts:103" },
|
|
32
|
+
{ "call": "GET /v1/checkouts/{id}", "operation": "checkouts:get", "evidence": "apps/platform/src/polar.ts:129" },
|
|
33
|
+
{ "call": "GET /v1/orders/?checkout_id=", "operation": "orders:list", "evidence": "apps/platform/src/polar.ts:133" }
|
|
34
|
+
],
|
|
35
|
+
"events": [
|
|
36
|
+
{ "event": "order.paid", "evidence": "apps/platform/src/polar.ts:160 (Standard Webhooks, verified at apps/platform/src/polar.ts:144)" },
|
|
37
|
+
{ "event": "order.created", "evidence": "apps/platform/src/polar.ts:160" }
|
|
38
|
+
],
|
|
39
|
+
"flows": [
|
|
40
|
+
{ "flow": "the hosted checkout: a patron is sent (303) to the checkout's url, pays, and returns to the thanks page with {CHECKOUT_ID} filled", "evidence": "apps/platform/src/polar.ts:88" },
|
|
41
|
+
{ "flow": "the webhook endpoint: the operator registers the platform's /webhooks/polar and gives it the endpoint's secret (POLAR_WEBHOOK_SECRET), without which no order.paid reaches it", "evidence": "apps/platform/src/polar.ts:155" }
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
{
|
|
2
|
+
"vendor": "polar",
|
|
3
|
+
"life": {
|
|
4
|
+
"steps": 59,
|
|
5
|
+
"verdict": "plausible",
|
|
6
|
+
"judge": "Contributor 16",
|
|
7
|
+
"authors": [
|
|
8
|
+
"Contributor 39"
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
"failures": [],
|
|
12
|
+
"flags": [],
|
|
13
|
+
"coverage": {
|
|
14
|
+
"vendor": "polar",
|
|
15
|
+
"missing": 27,
|
|
16
|
+
"stale": [],
|
|
17
|
+
"code": {
|
|
18
|
+
"lines": 763,
|
|
19
|
+
"run": 750,
|
|
20
|
+
"recorded": 2,
|
|
21
|
+
"missing": 11
|
|
22
|
+
},
|
|
23
|
+
"state": {
|
|
24
|
+
"declared": 9,
|
|
25
|
+
"reached": 2,
|
|
26
|
+
"recorded": 0,
|
|
27
|
+
"missing": [
|
|
28
|
+
"refusal Checkout.status: checkouts:client_confirm confirmed|succeeded|failed|expired → (stays)",
|
|
29
|
+
"move Checkout.status: vendor confirmed → succeeded",
|
|
30
|
+
"move Checkout.status: time open → expired",
|
|
31
|
+
"refusal Subscription.status: checkouts:client_confirm active|trialing → (stays)",
|
|
32
|
+
"move Subscription.status: vendor incomplete → active",
|
|
33
|
+
"move Subscription.status: vendor incomplete → trialing",
|
|
34
|
+
"move Subscription.status: time trialing → active"
|
|
35
|
+
],
|
|
36
|
+
"undeclared": [
|
|
37
|
+
"Checkout.status: confirmed → succeeded by checkout.update",
|
|
38
|
+
"Checkout.status: confirmed → succeeded by checkouts:client_confirm",
|
|
39
|
+
"Checkout.status: open → expired by checkout.update",
|
|
40
|
+
"Order.status: pending → paid by checkouts:client_confirm",
|
|
41
|
+
"Order.status: pending → paid by order.pay",
|
|
42
|
+
"Subscription.status: incomplete → active by checkouts:client_confirm",
|
|
43
|
+
"Subscription.status: incomplete → active by subscription.activate",
|
|
44
|
+
"Subscription.status: incomplete → trialing by subscription.activate",
|
|
45
|
+
"Subscription.status: trialing → active by subscription.update"
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
"files": [
|
|
49
|
+
{
|
|
50
|
+
"file": "semantics/doors.ts",
|
|
51
|
+
"lines": {
|
|
52
|
+
"found": 28,
|
|
53
|
+
"hit": 28
|
|
54
|
+
},
|
|
55
|
+
"missing": []
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"file": "semantics/states.ts",
|
|
59
|
+
"lines": {
|
|
60
|
+
"found": 34,
|
|
61
|
+
"hit": 34
|
|
62
|
+
},
|
|
63
|
+
"missing": []
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"file": "semantics/customers.ts",
|
|
67
|
+
"lines": {
|
|
68
|
+
"found": 34,
|
|
69
|
+
"hit": 32
|
|
70
|
+
},
|
|
71
|
+
"missing": [
|
|
72
|
+
{
|
|
73
|
+
"from": 60,
|
|
74
|
+
"to": 60,
|
|
75
|
+
"fn": "duplicateExternal"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"from": 66,
|
|
79
|
+
"to": 66,
|
|
80
|
+
"fn": "duplicateEmail"
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"file": "semantics/customer-sessions.ts",
|
|
86
|
+
"lines": {
|
|
87
|
+
"found": 7,
|
|
88
|
+
"hit": 7
|
|
89
|
+
},
|
|
90
|
+
"missing": []
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"file": "semantics/webhooks.ts",
|
|
94
|
+
"lines": {
|
|
95
|
+
"found": 17,
|
|
96
|
+
"hit": 17
|
|
97
|
+
},
|
|
98
|
+
"missing": []
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"file": "semantics/shared.ts",
|
|
102
|
+
"lines": {
|
|
103
|
+
"found": 245,
|
|
104
|
+
"hit": 236
|
|
105
|
+
},
|
|
106
|
+
"missing": [
|
|
107
|
+
{
|
|
108
|
+
"from": 331,
|
|
109
|
+
"to": 339,
|
|
110
|
+
"fn": "compareClause"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"file": "semantics/around.ts",
|
|
116
|
+
"lines": {
|
|
117
|
+
"found": 12,
|
|
118
|
+
"hit": 12
|
|
119
|
+
},
|
|
120
|
+
"missing": []
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"file": "semantics/products.ts",
|
|
124
|
+
"lines": {
|
|
125
|
+
"found": 34,
|
|
126
|
+
"hit": 34
|
|
127
|
+
},
|
|
128
|
+
"missing": []
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"file": "semantics/orders.ts",
|
|
132
|
+
"lines": {
|
|
133
|
+
"found": 7,
|
|
134
|
+
"hit": 7
|
|
135
|
+
},
|
|
136
|
+
"missing": []
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"file": "semantics/subscriptions.ts",
|
|
140
|
+
"lines": {
|
|
141
|
+
"found": 10,
|
|
142
|
+
"hit": 10
|
|
143
|
+
},
|
|
144
|
+
"missing": []
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"file": "semantics/clock.ts",
|
|
148
|
+
"lines": {
|
|
149
|
+
"found": 17,
|
|
150
|
+
"hit": 17
|
|
151
|
+
},
|
|
152
|
+
"missing": []
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"file": "semantics/events.ts",
|
|
156
|
+
"lines": {
|
|
157
|
+
"found": 37,
|
|
158
|
+
"hit": 37
|
|
159
|
+
},
|
|
160
|
+
"missing": []
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"file": "semantics/index.ts",
|
|
164
|
+
"lines": {
|
|
165
|
+
"found": 27,
|
|
166
|
+
"hit": 27
|
|
167
|
+
},
|
|
168
|
+
"missing": []
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"file": "semantics/tenant.ts",
|
|
172
|
+
"lines": {
|
|
173
|
+
"found": 2,
|
|
174
|
+
"hit": 2
|
|
175
|
+
},
|
|
176
|
+
"missing": []
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"file": "semantics/checkouts.ts",
|
|
180
|
+
"lines": {
|
|
181
|
+
"found": 85,
|
|
182
|
+
"hit": 85
|
|
183
|
+
},
|
|
184
|
+
"missing": []
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"file": "screens/checkout.ts",
|
|
188
|
+
"lines": {
|
|
189
|
+
"found": 21,
|
|
190
|
+
"hit": 21
|
|
191
|
+
},
|
|
192
|
+
"missing": []
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"file": "screens/portal.ts",
|
|
196
|
+
"lines": {
|
|
197
|
+
"found": 13,
|
|
198
|
+
"hit": 13
|
|
199
|
+
},
|
|
200
|
+
"missing": []
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"file": "manifest.ts",
|
|
204
|
+
"lines": {
|
|
205
|
+
"found": 101,
|
|
206
|
+
"hit": 101
|
|
207
|
+
},
|
|
208
|
+
"missing": []
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"file": "index.ts",
|
|
212
|
+
"lines": {
|
|
213
|
+
"found": 7,
|
|
214
|
+
"hit": 7
|
|
215
|
+
},
|
|
216
|
+
"missing": []
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"file": "server.ts",
|
|
220
|
+
"lines": {
|
|
221
|
+
"found": 4,
|
|
222
|
+
"hit": 2
|
|
223
|
+
},
|
|
224
|
+
"missing": []
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"file": "fetch.ts",
|
|
228
|
+
"lines": {
|
|
229
|
+
"found": 21,
|
|
230
|
+
"hit": 21
|
|
231
|
+
},
|
|
232
|
+
"missing": []
|
|
233
|
+
}
|
|
234
|
+
]
|
|
235
|
+
},
|
|
236
|
+
"examples": {
|
|
237
|
+
"done": true,
|
|
238
|
+
"replayed": true,
|
|
239
|
+
"verdict": "plausible",
|
|
240
|
+
"failures": [],
|
|
241
|
+
"line": "examples: 31 published, 0 of patch-removed operations, 0 of operations the twin does not serve, 31 replayed, 0 recorded; 0 failing done: yes"
|
|
242
|
+
},
|
|
243
|
+
"breadth": {
|
|
244
|
+
"operations": 186,
|
|
245
|
+
"gap": 166,
|
|
246
|
+
"handler": 17,
|
|
247
|
+
"core": 3
|
|
248
|
+
}
|
|
249
|
+
}
|