@oxygen-agent/cli 1.1011.326 → 1.1011.440

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.
Files changed (98) hide show
  1. package/README.md +1 -1
  2. package/dist/command-manifest.js +15 -4
  3. package/dist/connectors-commands.d.ts +4 -1
  4. package/dist/connectors-commands.js +84 -10
  5. package/dist/contract-flags.d.ts +2 -0
  6. package/dist/contract-flags.js +26 -11
  7. package/dist/crm-support-flags.d.ts +11 -0
  8. package/dist/crm-support-flags.js +60 -0
  9. package/dist/customer-operation-commands.d.ts +5 -0
  10. package/dist/customer-operation-commands.js +101 -0
  11. package/dist/database-query-flags.d.ts +2 -0
  12. package/dist/database-query-flags.js +6 -0
  13. package/dist/help.d.ts +3 -1
  14. package/dist/help.js +43 -0
  15. package/dist/http-client.d.ts +2 -0
  16. package/dist/http-client.js +41 -1
  17. package/dist/index.js +640 -234
  18. package/dist/knowledge-repository-commands.js +12 -14
  19. package/dist/mailbox-ramp-notice.d.ts +11 -0
  20. package/dist/mailbox-ramp-notice.js +53 -0
  21. package/dist/settings-commands.d.ts +11 -0
  22. package/dist/settings-commands.js +73 -0
  23. package/dist/skills.d.ts +5 -4
  24. package/dist/skills.js +106 -79
  25. package/dist/tool-catalog-detail-command.d.ts +7 -0
  26. package/dist/tool-catalog-detail-command.js +19 -0
  27. package/dist/tool-catalog-search-window.d.ts +6 -0
  28. package/dist/tool-catalog-search-window.js +12 -0
  29. package/dist/transcript.js +1 -0
  30. package/node_modules/@oxygen/shared/dist/bounded-read-result.d.ts +4 -0
  31. package/node_modules/@oxygen/shared/dist/bounded-read-result.js +25 -0
  32. package/node_modules/@oxygen/shared/dist/capability-discovery.d.ts +47 -1
  33. package/node_modules/@oxygen/shared/dist/capability-discovery.js +625 -39
  34. package/node_modules/@oxygen/shared/dist/connection-approval.d.ts +2 -0
  35. package/node_modules/@oxygen/shared/dist/connection-approval.js +2 -0
  36. package/node_modules/@oxygen/shared/dist/contracts/browser-operations.d.ts +2 -0
  37. package/node_modules/@oxygen/shared/dist/contracts/browser-operations.js +110 -0
  38. package/node_modules/@oxygen/shared/dist/contracts/connectors.d.ts +32 -6
  39. package/node_modules/@oxygen/shared/dist/contracts/connectors.js +56 -4
  40. package/node_modules/@oxygen/shared/dist/contracts/crm-attributes.d.ts +4 -0
  41. package/node_modules/@oxygen/shared/dist/contracts/crm-attributes.js +39 -0
  42. package/node_modules/@oxygen/shared/dist/contracts/crm-enrichment-read.d.ts +21 -0
  43. package/node_modules/@oxygen/shared/dist/contracts/crm-enrichment-read.js +15 -0
  44. package/node_modules/@oxygen/shared/dist/contracts/crm-support.d.ts +117 -0
  45. package/node_modules/@oxygen/shared/dist/contracts/crm-support.js +43 -0
  46. package/node_modules/@oxygen/shared/dist/contracts/customer-operations.d.ts +2 -0
  47. package/node_modules/@oxygen/shared/dist/contracts/customer-operations.js +131 -0
  48. package/node_modules/@oxygen/shared/dist/contracts/dashboard-tabs.d.ts +3 -0
  49. package/node_modules/@oxygen/shared/dist/contracts/dashboard-tabs.js +2 -0
  50. package/node_modules/@oxygen/shared/dist/contracts/database.d.ts +30 -0
  51. package/node_modules/@oxygen/shared/dist/contracts/database.js +29 -0
  52. package/node_modules/@oxygen/shared/dist/contracts/integration-connect.d.ts +4 -0
  53. package/node_modules/@oxygen/shared/dist/contracts/integration-connect.js +7 -0
  54. package/node_modules/@oxygen/shared/dist/contracts/knowledge-content-reads.d.ts +43 -0
  55. package/node_modules/@oxygen/shared/dist/contracts/knowledge-content-reads.js +20 -0
  56. package/node_modules/@oxygen/shared/dist/contracts/linkedin-invites-list.d.ts +12 -0
  57. package/node_modules/@oxygen/shared/dist/contracts/linkedin-invites-list.js +8 -0
  58. package/node_modules/@oxygen/shared/dist/contracts/operations.d.ts +48 -2
  59. package/node_modules/@oxygen/shared/dist/contracts/operations.js +68 -2
  60. package/node_modules/@oxygen/shared/dist/contracts/table-grid-query.d.ts +4 -0
  61. package/node_modules/@oxygen/shared/dist/contracts/table-grid-query.js +6 -0
  62. package/node_modules/@oxygen/shared/dist/contracts/table-query-grid.d.ts +21 -0
  63. package/node_modules/@oxygen/shared/dist/contracts/table-query-grid.js +27 -0
  64. package/node_modules/@oxygen/shared/dist/contracts/tool-catalog-detail.d.ts +19 -0
  65. package/node_modules/@oxygen/shared/dist/contracts/tool-catalog-detail.js +10 -0
  66. package/node_modules/@oxygen/shared/dist/contracts/tool-catalog-search-window.d.ts +12 -0
  67. package/node_modules/@oxygen/shared/dist/contracts/tool-catalog-search-window.js +7 -0
  68. package/node_modules/@oxygen/shared/dist/contracts/workspace-pages.d.ts +17 -0
  69. package/node_modules/@oxygen/shared/dist/contracts/workspace-pages.js +49 -0
  70. package/node_modules/@oxygen/shared/dist/decision-ledger-parser.d.ts +32 -0
  71. package/node_modules/@oxygen/shared/dist/decision-ledger-parser.js +303 -0
  72. package/node_modules/@oxygen/shared/dist/decision-ledger.d.ts +10 -0
  73. package/node_modules/@oxygen/shared/dist/decision-ledger.generated.d.ts +2 -0
  74. package/node_modules/@oxygen/shared/dist/decision-ledger.generated.js +717 -0
  75. package/node_modules/@oxygen/shared/dist/decision-ledger.js +20 -0
  76. package/node_modules/@oxygen/shared/dist/email-campaign-ramp.d.ts +104 -0
  77. package/node_modules/@oxygen/shared/dist/email-campaign-ramp.js +250 -0
  78. package/node_modules/@oxygen/shared/dist/mcp-event-contract.d.ts +10 -7
  79. package/node_modules/@oxygen/shared/dist/mcp-event-contract.js +11 -7
  80. package/node_modules/@oxygen/shared/dist/mcp-table-widget.d.ts +50 -0
  81. package/node_modules/@oxygen/shared/dist/mcp-table-widget.js +24 -0
  82. package/node_modules/@oxygen/shared/dist/plan-band.d.ts +8 -0
  83. package/node_modules/@oxygen/shared/dist/plan-band.js +12 -0
  84. package/node_modules/@oxygen/shared/dist/plan-limits.d.ts +20 -0
  85. package/node_modules/@oxygen/shared/dist/plan-limits.js +41 -0
  86. package/node_modules/@oxygen/shared/dist/provider-input-value.d.ts +5 -0
  87. package/node_modules/@oxygen/shared/dist/provider-input-value.js +10 -0
  88. package/node_modules/@oxygen/shared/dist/sequences.d.ts +33 -4
  89. package/node_modules/@oxygen/shared/dist/sequences.js +48 -13
  90. package/node_modules/@oxygen/shared/dist/user-capability-routing.js +17 -0
  91. package/node_modules/@oxygen/shared/dist/version.generated.d.ts +1 -1
  92. package/node_modules/@oxygen/shared/dist/version.generated.js +1 -1
  93. package/node_modules/@oxygen/shared/package.json +8 -6
  94. package/package.json +1 -1
  95. package/node_modules/@oxygen/shared/dist/copilot-skills.d.ts +0 -15
  96. package/node_modules/@oxygen/shared/dist/copilot-skills.generated.d.ts +0 -31
  97. package/node_modules/@oxygen/shared/dist/copilot-skills.generated.js +0 -41
  98. package/node_modules/@oxygen/shared/dist/copilot-skills.js +0 -6
@@ -0,0 +1,717 @@
1
+ export const DECISION_LEDGER_ENTRIES = [
2
+ {
3
+ id: "D1",
4
+ title: "Expensive-tier behavior at approval",
5
+ answer: "(b) expensive tail named separately in the plan, excluded by default, included only via explicit --include-expensive-tail; default per-hit ceiling 50 credits shown in the plan as a named, liftable policy. No mid-run interruption.",
6
+ status: "ratified",
7
+ table: "ratified",
8
+ ratifiedOn: "2026-06-10",
9
+ lands: "Plan rendering + flags at T1b; policy enforcement hardening at T3",
10
+ supersededBy: [],
11
+ partlySupersededBy: [],
12
+ },
13
+ {
14
+ id: "D2",
15
+ title: "Billing on paid-empty attempts",
16
+ answer: "(a) disclosed cost recovery: bill the customer with an honest billed: true flag and plan-time disclosure (\"each empty Serper page bills 0.25\"). Never bill unreachable / invalid_input.",
17
+ status: "ratified",
18
+ table: "ratified",
19
+ ratifiedOn: "2026-06-10",
20
+ lands: "Plan-time disclosure at T1b; executor billing semantics at T2",
21
+ supersededBy: [],
22
+ partlySupersededBy: [],
23
+ },
24
+ {
25
+ id: "D3",
26
+ title: "Free-preflight plan semantics",
27
+ answer: "(a) live_provider_calls: false means \"no paid provider calls\"; registered freeReadCost preflights auto-run at plan time; estimates default-on.",
28
+ status: "ratified",
29
+ table: "ratified",
30
+ ratifiedOn: "2026-06-10",
31
+ lands: "T1a",
32
+ supersededBy: [],
33
+ partlySupersededBy: [],
34
+ },
35
+ {
36
+ id: "D4",
37
+ title: "Probe micro-spend",
38
+ answer: "(b) zero-spend-without-approval absolute; probe_page stays policy-gated opt-in; estimates degrade honestly to deterministic_guess.",
39
+ status: "ratified",
40
+ table: "ratified",
41
+ ratifiedOn: "2026-06-10",
42
+ lands: "T1a/T1b estimate ladder",
43
+ supersededBy: [],
44
+ partlySupersededBy: [],
45
+ },
46
+ {
47
+ id: "D5",
48
+ title: "BYOK hoisting default",
49
+ answer: "(a) hoist-when-connected with a mandatory third-party-spend disclosure line. Named exception: managed Blitz stays ahead of BYOK Apollo for people-search until org-level provider stats exist.",
50
+ status: "ratified",
51
+ table: "ratified",
52
+ ratifiedOn: "2026-06-10",
53
+ lands: "T1a availability/order derivation",
54
+ supersededBy: [],
55
+ partlySupersededBy: [],
56
+ },
57
+ {
58
+ id: "D6",
59
+ title: "Trigger budget default",
60
+ answer: "Open; spec recommends (a) opt-out 500 cr/day + auto-pause",
61
+ status: "open",
62
+ table: "open",
63
+ ratifiedOn: null,
64
+ lands: "T3",
65
+ supersededBy: [],
66
+ partlySupersededBy: [],
67
+ },
68
+ {
69
+ id: "D7",
70
+ title: "workflows call --mode live parity",
71
+ answer: "(a) require approved + max_credits at T0; existing uncapped scripts get typed refusals.",
72
+ status: "ratified",
73
+ table: "ratified",
74
+ ratifiedOn: "2026-06-10",
75
+ lands: "Shipped [v1.162.19]",
76
+ supersededBy: [],
77
+ partlySupersededBy: [],
78
+ },
79
+ {
80
+ id: "D8",
81
+ title: "Cache reuse policy",
82
+ answer: "Open; spec recommends (a) default-on read-through, free hits with credits_saved",
83
+ status: "open",
84
+ table: "open",
85
+ ratifiedOn: null,
86
+ lands: "T2",
87
+ supersededBy: [],
88
+ partlySupersededBy: [],
89
+ },
90
+ {
91
+ id: "D9",
92
+ title: "BlitzAPI COGS",
93
+ answer: "Closed 2026-07-25 (moved from Open): customer price 0.5 cr/op stays; the monthly subscription is booked at $625.30/mo in infra-fixed-costs.ts from the vendor pricing audit — it read $0 while actually billing, so Data-layer margin was overstated. D26/D28 concentrate search and hiring volume on Blitz, which makes this figure margin-critical; re-verify against the bank line each quarter.",
94
+ status: "ratified",
95
+ table: "ratified",
96
+ ratifiedOn: "2026-07-25",
97
+ lands: "Booked in infra-fixed-costs.ts",
98
+ supersededBy: [],
99
+ partlySupersededBy: [],
100
+ },
101
+ {
102
+ id: "D10",
103
+ title: "Bright Data contract",
104
+ answer: "Contested, pinned in CI (descriptor reserves 0.75 cr/record vs resolver bills 0.625)",
105
+ status: "open",
106
+ table: "open",
107
+ ratifiedOn: null,
108
+ lands: "Human staff verification",
109
+ supersededBy: [],
110
+ partlySupersededBy: [],
111
+ },
112
+ {
113
+ id: "D11",
114
+ title: "Firecrawl page price",
115
+ answer: "(a) at 2 cr/page deliberate wedge, uniform 2 Oxygen credits per Firecrawl provider credit.",
116
+ status: "ratified",
117
+ table: "ratified",
118
+ ratifiedOn: "2026-06-10",
119
+ lands: "Shipped [v1.162.22]",
120
+ supersededBy: [],
121
+ partlySupersededBy: [],
122
+ },
123
+ {
124
+ id: "D12",
125
+ title: "parallel / DataForSEO / openwebninja / apify / builtwith rates",
126
+ answer: "Pull-posture enforced (unpriced ⇒ not routed; Guard 2 fails growth); rates owed before routing",
127
+ status: "open",
128
+ table: "open",
129
+ ratifiedOn: null,
130
+ lands: "Human; runbooks disclose the posture",
131
+ supersededBy: [],
132
+ partlySupersededBy: [],
133
+ },
134
+ {
135
+ id: "D13",
136
+ title: "Exa identity + premium ops",
137
+ answer: "(a) managed at dev prices; BYOK only as override; premium ops repriced toward adoption (already at 0.25–1.75 cr since v1.160.7; hints aligned).",
138
+ status: "ratified",
139
+ table: "ratified",
140
+ ratifiedOn: "2026-06-10",
141
+ lands: "Shipped [v1.162.22] (hints), runbook claim fixed [v1.163.3]",
142
+ supersededBy: [],
143
+ partlySupersededBy: [],
144
+ },
145
+ {
146
+ id: "D14",
147
+ title: "One-shot enrich tools",
148
+ answer: "Open; spec recommends ship at T4",
149
+ status: "open",
150
+ table: "open",
151
+ ratifiedOn: null,
152
+ lands: "T4",
153
+ supersededBy: [],
154
+ partlySupersededBy: [],
155
+ },
156
+ {
157
+ id: "D15",
158
+ title: "Company structured primary",
159
+ answer: "Hold Blitz-first until D9 COGS lands, then re-derive from the resolver (intra-tier order is resolver-derived by design). Registry seeds Blitz-first meanwhile. Superseded by D26 (2026-07-25): D9 is closed and Blitz-first is now ratified outright, with Apollo as the named managed alternative.",
160
+ status: "ratified",
161
+ table: "ratified",
162
+ ratifiedOn: "2026-06-10",
163
+ lands: "T1a seed; re-derivation automatic once D9 numbers land",
164
+ supersededBy: ["D26"],
165
+ partlySupersededBy: [],
166
+ },
167
+ {
168
+ id: "D16",
169
+ title: "ai_ark promotion",
170
+ answer: "Ratified 2026-07-25 (moved from Open): ai_ark promoted into the default tier-2 slot of both the email and phone chains on the audit's buyable-tier numbers ($0.01/provider credit → 50 cr email / 250 cr phone). Ratified by founder directive without the paid bake-off the original entry required — stated plainly rather than left Open while the promotion ships. Forcing function is now post-launch per-provider net-new yield monitoring; drop any source under ~5% net-new.",
171
+ status: "ratified",
172
+ table: "ratified",
173
+ ratifiedOn: "2026-07-25",
174
+ lands: "enrichment-capabilities.ts defaults",
175
+ supersededBy: [],
176
+ partlySupersededBy: [],
177
+ },
178
+ {
179
+ id: "D17",
180
+ title: "Hiring chain head",
181
+ answer: "TheirStack-first; Signalbase premium-only where it is the sole structured source — pending D18 price verification. Superseded by D28 (2026-07-25): BlitzAPI takes the hiring head on flat-fee unmetered polling; TheirStack becomes the named alternative.",
182
+ status: "ratified",
183
+ table: "ratified",
184
+ ratifiedOn: "2026-06-10",
185
+ lands: "T1a seed",
186
+ supersededBy: ["D28"],
187
+ partlySupersededBy: [],
188
+ },
189
+ {
190
+ id: "D18",
191
+ title: "Signalbase pricing",
192
+ answer: "(a) posture: treat as premium verified-events feed until the contract rate is staff-verified; the 5–12× dry-run understatement fixed regardless. Placeholder amounts (125/50) still need verification — see Open. Superseded by D29 (2026-07-25) as a routing posture (SignalBase leaves every default chain); the price-verification obligation survives and gates any future re-routing.",
193
+ status: "ratified",
194
+ table: "ratified",
195
+ ratifiedOn: "2026-06-10",
196
+ lands: "Posture shipped [v1.162.22]/[v1.163.1]",
197
+ supersededBy: [],
198
+ partlySupersededBy: ["D29"],
199
+ },
200
+ {
201
+ id: "D19",
202
+ title: "Phone-lane ordering + verifier consolidation",
203
+ answer: "(a) cost-order phone/company lanes; demote prospeo 100 cr/25 cr premium slots behind cheaper verified lanes until org-level provider stats prove the premium; MillionVerifier (0.1 cr) ratified as the single default verifier with a hard cap of 2–3 pattern validations per row. Partially superseded (2026-07-25): the single default verifier clause is replaced by D30's two-step flow; the cost-order rule and PATTERN_VALIDATION_ROW_CAP stand, subject to D25 where the two disagree.",
204
+ status: "ratified",
205
+ table: "ratified",
206
+ ratifiedOn: "2026-06-10",
207
+ lands: "T1a seeds (8 documented order exceptions from [v1.162.22] re-derive under this rule)",
208
+ supersededBy: [],
209
+ partlySupersededBy: ["D30"],
210
+ },
211
+ {
212
+ id: "D20",
213
+ title: "Standing budget scope",
214
+ answer: "Open; spec recommends org-level first",
215
+ status: "open",
216
+ table: "open",
217
+ ratifiedOn: null,
218
+ lands: "T3",
219
+ supersededBy: [],
220
+ partlySupersededBy: [],
221
+ },
222
+ {
223
+ id: "D21",
224
+ title: "Job-change cadence default",
225
+ answer: "Open; spec recommends monthly-with-weekly-option; verify LeadMagic no_change billing",
226
+ status: "open",
227
+ table: "open",
228
+ ratifiedOn: null,
229
+ lands: "During T1–T2",
230
+ supersededBy: [],
231
+ partlySupersededBy: [],
232
+ },
233
+ {
234
+ id: "D22",
235
+ title: "Apify posture",
236
+ answer: "Open; spec recommends managed-vetted-registry + BYOK for arbitrary actors",
237
+ status: "open",
238
+ table: "open",
239
+ ratifiedOn: null,
240
+ lands: "During T1–T2",
241
+ supersededBy: [],
242
+ partlySupersededBy: [],
243
+ },
244
+ {
245
+ id: "D23",
246
+ title: "AI defaults",
247
+ answer: "Open; spec recommends the leans; icebreaker tier price is a pure pricing call",
248
+ status: "open",
249
+ table: "open",
250
+ ratifiedOn: null,
251
+ lands: "During T1–T2",
252
+ supersededBy: [],
253
+ partlySupersededBy: [],
254
+ },
255
+ {
256
+ id: "D24",
257
+ title: "\"Unlimited trio\" customer pricing",
258
+ answer: "(a) near-zero-rate RocketReach/blitz/prospeo email ops and keep them front-loaded (\"hit-rate on them costs you near-nothing\"). Revenue-posture call, taken deliberately. Superseded by D25 (2026-07-25): the audit found only BlitzAPI is flat-fee; RocketReach and Prospeo are metered and lose their front-loaded slot.",
259
+ status: "ratified",
260
+ table: "ratified",
261
+ ratifiedOn: "2026-06-10",
262
+ lands: "T1a pricing rows + seed order",
263
+ supersededBy: ["D25"],
264
+ partlySupersededBy: [],
265
+ },
266
+ {
267
+ id: "D25",
268
+ title: "Default provider tier doctrine",
269
+ answer: "(a) every default chain orders tier 0 free (no_bill preflights/counts) → tier 1 unlimited/flat-fee ($0 marginal) → tier 2 cheap managed per-credit → tier 3 external waterfall aggregator on the residual only. Supersedes D24(a): UNLIMITED_EMAIL_ENRICHMENT_PROVIDERS narrows to [\"blitzapi\"]. Where this disagrees with D19(a)'s cost-order rule, D25 wins.",
270
+ status: "ratified",
271
+ table: "ratified",
272
+ ratifiedOn: "2026-07-25",
273
+ lands: "enrichment-capabilities.ts defaults + registry tiering",
274
+ supersededBy: [],
275
+ partlySupersededBy: [],
276
+ },
277
+ {
278
+ id: "D26",
279
+ title: "Search primary + paid alternative",
280
+ answer: "BlitzAPI is the default primary for people and company/account search; Apollo is the paid alternative and runs MANAGED (our APOLLO_API_KEY, customer billed Oxygen credits), switchable via --provider. Explicitly overrides the audit's BYOK-Apollo recommendation — founder call, accepting that Apollo API access is Custom-plan-only with unpublished rate limits. Supersedes D15's \"hold Blitz-first until D9 COGS lands\" (D9 is now closed). D5's BLITZ_BEFORE_BYOK_APOLLO exception stands for BYOK-connected orgs.",
281
+ status: "ratified",
282
+ table: "ratified",
283
+ ratifiedOn: "2026-07-25",
284
+ lands: "L1 planners + registry seeds",
285
+ supersededBy: [],
286
+ partlySupersededBy: [],
287
+ },
288
+ {
289
+ id: "D27",
290
+ title: "Hard prune of default chains",
291
+ answer: "Email blitzapi → icypeas → ai_ark → leadmagic → bettercontact; phone blitzapi → ai_ark → leadmagic → bettercontact. Search defaults blitzapi → apollo. Every other provider stays wired and selectable (--provider-order, --provider); only the DEFAULTS shrink — pruning is never deletion. Named carve-outs: tier-0 free counts (Forager totals, Dropleads/ContactOut/Icypeas people_count, TheirStack catalog_keywords), ContactOut for reachable_persona (only provider enforcing --require-phone), ContactOut on the phone-from-email profile (only cheap email-keyed lane), and MoltSets as a $0 BYOK head where it can run.",
292
+ status: "ratified",
293
+ table: "ratified",
294
+ ratifiedOn: "2026-07-25",
295
+ lands: "DEFAULT_* arrays + profiles + planners",
296
+ supersededBy: [],
297
+ partlySupersededBy: [],
298
+ },
299
+ {
300
+ id: "D28",
301
+ title: "Signals defaults",
302
+ answer: "BlitzAPI first for hiring + job search (flat-fee, unmetered polling; requires wiring /v2/search/jobs + /v2/search/company-jobs). PredictLeads primary for funding, news, and tech. TheirStack is the named alternative to PredictLeads for hiring and tech. Supersedes D17 (TheirStack-first hiring head).",
303
+ status: "ratified",
304
+ table: "ratified",
305
+ ratifiedOn: "2026-07-25",
306
+ lands: "routing-registry/signals.ts",
307
+ supersededBy: [],
308
+ partlySupersededBy: [],
309
+ },
310
+ {
311
+ id: "D29",
312
+ title: "SignalBase + Crustdata cut from signal defaults",
313
+ answer: "Both leave every default signal chain; both stay wired and selectable. Supersedes D18(a) as a routing posture — the price-verification obligation survives as a precondition for ever re-routing SignalBase. Accepted coverage loss, recorded deliberately: market-wide acquisitions lose acquirer identity, deal amount, and true close date; market-wide job change has no substitute and becomes a typed no_default_provider_chain refusal rather than a thinner chain that would emit rows its own person_linkedin_url upsert key cannot key; funding events lose SignalBase's verification flag. Per-row job-change tracking survives on the watch-list chain.",
314
+ status: "ratified",
315
+ table: "ratified",
316
+ ratifiedOn: "2026-07-25",
317
+ lands: "routing-registry/signals.ts",
318
+ supersededBy: [],
319
+ partlySupersededBy: [],
320
+ },
321
+ {
322
+ id: "D30",
323
+ title: "Email verification is a fixed two-step flow",
324
+ answer: "MillionVerifier on every found email; any catch-all/accept-all escalates to bounceban.verify_single_waterfall. Both verdicts recorded on the cell and in provenance. Supersedes only D19(a)'s \"single default verifier\" clause; D19(a)'s cost-order rule and the pattern-validation row cap stand. Verification attaches to all three email profiles (including linkedin_url, which had none); the pattern pre-step stays off linkedin_url because it would spend verifier credits ahead of the $0-marginal Blitz lane. Extended (2026-07-29, v1.507.0): the same two-step flow now also serves the STANDALONE verify_email intent — verifying an address you already have, via oxygen verify email / oxygen_verify_email / POST /api/cli/verify/run — through one shared leg runner, so a found-then-verified address and a directly-verified address cannot get different verdicts or prices. zerobounce.validate_email is REMOVED from the chain (cut at 22x MillionVerifier) and recorded in the chain's excluded_tools; catch_all is modelled as a separate catch_all_escalation target rather than an ordinary chain step, because advance_policy conflates \"provider missed\" with \"provider answered catch-all\". Both providers repriced to exactly 5x COGS (MillionVerifier 2.245, BounceBan 17).",
325
+ status: "ratified",
326
+ table: "ratified",
327
+ ratifiedOn: "2026-07-25",
328
+ lands: "verifyEmailCandidate + runEmailVerificationWaterfall + profile config",
329
+ supersededBy: [],
330
+ partlySupersededBy: [],
331
+ },
332
+ {
333
+ id: "D31",
334
+ title: "Charge-on-success is not per-lane spend",
335
+ answer: "find_email/find_phone bill on hit and stop on first success, so a miss costs nothing. The premium-lane gate must not pre-skip a bill-on-hit lane on its nominal per-call price, and the credit estimate must not sum every lane in the chain — it estimates the expected billed cost of a converting row. Real spend stays bounded by charge-on-success plus the run's credit ceiling (which must also count verifier legs).",
336
+ status: "ratified",
337
+ table: "ratified",
338
+ ratifiedOn: null,
339
+ lands: "Premium gate + table-action-credit-estimates.ts + provider-cascade.ts",
340
+ supersededBy: [],
341
+ partlySupersededBy: [],
342
+ },
343
+ {
344
+ id: "D32",
345
+ title: "find_personal_email GA (shipped 2026-09-16 without a ledger id)",
346
+ answer: "Ratify retroactively as a default intent with its shipped chain (contactout → leadmagic → forager), personal mailboxes graded but never catch-all-escalated.",
347
+ status: "proposed",
348
+ table: "proposed",
349
+ ratifiedOn: null,
350
+ lands: null,
351
+ supersededBy: ["D43"],
352
+ partlySupersededBy: [],
353
+ },
354
+ {
355
+ id: "D33",
356
+ title: "Catalogue doctrine",
357
+ answer: "Five statuses (default, selectable, no_default, coming_soon, rejected); region bands per default-chain step marked claimed until measured; labels are data types and providers are metadata (visible in --json, previews, provenance); vendor cost structure is never projected; pruning is never deletion — rejected rows stay in the taxonomy with this id.",
358
+ status: "proposed",
359
+ table: "proposed",
360
+ ratifiedOn: null,
361
+ lands: null,
362
+ supersededBy: [],
363
+ partlySupersededBy: [],
364
+ },
365
+ {
366
+ id: "D34a",
367
+ title: "Revenue",
368
+ answer: "\"Revenue (estimate)\" ships on the managed estimate sources in this order: Apollo organization_enrich (annual_revenue) → PDL company_enrich (inferred_revenue range) → Prospeo enrich_company (revenue_range, customer key only). Label says estimate; \"reported revenue\" stays no_default.",
369
+ status: "ratified",
370
+ table: "proposed",
371
+ ratifiedOn: "2026-09-19",
372
+ lands: "lanes ship in the follow-up engineering slice (OXP task)",
373
+ supersededBy: [],
374
+ partlySupersededBy: [],
375
+ },
376
+ {
377
+ id: "D34b",
378
+ title: "Website traffic",
379
+ answer: "coming_soon; only a keyword-derived SEO estimate (Adyntel) is wired — buy decision for a visits-grade source.",
380
+ status: "proposed",
381
+ table: "proposed",
382
+ ratifiedOn: null,
383
+ lands: null,
384
+ supersededBy: [],
385
+ partlySupersededBy: [],
386
+ },
387
+ {
388
+ id: "D34c",
389
+ title: "Headcount growth",
390
+ answer: "coming_soon; Apollo, PDL, SignalBase and Crustdata document it — founder picks the default.",
391
+ status: "proposed",
392
+ table: "proposed",
393
+ ratifiedOn: null,
394
+ lands: null,
395
+ supersededBy: [],
396
+ partlySupersededBy: [],
397
+ },
398
+ {
399
+ id: "D34d",
400
+ title: "EU/DACH mobile vendor",
401
+ answer: "Open buy decision (Forager wired, Cognism not integrated); the catalogue reports non-US phone bands as unknown (no vendor statement) until then.",
402
+ status: "proposed",
403
+ table: "proposed",
404
+ ratifiedOn: null,
405
+ lands: null,
406
+ supersededBy: [],
407
+ partlySupersededBy: [],
408
+ },
409
+ {
410
+ id: "D34e",
411
+ title: "Work vs mobile phone",
412
+ answer: "Merged: one Phone column with mobile + work/direct-dial outputs.",
413
+ status: "ratified",
414
+ table: "proposed",
415
+ ratifiedOn: "2026-09-19",
416
+ lands: null,
417
+ supersededBy: [],
418
+ partlySupersededBy: [],
419
+ },
420
+ {
421
+ id: "D35",
422
+ title: "Company chain head (funding + shared firmographics)",
423
+ answer: "Apollo organization_enrich (managed per D26, 125 cr/hit, schema-declared; funding, revenue, headcount, growth, industry, technologies in one call) becomes the managed tier-1 head for funding, revenue and headcount growth; PredictLeads company_financing_events is the lane for dated round events with source URLs; LeadMagic company_funding stays as fallback; Prospeo stays selectable on a customer key; Crustdata leaves the default company lanes (D29 scope extended to enrichment). Basis: docs-based response-detail comparison (docs/gtm-program/evidence/2026-09-provider-opinionation/rankings-draft.md).",
424
+ status: "ratified",
425
+ table: "proposed",
426
+ ratifiedOn: "2026-09-19",
427
+ lands: "registry/runtime lane change ships in the follow-up engineering slice",
428
+ supersededBy: [],
429
+ partlySupersededBy: [],
430
+ },
431
+ {
432
+ id: "D36",
433
+ title: "enrich_person_profile head",
434
+ answer: "scraper.linkedin_profile as the single managed lane (the shipped person_enrich preset), seeded 2026-09-19.",
435
+ status: "proposed",
436
+ table: "proposed",
437
+ ratifiedOn: null,
438
+ lands: null,
439
+ supersededBy: ["D47"],
440
+ partlySupersededBy: [],
441
+ },
442
+ {
443
+ id: "D37",
444
+ title: "Golden expected.input_shape",
445
+ answer: "Allow per-shape golden cases for enrich_company field chains (schema addition to GoldenCase).",
446
+ status: "proposed",
447
+ table: "proposed",
448
+ ratifiedOn: null,
449
+ lands: null,
450
+ supersededBy: [],
451
+ partlySupersededBy: [],
452
+ },
453
+ {
454
+ id: "D38",
455
+ title: "Work-email default order after measurement",
456
+ answer: "Keep the D27 order (Blitz → Icypeas → AI Ark → LeadMagic → BetterContact); publish the measured chain-position rates (Blitz 50.5% n=27,103; AI Ark 23.6% n=1,650; LeadMagic email_finder 25.8% n=120; profile_to_email 3.6% n=959) through the catalogue; Icypeas (0% before the v1.930.0 extractor fix) and BetterContact (0/615, spend-cap refusals) are re-measured in two weeks before any reorder.",
457
+ status: "ratified",
458
+ table: "proposed",
459
+ ratifiedOn: "2026-09-19",
460
+ lands: null,
461
+ supersededBy: [],
462
+ partlySupersededBy: [],
463
+ },
464
+ {
465
+ id: "D39",
466
+ title: "Enrich.so",
467
+ answer: "Integrate as a BYOK-only provider (email finder, email validation, reverse email lookup, phone finder) — customer key, no managed spend, no resale-terms exposure; the managed work-email tier-2 slot is not changed.",
468
+ status: "ratified",
469
+ table: "proposed",
470
+ ratifiedOn: "2026-09-19",
471
+ lands: "integration slice filed",
472
+ supersededBy: [],
473
+ partlySupersededBy: [],
474
+ },
475
+ {
476
+ id: "D40",
477
+ title: "Chain order for single-output, high-scale rows",
478
+ answer: "LinkedIn URL, work email, personal email, phone and email verification order cheapest to most expensive: every surviving step sits in tier 1 so the price-derived resolver order is the whole order; no order_exceptions. Quality-sensitive rows (D41) keep tier curation. One exception since 2026-09-29 (D60): the LinkedIn URL chain keeps the managed lookup ahead of Icypeas until the repricing date.",
479
+ status: "ratified",
480
+ table: "proposed",
481
+ ratifiedOn: "2026-09-19",
482
+ lands: null,
483
+ supersededBy: [],
484
+ partlySupersededBy: [],
485
+ },
486
+ {
487
+ id: "D41",
488
+ title: "Quality rows show the output difference per lane",
489
+ answer: "Person profile, company identity/headcount/industry/profile, funding, tech stack and revenue project each lane's documented output fields (default_chain.lanes[].output_fields) so the agent or user sees what a pricier lane returns before choosing it.",
490
+ status: "ratified",
491
+ table: "proposed",
492
+ ratifiedOn: "2026-09-19",
493
+ lands: null,
494
+ supersededBy: [],
495
+ partlySupersededBy: [],
496
+ },
497
+ {
498
+ id: "D42",
499
+ title: "Vendor docs are fetched live at implementation time",
500
+ answer: "Every descriptor input, output, price or coverage claim is re-read from the vendor's official API docs when the code changes and the descriptor records docs_checked: <date>; the 2026-09-19 evidence cards and the wiki are a worklist, never a source. Worked example: Blitz has no name-to-LinkedIn endpoint (every documented endpoint + changelog to 2026-09-17 checked).",
501
+ status: "ratified",
502
+ table: "proposed",
503
+ ratifiedOn: "2026-09-19",
504
+ lands: null,
505
+ supersededBy: [],
506
+ partlySupersededBy: [],
507
+ },
508
+ {
509
+ id: "D43",
510
+ title: "Personal email chain",
511
+ answer: "leadmagic.personal_email_finder is the only managed lane; ContactOut and Forager leave the default (stay selectable by name). Supersedes the D32 chain.",
512
+ status: "ratified",
513
+ table: "proposed",
514
+ ratifiedOn: "2026-09-19",
515
+ lands: null,
516
+ supersededBy: [],
517
+ partlySupersededBy: [],
518
+ },
519
+ {
520
+ id: "D44",
521
+ title: "Phone chain",
522
+ answer: "blitzapi.phone_enrich → leadmagic.mobile_finder → bettercontact.enrich_lead (all three already managed); every other phone lane leaves the default. Email shape starts at LeadMagic; name+company reaches BetterContact only.",
523
+ status: "ratified",
524
+ table: "proposed",
525
+ ratifiedOn: "2026-09-19",
526
+ lands: null,
527
+ supersededBy: [],
528
+ partlySupersededBy: [],
529
+ },
530
+ {
531
+ id: "D45",
532
+ title: "Email verification chain",
533
+ answer: "MillionVerifier on every email, BounceBan on catch-all escalation only (D30 shape); Icypeas, Dropleads and Hunter verifiers leave the chain.",
534
+ status: "ratified",
535
+ table: "proposed",
536
+ ratifiedOn: "2026-09-19",
537
+ lands: null,
538
+ supersededBy: [],
539
+ partlySupersededBy: [],
540
+ },
541
+ {
542
+ id: "D46",
543
+ title: "LinkedIn URL chain",
544
+ answer: "New managed composite scraper.linkedin_profile_lookup (company lookup by domain → first/last-name people search inside it; 2 credits, 1 on a company miss) heads; icypeas.profile_url_search is the fallback. Blitz cannot head it: no Blitz endpoint accepts a person's name (verified live 2026-09-19).",
545
+ status: "ratified",
546
+ table: "proposed",
547
+ ratifiedOn: "2026-09-19",
548
+ lands: null,
549
+ supersededBy: [],
550
+ partlySupersededBy: [],
551
+ },
552
+ {
553
+ id: "D47",
554
+ title: "Person profile chain",
555
+ answer: "blitzapi.person_profile_enrich (vendor endpoint added 2026-09-15; 1 credit) heads ahead of the managed LinkedIn rail scraper.linkedin_profile (1 credit). Supersedes D36.",
556
+ status: "ratified",
557
+ table: "proposed",
558
+ ratifiedOn: "2026-09-19",
559
+ lands: null,
560
+ supersededBy: [],
561
+ partlySupersededBy: [],
562
+ },
563
+ {
564
+ id: "D48",
565
+ title: "Company identity, headcount, industry, profile",
566
+ answer: "Managed LinkedIn rail (scraper.linkedin_company) then Blitz (domain_to_linkedin / linkedin_to_domain / company_profile_enrich) only. Crustdata's free identify pre-step, Prospeo, LeadMagic and AI Ark leave these lanes; identity resolution now starts at the 1-credit scraper call.",
567
+ status: "ratified",
568
+ table: "proposed",
569
+ ratifiedOn: "2026-09-19",
570
+ lands: null,
571
+ supersededBy: [],
572
+ partlySupersededBy: ["D55"],
573
+ },
574
+ {
575
+ id: "D49",
576
+ title: "Funding and tech stack",
577
+ answer: "Funding: apollo.organization_enrich → peopledatalabs.company_enrich → leadmagic.company_funding (applies D35; Prospeo customer-key only, Crustdata out per D29). Tech stack: theirstack.technographics (job-posting-derived, confidence + first/last seen, 3 vendor credits = 30 credits at $0.01) → leadmagic.technographics (website-derived).",
578
+ status: "ratified",
579
+ table: "proposed",
580
+ ratifiedOn: "2026-09-19",
581
+ lands: null,
582
+ supersededBy: [],
583
+ partlySupersededBy: [],
584
+ },
585
+ {
586
+ id: "D50",
587
+ title: "Revenue",
588
+ answer: "One row company_revenue_estimate (\"Revenue (estimate)\"), status default, new company field revenue on apollo.organization_enrich (annual_revenue) → peopledatalabs.company_enrich (inferred_revenue range). company_revenue_exact merged into it (rejected row kept). Amends D34a (Prospeo dropped).",
589
+ status: "ratified",
590
+ table: "proposed",
591
+ ratifiedOn: "2026-09-19",
592
+ lands: null,
593
+ supersededBy: [],
594
+ partlySupersededBy: [],
595
+ },
596
+ {
597
+ id: "D51",
598
+ title: "Long tail parked coming_soon",
599
+ answer: "Competitors, corporate structure, acquisitions, news, web presence, domain status, headcount growth, website traffic, reachable people, audience size, lookalikes and all seven signal rows are coming_soon: no add path, no runtime lane, candidate providers recorded. preset:domain_check leaves the picker.",
600
+ status: "ratified",
601
+ table: "proposed",
602
+ ratifiedOn: "2026-09-19",
603
+ lands: null,
604
+ supersededBy: [],
605
+ partlySupersededBy: [],
606
+ },
607
+ {
608
+ id: "D52",
609
+ title: "Managed web rail is three wallets",
610
+ answer: "serper (keyword/URL recall at 0.5 cr, and the only priced local/maps shape — openwebninja is D12-unpriced), exa (the only semantic engine, category filters, cited answers, and the 0.5 cr cached-index page read) and firecrawl (managed on the SCRAPING rail only: JS/anti-bot scrape, site map, crawl, batch, and PDFs under a page cap) stay managed. parallel and linkup go BYOK-only (managedKeyEnvVar: null); firecrawl.search and crustdata.web_search_live leave every web-search chain. Neither removal is a quality judgement: parallel's managed wallet was never funded (HTTP 402 on all 838 managed calls, 2026-07-30 to 2026-09-17, zero successes ever) and Serper covers its recall niche at the identical 0.5 cr; linkup served 9 calls from ONE org in 120 days and its only exclusive lane (flat-rate PDF) moved to Firecrawl; firecrawl.search costs 8 cr at 5 results for what serper does at 0.5. The rule being enforced is a default cascade may contain only funded, managed-credential lanes, asserted in routing-conformance.test.ts. The Doppler secrets PARALLEL_API_KEY / LINKUP_API_KEY stay declared in ops/env/doppler.manifest.json (required: false) so the env audit does not read a live value as unexpected — removing them is a human step.",
611
+ status: "ratified",
612
+ table: "proposed",
613
+ ratifiedOn: "2026-09-20",
614
+ lands: "shipped in the same slice",
615
+ supersededBy: [],
616
+ partlySupersededBy: [],
617
+ },
618
+ {
619
+ id: "D53",
620
+ title: "AI research column grounds by discover-then-read",
621
+ answer: "The default column runs serper.search (0.5) for URLs, then ONE additive page read of the top result (exa.contents, 0.5) that turns a ~160-char SERP teaser into real page text. Additive is load-bearing: the row is already grounded on its snippets, so a failed read costs a thinner answer and nothing else — which is why the read carries no fallback lane and cannot multiply the reserved ceiling. Typical row drops from 5.0 to 2.5 credits (model 1.5 + grounding 1.0) while the evidence gets richer; the reserve is 6 because the ceiling still covers the exa.search fallback. PDF reading moves from Linkup's flat-rate lane to Firecrawl under a per-column page budget (webSearch.pdfMaxPages, default off, ceiling 8): Firecrawl bills one credit per parsed page (vendor docs, docs_checked 2026-09-20), so a global 8-page ceiling would have held ~6x what an ordinary HTML fetch row spends. AI_COLUMN_WEB_SEARCH_TYPICAL_CREDITS 3.5 → 1 and ..._RESERVED_CREDITS 4 → 4.5, both resolver-derived and pinned.",
622
+ status: "ratified",
623
+ table: "proposed",
624
+ ratifiedOn: "2026-09-20",
625
+ lands: "shipped in the same slice",
626
+ supersededBy: [],
627
+ partlySupersededBy: [],
628
+ },
629
+ {
630
+ id: "D54",
631
+ title: "A dedicated lookalike engine heads the lookalike chain",
632
+ answer: "ocean.company_lookalike_preview becomes the free tier-0 preflight (D25 doctrine: free previews run before spend), a dedicated lookalike search becomes the paid head, and exa.find_similar leaves the chain — a general semantic search is not a lookalike engine. leadmagic.company_lookalike is healthy (3,350/3,368 ok, 37 orgs) and stays; whether Ocean leads or follows is a quality call, and Ocean's free preview makes that comparison free to run. Closes the routing-spec.md §5 Ocean/PredictLeads deferral that the current find_lookalikes exclusion cites — Ocean has been managed, priced and never called (0 managed calls in 120 days) purely because that chain excluded it. Discolike gets the same standard applied to parallel: it earns a chain step or it leaves managed (managed, priced, routed in NO chain, 6 calls / 0 successes).",
633
+ status: "ratified",
634
+ table: "proposed",
635
+ ratifiedOn: "2026-09-20",
636
+ lands: "chain + the built-in Lookalike companies column ship in the follow-up slice",
637
+ supersededBy: [],
638
+ partlySupersededBy: [],
639
+ },
640
+ {
641
+ id: "D55",
642
+ title: "Blitz heads person and company enrichment, the managed LinkedIn rail backs it",
643
+ answer: "Person profile: oxygen.person_profile, a composite tool that runs blitzapi.person_profile_enrich and falls back to scraper.linkedin_profile only when Blitz returns no match. Before this change the person_enrich bundle ran the scraper alone, and nothing executed the D47 chain. Company identity, headcount, industry and profile now run Blitz (linkedin_to_domain / domain_to_linkedin / company_profile_enrich) first and scraper.linkedin_company second, reversing D48's order. A domain or LinkedIn URL the row already holds is written from the input for 0 credits. Blitz legs bill only on a hit (found: true); a miss costs nothing. Funding stage and latest round leave the default company bundle for the Funding details group, because Blitz's company profile carries no funding data. In the web add-column panel, Person enrichment, Company enrichment and Tech stack are configured before they are created: the user picks the input column, the Work-email style replaces checkboxes, and auto-detection only preselects. Personal email leaves the add-column catalog (it is LeadMagic, reachable under Integrations). Website contacts becomes the template website_contacts_v1. Consequence: a default company row costs about 2 credits instead of about 1, which is margin because Blitz is flat-rate. Supersedes D48's order; D47 now executes.",
644
+ status: "ratified",
645
+ table: "proposed",
646
+ ratifiedOn: "2026-09-24",
647
+ lands: null,
648
+ supersededBy: [],
649
+ partlySupersededBy: ["D56"],
650
+ },
651
+ {
652
+ id: "D56",
653
+ title: "Company enrichment is one profile lookup, like person enrichment",
654
+ answer: "The company_enrich bundle runs oxygen.company_profile, a composite tool: blitzapi.company_profile_enrich first (a domain-only row first resolves its LinkedIn URL with blitzapi.domain_to_linkedin, which is never billed), then scraper.linkedin_company only when Blitz has no match. Both lanes land in one merged schema, the managed rail's response.raw.element, kept whole in the JSON column, and free stored columns (domain, LinkedIn URL, name, headcount, industry, description, founded year, HQ country) fill in the same write. About 1 credit per company found, at most 2 reserved; the previous per-field waterfall quoted up to 10 because it priced each field's lanes separately. The opt-in field groups leave the bundle on every surface: --preset-fields on company_enrich refuses and points to find company --fields and the Tech stack bundle, which keeps its own waterfall. The web add-column step asks only for the input columns: no providers list, no field list, no toggles (\"we just handle this in the backend for the user\"). Existing company columns are not converted. Supersedes D55's company half for the bundle; the per-field company waterfall (find company, Tech stack) keeps D55's Blitz-first order.",
655
+ status: "ratified",
656
+ table: "proposed",
657
+ ratifiedOn: "2026-09-24",
658
+ lands: null,
659
+ supersededBy: [],
660
+ partlySupersededBy: [],
661
+ },
662
+ {
663
+ id: "D57",
664
+ title: "Managed roster after the 2026-09-27 live matrix",
665
+ answer: "Crustdata, Findymail, RocketReach, ScaleList, Forager, DiscoLike, SignalBase and Lusha leave the managed rail: BYOK-only (managedKeyEnvVar: null), off every default chain, price rows kept, still selectable with a customer's own key. Each was dead in production as well as dev: Crustdata's managed wallet empty and benched since 2026-09-19 (934 managed calls/577 ok in 120 days); Findymail HTTP 402 since 2026-08-05; RocketReach 788 managed calls with 0 successes in 120 days; ScaleList HTTP 402 since 2026-09-01; Forager's FORAGER_API_KEY is empty in dev and prod Doppler (it never had a working managed key); DiscoLike 0 successes ever (key inactive, 403); SignalBase subscription expired (403 on 2026-09-27, same key in dev and prod, last prod success 2026-09-17); Lusha 0 successes ever (key rejected). BounceBan (the D45 catch-all escalation) and ScrapeLi stay managed and are funded by Philipp; PredictLeads stays managed (its prod key works; only the dev key needs renewal, OXP-1.14.2). Rule applied: D52/D54 — a managed provider earns a default-chain step and a funded wallet, or it leaves managed. The chains lose Forager's free count preflights (company, job and person totals), Crustdata's free autocomplete preflight and the Crustdata, RocketReach, Forager, Findymail and ScaleList email/people fallbacks; each is recorded as a D57 excluded_tools entry, and linkup.fetch leaves the scrape chain under D52's rule. routing-conformance.test.ts now fails when any default-chain step, verifier, escalation, poll or free-count tool belongs to a provider with no managed key, unless the tool itself runs only on a customer key. The Doppler declarations stay (required: false); deleting the secrets is a human step.",
666
+ status: "ratified",
667
+ table: "proposed",
668
+ ratifiedOn: "2026-09-29",
669
+ lands: "shipped in the same slice",
670
+ supersededBy: [],
671
+ partlySupersededBy: [],
672
+ },
673
+ {
674
+ id: "D58",
675
+ title: "Company funding, revenue and hiring are table columns",
676
+ answer: "The three default catalogue rows that had no table add path (only find company --fields) become table presets company_funding, company_revenue and company_hiring, each running its ratified chain with bill-on-hit pricing — funding Apollo → PDL → LeadMagic (D49), revenue Apollo → PDL (D50), hiring Blitz jobs → LeadMagic jobs — on CLI, MCP and the web add-column menu, like company_tech_stack. company_enrich stays the D56 one-lookup bundle. Found by the 2026-09-29 blind baseline, which could not add funding to a table and fell back to an AI research template.",
677
+ status: "ratified",
678
+ table: "proposed",
679
+ ratifiedOn: "2026-09-29",
680
+ lands: null,
681
+ supersededBy: [],
682
+ partlySupersededBy: [],
683
+ },
684
+ {
685
+ id: "D59",
686
+ title: "One email column: work email, with personal email as an option",
687
+ answer: "The opinionated catalogue offers one email column, work email. Personal email stops being its own default row and becomes an optional selection on the work-email column on CLI, MCP and web: it runs the D43 lane (leadmagic.personal_email_finder, needs the person's LinkedIn URL), is quoted only when selected and bills on hit at that lane's existing price; existing personal-email columns keep working. The address a provider returns for the contact is written and charged even when its domain differs from the row's company domain: Blitz keys its email lookup on the LinkedIn URL and answers the person's current employer (Patrick Collison's profile now shows Arc Institute, so a stripe.com row gets an @arcinstitute.org address). This reverts the domain-mismatch refusal PR #2343 added the same day, which wrote nothing while the Blitz hit was still charged; #2343's public-LinkedIn-URL fixes stay. Phone verification (verify_phone, selectable with no surface of its own) becomes coming_soon with no add path. Recommended options declined: restoring the separate personal-email picker row, and picking a row-domain all_emails[] address or charging nothing on a mismatch. Quoted: \"NO email should be just work email with an additional select to add personal email ; phone verification stays coming soon\" and \"just give the user the email it returend for the contact , keep charge\".",
688
+ status: "ratified",
689
+ table: "proposed",
690
+ ratifiedOn: "2026-09-29",
691
+ lands: "lands with the work-email option slice",
692
+ supersededBy: [],
693
+ partlySupersededBy: [],
694
+ },
695
+ {
696
+ id: "D60",
697
+ title: "Opaque LinkedIn member ids are resolved inside the lookup",
698
+ answer: "When the people search inside scraper.linkedin_profile_lookup (D46) returns only an opaque member id (/in/ACwAA…), the lookup resolves it to the public profile URL through Up2Data's profile read, at most one extra call per row: +1 Up2Data credit (about $0.002), billed only when the read runs and returns a profile. Before the repricing effective date an affected row settles 3 credits instead of 2; after it OXYGEN absorbs the read inside the flat 5 credits per URL. A failed or empty resolution keeps today's fall-through to icypeas.profile_url_search at no extra charge. Evidence: in the 2026-09-27 dev live matrix 3 of 3 LinkedIn URLs were member ids; PR #2343 stopped writing member-id URLs. Declined: keeping the Icypeas fall-through (name-only match, about $0.005 a call). Implementation: before the repricing date the lookup quotes and reserves 3, the ceiling that lets it bill the read, and a row settles 1, 2 or 3. That quote is above Icypeas's 2.494, so D40's price-derived order alone would run Icypeas first; the chain keeps the D46 order through one order_exceptions entry citing D46, which goes stale at the repricing date, when both lanes cost a flat 5 per URL found. Asked the same day, Philipp left the order open; the agent kept the existing D46 order (no behaviour change) pending his ratification.",
699
+ status: "ratified",
700
+ table: "proposed",
701
+ ratifiedOn: "2026-09-29",
702
+ lands: "lands with the member-id resolution slice",
703
+ supersededBy: [],
704
+ partlySupersededBy: [],
705
+ },
706
+ {
707
+ id: "D61",
708
+ title: "RocketReach and Lusha get a native own-key connect",
709
+ answer: "D57 made both BYOK-only, but neither could take a customer's key: RocketReach routed to Composio and Lusha had no integration definition, so integrations connect answered byok_connect_unavailable and nobody could run them. Both get a native API-key connect on web, CLI and MCP, validated at connect time against a zero-credit authenticated vendor endpoint where the vendor documents one, and their tools run on the customer's key under the existing BYOK pricing. Both stay off every default chain (D57). Declined: marking them unavailable. Quoted: \"Build own-key connect\".",
710
+ status: "ratified",
711
+ table: "proposed",
712
+ ratifiedOn: "2026-09-29",
713
+ lands: "lands with the own-key connect slice",
714
+ supersededBy: [],
715
+ partlySupersededBy: [],
716
+ },
717
+ ];