Service catalog coverage
docs/CATALOG_COVERAGE.md Β· the same file GitHub renders Β·Edit on GitHub Β·Markdown
Where each section of the geviti "Mockingbird wish list β service catalog" (2026-09-20) lives in this repo, how it is proven, and what the proof turned up. Every package follows AUTHORING_A_SERVICE.md and ships the same evidence:
- Self-parity: two independent instances run random OpenAPI-driven walks and must agree after every command, with every response conforming to the package's contract; each suite asserts the walks reach every parity-enabled operation and that a deliberately divergent instance is caught.
- Acceptance: every acceptance bullet of the catalog section, driven through
test/consumer.ts, a port of the consumer's own client and webhook-receiver code. - SDK drop-in: the vendor's official SDK, at the version the consumer pins, pointed at the mock (where the consumer uses one).
- Live parity (
bun run parity:service -- <name>): the same walks against the real sandbox, when credentials exist in Vaultsecret/personal/prd.
| Β§ | Vendor | Package | SDK drop-in | Live parity |
|---|---|---|---|---|
| S1 | Stripe | service-stripe |
stripe-node 16.12 (2024-06-20, 2025-02-24.acacia), 17.7 | passing on well-formed walks (parity -- --valid-only) |
| S2 | Gene by Gene | service-genebygene |
β (raw fetch) | no credentials |
| S3 | RxVortex (Strive) | service-rxvortex |
β (raw fetch) | no credentials |
| S4 | Flex | service-flex |
svix 1.41 (webhook verification) | no credentials |
| S5 | Mail inbox | service-mailosaur |
mailosaur 11.1 | no credentials |
| S6 | PostHog | service-posthog |
posthog-node 5.52, @posthog/core 1.54, posthog-js 1.433 (transport) | no credentials |
| S7 | AWS Bedrock Runtime | service-bedrock |
@aws-sdk/client-bedrock-runtime, AgentCore, @ai-sdk/amazon-bedrock + ai | no credentials |
| S8 | Twilio | service-twilio |
twilio 5.10 | passing (Lookup v2, free operations only) |
| S9 | Resend | service-resend |
resend 4.8, svix 1.41 | no credentials |
| S10 | AHA | service-aha |
β (raw fetch) | no credentials |
| S11 | Daily.co | service-daily |
β (raw fetch) | no credentials |
| S12 | Pharmetika, VPI, Wholescripts, portal agent | service-pharmetika, -vpi, -wholescripts, -portal-agent |
β | no credentials |
| S13 | AWS Polly + Transcribe | service-aws-speech |
@aws-sdk/client-polly, -transcribe-streaming, -transcribe | no credentials |
| S14 | LlamaCloud | service-llamacloud |
llama-cloud-services 0.6.88 (Python, opt-in) | no credentials |
| S15 | Legacy Makor AI (CPG) | service-makor-cpg |
β | no credentials |
| S16 | Intercom | service-intercom |
β (raw fetch) | no credentials |
| S17 | Slack | service-slack |
@slack/web-api 7.9 | no credentials |
| S18 | OTLP + OpenObserve | service-otel |
OpenTelemetry exporters 0.201 (HTTP JSON and protobuf) | no credentials |
| S19 | Customer.io, Klaviyo, First Promoter | service-customerio, -klaviyo, -firstpromoter |
@customerio/cdp-analytics-node 0.5.6 | no credentials |
| S20 | Formbricks | service-formbricks |
β | no credentials |
| S21 | Google Places / Maps / Geocode | service-google-maps |
Maps JS shim evaluated in a fake window | no credentials |
| S22 | Persona | service-persona |
β | no credentials |
| S23 | Healthie | service-healthie |
graphql-request 7.2, awesome-graphql-client 0.14 (the consumer's clients) | no credentials |
| S24 | Optimal DX | service-odx |
β | no credentials |
| S25 | EasyPost, Fullscript, Google Calendar, Plane, Payload CMS, CareTalk, Edamam, Prism | service-easypost, -fullscript, -google-calendar, -plane, -payload-cms, -caretalk, -edamam, -prism |
@googleapis/calendar 9.8 | no credentials |
"No credentials" means the package's scripts/parity.ts exits 2 and names the
MOCKINGBIRD_<VENDOR>_* keys it needs; add them to Vault and bun run parity:service -- <name>
runs the live walk. The Junction mock (catalog: "already exists") is unchanged.
What live parity fixed in the Stripe mock
Walks against Stripe test mode, each confirmed with a targeted probe before changing the mock:
- ids in
No such β¦errors are escaped Ruby-style (<β<,'β\'), get a whitespace/quotes hint, and are elided past 998 characters; starting_afteris resolved before "both cursors" and before the path's customer;customer+customer_accountandscheduled+*_atfilters are mutually exclusive; an unknowntest_clockfilter isNo such billingclock; the customer balance-transaction cursor is anabstracttransaction;package_dimensions: order length, width, height, weight; plain decimals only; at most 15 fraction digits, then at most two decimal places, echoed as a Ruby Float (1.0e-07);marketing_features[].nameis capped at 80 characters (docs say 5000) and trimmed;address.countryis upper-cased;metadatagiven as a scalar gets Stripe's own message;- search:
total_countonly withexpand[]=total_count(lists refuse it with "cannot be included"); an invalid page names the token asparam, elided past 1000 characters; - a request line over 16 KiB is nginx's HTML 414;
- a declined PaymentIntent omits (never nulls)
advice_code/decline_code/network_decline_codeinlast_payment_error(found by self-parity conformance).
Malformed-request walks (the default parity mode) still diverge on Stripe's per-endpoint
validation order for requests carrying several invalid parameters at once; --valid-only
compares behaviour on well-formed requests, which is what the consumer sends.
Consumer bugs and catalog discrepancies the mocks surfaced
Each is pinned in a test comment in the named package.
- Bedrock: chat retries never fire (AI SDK v6 emits
startbefore an error part);BedrockLlmProvider's stream-error branches are unreachable (the AWS SDK throws exception frames); the catalog'sreport_rx_symptominput shape is wrong. - AHA:
AhaServicenever checks the innerstatus; the lab-provider cancel sends the AHAorder_numberaspartner_order_id(G-A1); "Non Scheduled Update" is not ignored. - Daily: the EMR patient token's
expis in milliseconds; backend rooms'nbfblocks the 5-minute early join the member token allows. - Persona: every outcome passes through
completed, so a later-declined member was already marked verified; a wrong-length signature is a 500. - Google Maps: native autocomplete counts
ZERO_RESULTSas success, so manual entry never engages for unknown addresses. - Healthie:
createLocationsends line 2 as the city; an undeclaredtimezonevariable is ignored; the forms receiver reads a field its query never selects. - Optimal DX:
updateWebhooksends method'Put', which becomes a GET; stale registrations accumulate. - Mailosaur: the SDK always connects to port 443, so G-M1 needs
HTTPS_PROXY+NODE_EXTRA_CA_CERTS(the mock serves TLS with--tls-port), not only a base URL. - Pharmetika: a refused cancel reports "[object Object]"; the portal-agent callback
receiver rejects
pharmacyId: "pharmetika". VPI has no delivered state and polls only page 1 of 5; Wholescripts maps "Complete" to shipped. - RxVortex: an empty
errors: []yieldsinvalid fields=, not the plain message. - LlamaCloud: Makor's default project
"default"β the backend's"Default". - Twilio: the dispatcher treats every provider status β₯ 400 (5xx included) as definite.
- Customer.io under Bun reports
ConnectionRefusedwhere the code expectsECONNREFUSED; First Promoter is never called outside production and requires an https URL; Klaviyo is sent a user token as the profile id. - OTel: the EMR pino bridge sends lowercase severity while recipes filter
'ERROR'. - Flex, Stripe, Slack, Formbricks: several fixtures and files the catalog cites exist only on
the
crvouga/makor-voice-chatbranch or in history (e.g.flexCatalogMappings.jsonhas 663 rows, not 67).