diff --git a/README.md b/README.md index ce65cae..f0ba6ab 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Run the same discovery locally with an explicit date: bun run history:news:pull -- --as-of 2026-08-20 --json-out /tmp/stripe-news.json --markdown-out /tmp/stripe-news.md ``` -The manual [leadership appearance backfill](./.github/workflows/appearance-backfill.yml) searches one bounded calendar window at a time from 2009 onward and uploads a review artifact. It does not edit public data or open issues. A reviewer can normalize a completed run into the public, nonindexable [appearance backfill queue](https://stripehistory.com/appearances/backfill); candidates remain separate from the reviewed appearance corpus until full source review. The same window can be inspected locally: +The manual [leadership appearance backfill](./.github/workflows/appearance-backfill.yml) searches one bounded calendar window at a time from 2009 onward and uploads a private review artifact. It does not edit public data or open issues. Reviewers deduplicate the artifact, capture the retained sources, and merge only evidence-backed records into the main [leadership appearances](https://stripehistory.com/appearances) catalog. The same window can be inspected locally: ```sh bun run history:news:pull -- --from 2020-01-01 --as-of 2020-12-31 --monitor exa-stripe-leadership-appearances --json-out /tmp/stripe-appearances-2020.json --markdown-out /tmp/stripe-appearances-2020.md diff --git a/app/appearances/backfill/page.test.tsx b/app/appearances/backfill/page.test.tsx deleted file mode 100644 index ad0cdb0..0000000 --- a/app/appearances/backfill/page.test.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { describe, expect, test } from "bun:test"; -import { renderToStaticMarkup } from "react-dom/server"; - -import AppearanceBackfillPage, { metadata } from "./page"; - -describe("leadership appearance backfill page", () => { - test("keeps unreviewed discovery results public but out of search results", () => { - expect(metadata).toMatchObject({ - alternates: { canonical: "/appearances/backfill" }, - robots: { follow: true, index: false }, - title: "Leadership Appearance Backfill", - }); - }); - - test("renders the complete normalized review queue with provenance", async () => { - const html = renderToStaticMarkup(await AppearanceBackfillPage()); - - expect(html).toContain('

Leadership Appearance Backfill

'); - expect(html).toContain("31 candidates"); - expect(html).toContain("47 raw hits"); - expect(html).toContain("not accepted historical records"); - expect(html.match(/source review needed/gu)).toHaveLength(31); - expect(html).toContain('href="https://www.youtube.com/watch?v=YgYiF86h0yU"'); - expect(html).toContain('href="https://www.youtube.com/watch?v=y_4emS6D4og"'); - expect(html).toContain( - 'href="https://github.com/hraness/stripe-history/actions/runs/32265726670"', - ); - expect(html).not.toContain("OpenAI Co-founder Greg Brockman"); - }); -}); diff --git a/app/appearances/backfill/page.tsx b/app/appearances/backfill/page.tsx deleted file mode 100644 index f2ccac0..0000000 --- a/app/appearances/backfill/page.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import { - loadAppearanceBackfill, - type AppearanceBackfill, -} from "@/lib/appearance-backfill"; -import type { Metadata } from "next"; -import Link from "next/link"; - -import { SiteFooter } from "../../site-footer"; -import { SiteHeader } from "../../site-header"; -import { site, socialMetadata } from "../../site"; - -const title = "Leadership Appearance Backfill"; -const description = - "A public review queue of historical Stripe founder and executive podcast, interview, talk, and testimony candidates discovered through bounded Exa search."; - -export const dynamic = "force-static"; - -export const metadata: Metadata = { - title, - description, - alternates: { canonical: "/appearances/backfill" }, - robots: { follow: true, index: false }, - ...socialMetadata(`${title} | ${site.domain}`, description, "/appearances/backfill"), -}; - -export default async function AppearanceBackfillPage() { - const backfill = await loadAppearanceBackfill(); - const candidatesByYear = new Map< - string, - AppearanceBackfill["candidates"][number][] - >(); - for (const candidate of backfill.candidates) { - const year = candidate.published_at.slice(0, 4); - const candidates = candidatesByYear.get(year) ?? []; - candidates.push(candidate); - candidatesByYear.set(year, candidates); - } - - return ( -
- - -
-
-

{title}

- {backfill.candidates.length} candidates -
-
-

{description}

-

- These links are discovery results, not accepted historical records. - Each one still needs canonical deduplication, complete source capture, - role verification, and transcript-grounded editorial review before it - can join the reviewed appearances. -

-

- The successful backfill run searched - {" "}{backfill.review_window.from.slice(0, 4)} through{" "} - {backfill.review_window.through.slice(0, 4)} and returned{" "} - {backfill.counts.raw_hits} raw hits. Review collapsed{" "} - {backfill.counts.duplicate_variants} duplicate source variants, matched{" "} - {backfill.counts.already_reviewed_variants} variants to existing records, - and excluded {backfill.counts.excluded_hits} unrelated hits. -

-
-
- {[...candidatesByYear.entries()].map(([year, candidates]) => ( -
-
-

{year}

- {candidates.length} -
-
    - {candidates.map((candidate) => ( -
  1. -
    -

    - - source review needed -

    -

    {candidate.title}

    -

    - {candidate.participants.join(" · ")} -

    -

    - {new URL(candidate.url).hostname} -

    -
    -
  2. - ))} -
-
- ))} -
-
- -
- ); -} diff --git a/app/appearances/page.test.tsx b/app/appearances/page.test.tsx index e8cf2e7..906e968 100644 --- a/app/appearances/page.test.tsx +++ b/app/appearances/page.test.tsx @@ -25,7 +25,6 @@ describe("Stripe leadership appearances", () => { expect(html).toContain('"@type":"CollectionPage"'); expect(html).toContain('"@type":"PodcastEpisode"'); expect(html).toContain('"@type":"VideoObject"'); - expect(html).toContain('href="/appearances/backfill"'); - expect(html).toContain("Review 31 historical appearance candidates"); + expect(html).not.toContain('href="/appearances/backfill"'); }); }); diff --git a/app/appearances/page.tsx b/app/appearances/page.tsx index aa1229e..26f04ff 100644 --- a/app/appearances/page.tsx +++ b/app/appearances/page.tsx @@ -1,5 +1,4 @@ import { loadHistory } from "@/lib/content"; -import { loadAppearanceBackfill } from "@/lib/appearance-backfill"; import { JsonLdScript } from "@hraness/web-discovery/json-ld"; import type { Metadata } from "next"; import Link from "next/link"; @@ -30,10 +29,7 @@ function durationLabel(seconds: number | undefined): string | null { } export default async function AppearancesPage() { - const [history, backfill] = await Promise.all([ - loadHistory(), - loadAppearanceBackfill(), - ]); + const history = await loadHistory(); const sourceById = new Map(history.sources.map((source) => [source.id, source])); return ( @@ -60,12 +56,6 @@ export default async function AppearancesPage() { {history.appearances.length} reviewed

{description}

-

- - Review {backfill.candidates.length} historical appearance candidates - {" "} - from the public 2009–2026 leadership backfill. -

    {history.appearances.map((appearance) => { const sources = appearance.source_ids.flatMap((sourceId) => { diff --git a/app/data/page.test.tsx b/app/data/page.test.tsx index c53ac48..0017868 100644 --- a/app/data/page.test.tsx +++ b/app/data/page.test.tsx @@ -37,9 +37,8 @@ describe("Stripe company history dataset", () => { expect(html).toContain('href="/research/sources.yml"'); expect(html).toContain('href="/research/valuations.yml"'); expect(html).toContain('href="/research/appearances.yml"'); - expect(html).toContain('href="/appearances/backfill"'); - expect(html).toContain('href="/research/appearance-backfill.yml"'); - expect(html).toContain("31 candidates"); + expect(html).not.toContain('href="/appearances/backfill"'); + expect(html).not.toContain('href="/research/appearance-backfill.yml"'); expect(html).toContain('href="/research/collections.yml"'); expect(html).toContain('href="/research/runs.yml"'); expect(html).toContain(`${history.sources.length} canonical sources`); diff --git a/app/data/page.tsx b/app/data/page.tsx index 26005c0..3bacf7f 100644 --- a/app/data/page.tsx +++ b/app/data/page.tsx @@ -1,5 +1,4 @@ import { loadHistory } from "@/lib/content"; -import { loadAppearanceBackfill } from "@/lib/appearance-backfill"; import { JsonLdScript } from "@hraness/web-discovery/json-ld"; import type { Metadata } from "next"; import Link from "next/link"; @@ -24,10 +23,7 @@ export const metadata: Metadata = { }; export default async function DataPage() { - const [history, appearanceBackfill] = await Promise.all([ - loadHistory(), - loadAppearanceBackfill(), - ]); + const history = await loadHistory(); const countByCategory = new Map( history.categories.map(({ id }) => [ id, @@ -170,11 +166,6 @@ export default async function DataPage() { YAML ·{" "} {history.appearances.length} appearances -
  1. - appearance backfill queue ·{" "} - YAML ·{" "} - {appearanceBackfill.candidates.length} candidates -
  2. research collections YAML
  3. diff --git a/app/globals.css b/app/globals.css index 46f725f..266ec77 100644 --- a/app/globals.css +++ b/app/globals.css @@ -291,59 +291,6 @@ text-align: end; } -.stripe-history-backfill-intro { - color: var(--plain-muted); - display: grid; - gap: 0.7rem; - margin-bottom: 2rem; - max-width: 42rem; -} - -.stripe-history-backfill-intro p, -.stripe-history-backfill-list h3, -.stripe-history-backfill-list p { - margin: 0; -} - -.stripe-history-backfill-years { - display: grid; - gap: 2rem; -} - -.stripe-history-backfill-years > section > .stripe-history-section-heading { - border-top: 2px solid var(--plain-foreground); - margin-bottom: 0; - padding-top: 0.5rem; -} - -.stripe-history-backfill-list { - list-style: none; - margin: 0; - padding: 0; -} - -.stripe-history-backfill-list > li { - border-top: 1px solid var(--plain-line); -} - -.stripe-history-backfill-list article { - padding-block: 0.85rem 1rem; -} - -.stripe-history-backfill-list h3 { - font-family: var(--font-heading); - font-size: var(--text-label); - line-height: 1.35; - margin-top: 0.25rem; -} - -.stripe-history-backfill-list .stripe-history-appearance-participants, -.stripe-history-backfill-source { - color: var(--plain-muted); - font-size: var(--text-caption); - margin-top: 0.3rem; -} - .stripe-history-state button { background: var(--plain-foreground); border: 1px solid var(--plain-foreground); diff --git a/lib/appearance-backfill.test.ts b/lib/appearance-backfill.test.ts deleted file mode 100644 index 558b71e..0000000 --- a/lib/appearance-backfill.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { describe, expect, test } from "bun:test"; -import { readFile } from "node:fs/promises"; -import { join } from "node:path"; - -import { parse } from "yaml"; - -import { - AppearanceBackfillFileSchema, - loadAppearanceBackfill, -} from "./appearance-backfill"; - -describe("leadership appearance backfill", () => { - test("accounts for every raw discovery hit without promoting candidates", async () => { - const backfill = await loadAppearanceBackfill(); - - expect(backfill.counts).toEqual({ - already_reviewed_variants: 9, - duplicate_variants: 5, - excluded_hits: 2, - raw_hits: 47, - }); - expect(backfill.candidates).toHaveLength(31); - expect(backfill.candidates.every(({ review_status: status }) => - status === "source-review-needed")).toBe(true); - expect(backfill.candidates[0]?.published_at).toBe("2026-05-21"); - expect(backfill.candidates.at(-1)?.published_at).toBe("2013-08-13"); - }); - - test("rejects incomplete hit accounting", async () => { - const value = parse(await readFile(join( - process.cwd(), - "public", - "research", - "appearance-backfill.yml", - ), "utf8")) as Record; - const counts = value.counts as Record; - counts.raw_hits = 48; - - expect(() => AppearanceBackfillFileSchema.parse(value)).toThrow( - "Backfill accounting covers 47 of 48 raw hits", - ); - }); -}); diff --git a/lib/appearance-backfill.ts b/lib/appearance-backfill.ts deleted file mode 100644 index 55e3ccd..0000000 --- a/lib/appearance-backfill.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { readFile } from "node:fs/promises"; -import { dirname, join } from "node:path"; -import { fileURLToPath } from "node:url"; - -import { parse } from "yaml"; -import { z } from "zod"; - -import { CompactTextSchema, HttpsUrlSchema, PartialDateSchema } from "./history-schema"; - -export const STRIPE_HISTORY_APPEARANCE_BACKFILL_SCHEMA_VERSION = - "stripe-history/appearance-backfill/v1" as const; - -const ExactDateSchema = PartialDateSchema.refine( - (value) => value.length === 10, - "Backfill dates must include year, month, and day", -); - -const AppearanceBackfillCandidateSchema = z.strictObject({ - participants: z.array(CompactTextSchema.max(100)).min(1).max(2), - published_at: ExactDateSchema, - review_status: z.literal("source-review-needed"), - title: CompactTextSchema.max(240), - url: HttpsUrlSchema, -}); - -export const AppearanceBackfillFileSchema = z.strictObject({ - candidates: z.array(AppearanceBackfillCandidateSchema).min(1).max(100), - completed_at: z.iso.datetime({ offset: true }), - counts: z.strictObject({ - already_reviewed_variants: z.number().int().nonnegative(), - duplicate_variants: z.number().int().nonnegative(), - excluded_hits: z.number().int().nonnegative(), - raw_hits: z.number().int().positive(), - }), - monitor_id: z.literal("exa-stripe-leadership-appearances"), - review_window: z.strictObject({ - from: ExactDateSchema, - through: ExactDateSchema, - }), - schema: z.literal(STRIPE_HISTORY_APPEARANCE_BACKFILL_SCHEMA_VERSION), - workflow_run: HttpsUrlSchema, -}).superRefine((file, context) => { - if (file.review_window.from > file.review_window.through) { - context.addIssue({ - code: "custom", - message: "Backfill review window must be ordered", - path: ["review_window"], - }); - } - const accountedHits = file.candidates.length - + file.counts.already_reviewed_variants - + file.counts.duplicate_variants - + file.counts.excluded_hits; - if (accountedHits !== file.counts.raw_hits) { - context.addIssue({ - code: "custom", - message: `Backfill accounting covers ${accountedHits} of ${file.counts.raw_hits} raw hits`, - path: ["counts"], - }); - } - const urls = new Set(); - for (const [index, candidate] of file.candidates.entries()) { - if ( - candidate.published_at < file.review_window.from - || candidate.published_at > file.review_window.through - ) { - context.addIssue({ - code: "custom", - message: "Candidate date falls outside the reviewed window", - path: ["candidates", index, "published_at"], - }); - } - if (urls.has(candidate.url)) { - context.addIssue({ - code: "custom", - message: "Candidate URLs must be unique", - path: ["candidates", index, "url"], - }); - } - urls.add(candidate.url); - const previous = file.candidates[index - 1]; - if ( - previous !== undefined - && ( - previous.published_at < candidate.published_at - || ( - previous.published_at === candidate.published_at - && previous.title.localeCompare(candidate.title) > 0 - ) - ) - ) { - context.addIssue({ - code: "custom", - message: "Candidates must be reverse chronological, then title ordered", - path: ["candidates", index], - }); - } - } -}); - -export type AppearanceBackfill = z.infer; - -const PROJECT_DIRECTORY = dirname(dirname(fileURLToPath(import.meta.url))); -const DEFAULT_PATH = join( - PROJECT_DIRECTORY, - "public", - "research", - "appearance-backfill.yml", -); - -export async function loadAppearanceBackfill( - path = DEFAULT_PATH, -): Promise { - return AppearanceBackfillFileSchema.parse(parse(await readFile(path, "utf8")) as unknown); -} diff --git a/lib/research-schema.ts b/lib/research-schema.ts index 65aa6e3..48e2bad 100644 --- a/lib/research-schema.ts +++ b/lib/research-schema.ts @@ -800,6 +800,33 @@ const ResearchCandidateDecisionSchema = z.discriminatedUnion("disposition", [ }), ]); +const researchBackfillDecisionBase = { + candidate_id: z.string().regex(/^candidate-[a-f0-9]{20}$/u), + candidate_url: HttpsUrlSchema, + native_id: CompactTextSchema.max(160).optional(), + reason: CompactTextSchema, +} as const; + +const ResearchBackfillDecisionSchema = z.discriminatedUnion("disposition", [ + z.strictObject({ + ...researchBackfillDecisionBase, + disposition: z.literal("accepted"), + evidence: ResearchCaptureEvidenceSchema, + source_id: SourceIdSchema, + }), + z.strictObject({ + ...researchBackfillDecisionBase, + disposition: z.literal("duplicate"), + duplicate_of_source_id: SourceIdSchema, + evidence: ResearchCaptureEvidenceSchema.optional(), + }), + z.strictObject({ + ...researchBackfillDecisionBase, + disposition: z.literal("rejected"), + evidence: ResearchCaptureEvidenceSchema.optional(), + }), +]); + const ResearchBaselineImportRunSchema = z.strictObject({ accepted_input_sha256: Sha256Schema, candidate_history: z.literal("not-reconstructible-pre-ledger"), @@ -871,16 +898,80 @@ const ResearchDiscoveryRunSchema = z.strictObject({ } }); +const ResearchBackfillRunSchema = z.strictObject({ + accepted_input_sha256: Sha256Schema, + accepted_source_ids: z.array(SourceIdSchema).min(1).max(300), + artifact_url: HttpsUrlSchema, + collection: z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/u), + completed_on: ExactDateSchema, + decisions: z.array(ResearchBackfillDecisionSchema).min(1).max(2_000), + kind: z.literal("backfill"), + plan_sha256: Sha256Schema, + recorded_on: ExactDateSchema, + review_window: z.strictObject({ + from: ExactDateSchema, + through: ExactDateSchema, + }), + status: z.literal("complete"), +}).superRefine((run, context) => { + if (run.recorded_on > run.completed_on) { + context.addIssue({ + code: "custom", + message: "Backfill run must be recorded by its completion date", + path: ["recorded_on"], + }); + } + if (run.review_window.from > run.review_window.through) { + context.addIssue({ + code: "custom", + message: "Backfill review window must be chronological", + path: ["review_window"], + }); + } + if (run.review_window.through > run.completed_on) { + context.addIssue({ + code: "custom", + message: "Backfill review window must not follow its completion date", + path: ["review_window", "through"], + }); + } + uniqueValues(run.accepted_source_ids, context, ["accepted_source_ids"]); + uniqueValues(run.decisions.map(({ candidate_id: id }) => id), context, ["decisions"]); + const sortedInputs = run.accepted_source_ids.toSorted(); + if (run.accepted_source_ids.some((id, index) => id !== sortedInputs[index])) { + context.addIssue({ + code: "custom", + message: "Backfill accepted inputs must be ordered by source ID", + path: ["accepted_source_ids"], + }); + } + const sortedDecisions = run.decisions.map(({ candidate_id: id }) => id).toSorted(); + if (run.decisions.some(({ candidate_id: id }, index) => id !== sortedDecisions[index])) { + context.addIssue({ + code: "custom", + message: "Backfill candidate decisions must be ordered by ID", + path: ["decisions"], + }); + } +}); + export const ResearchRunLedgerSchema = z.strictObject({ runs: z.array(z.discriminatedUnion("kind", [ ResearchBaselineImportRunSchema, + ResearchBackfillRunSchema, ResearchDiscoveryRunSchema, ])).min(1).max(500), schema: z.literal(STRIPE_HISTORY_RESEARCH_RUNS_SCHEMA_VERSION), }).superRefine((ledger, context) => { - const keys = ledger.runs.map((run) => run.kind === "baseline-import" - ? `${run.collection}:${run.target_through}:${run.plan_sha256}` - : `${run.collection}:${run.plan.watermark.targetThrough}:${run.plan.planSha256}`); + const keys = ledger.runs.map((run) => { + if (run.kind === "baseline-import") { + return `${run.collection}:${run.target_through}:0-baseline:${run.plan_sha256}`; + } + if (run.kind === "discovery") { + return `${run.collection}:${run.plan.watermark.targetThrough}:1-discovery:${run.plan.planSha256}`; + } + return `${run.collection}:${run.completed_on}:2-backfill:${run.plan_sha256}`; + }); uniqueValues(keys, context, ["runs"]); const sortedKeys = keys.toSorted(); if (keys.some((key, index) => key !== sortedKeys[index])) { diff --git a/public/research/appearance-backfill.yml b/public/research/appearance-backfill.yml deleted file mode 100644 index 34eee75..0000000 --- a/public/research/appearance-backfill.yml +++ /dev/null @@ -1,168 +0,0 @@ -schema: stripe-history/appearance-backfill/v1 -completed_at: 2026-08-19T14:45:15Z -workflow_run: https://github.com/hraness/stripe-history/actions/runs/32265726670 -monitor_id: exa-stripe-leadership-appearances -review_window: - from: 2009-01-01 - through: 2026-08-19 -counts: - raw_hits: 47 - already_reviewed_variants: 9 - duplicate_variants: 5 - excluded_hits: 2 -candidates: - - published_at: 2026-05-21 - title: "The Best Time in History to Start a Company | Patrick Collison & Amjad Masad" - url: https://www.youtube.com/watch?v=YgYiF86h0yU - participants: [Patrick Collison] - review_status: source-review-needed - - published_at: 2026-05-19 - title: "Nat Friedman and Daniel Gross in conversation with John and Patrick Collison" - url: https://www.youtube.com/watch?v=l9wzs_QIyp0 - participants: [John Collison, Patrick Collison] - review_status: source-review-needed - - published_at: 2026-05-16 - title: "Stripe's John Collison on How Agentic Commerce Will Reshape the Internet | Odd Lots" - url: https://www.youtube.com/watch?v=QhGqLqCzFac - participants: [John Collison] - review_status: source-review-needed - - published_at: 2026-04-28 - title: "John and Patrick Collison on Stripe's Growth, Agent Commerce, and the Future of Software" - url: https://a16z.com/podcast/john-and-patrick-collison-on-stripes-growth-agent-commerce-and-the-future-of-software - participants: [John Collison, Patrick Collison] - review_status: source-review-needed - - published_at: 2026-02-20 - title: "Patrick Collison on Stripe's Early Choices, Smalltalk, and What Comes After Coding" - url: https://a16z.com/podcast/patrick-collison-on-stripes-early-choices-smalltalk-and-what-comes-after-coding - participants: [Patrick Collison] - review_status: source-review-needed - - published_at: 2025-11-13 - title: "Inside Stripe: Stablecoins, AI, and (not) Going Public | Will Gaybrick" - url: https://www.youtube.com/watch?v=AM1_NADNSgI - participants: [Will Gaybrick] - review_status: source-review-needed - - published_at: 2025-07-17 - title: "Patrick Collison on programming languages, AI, and Stripe" - url: https://podcasts.apple.com/id/podcast/patrick-collison-on-programming-languages-ai-and/id1819406817?i=1000717598878 - participants: [Patrick Collison] - review_status: source-review-needed - - published_at: 2025-06-27 - title: "Hard Fork Live, with Patrick Collison, Kathryn Zealand, Sam Altman & Brad Lightcap" - url: https://www.youtube.com/watch?v=jdNwzYMtPN8 - participants: [Patrick Collison] - review_status: source-review-needed - - published_at: 2025-02-28 - title: "Bonus Episode: Stripe CEO John Collison" - url: https://podcasts.apple.com/us/podcast/bonus-episode-stripe-ceo-john-collison-2-28-25/id1480890290?i=1000696834852 - participants: [John Collison] - review_status: source-review-needed - - published_at: 2024-09-20 - title: "Will Gaybrick on capital allocation, org design, AI, and global growth" - url: https://podcasts.apple.com/us/podcast/ep-118-will-gaybrick-president-of-product-and/id1606770839?i=1000670156025 - participants: [Will Gaybrick] - review_status: source-review-needed - - published_at: 2023-10-06 - title: "Arthur Mensch and John Collison | Stripe AI Day Paris" - url: https://www.youtube.com/watch?v=yXN5xSXJ1Is - participants: [John Collison] - review_status: source-review-needed - - published_at: 2023-08-08 - title: "Scaling People with Claire Hughes Johnson" - url: https://www.newcomer.co/p/scaling-people-with-claire-hughes - participants: [Claire Hughes Johnson] - review_status: source-review-needed - - published_at: 2023-05-24 - title: "Claire Hughes Johnson on scaling operations and culture at Stripe" - url: https://podcasts.apple.com/us/podcast/claire-hughes-johnson-stripe-scaling-operations-and/id80867514?i=1000614322138 - participants: [Claire Hughes Johnson] - review_status: source-review-needed - - published_at: 2023-05-15 - title: "Stripe CEO Patrick Collison on innovating e-commerce and accelerating biomedical research" - url: https://podcasts.apple.com/us/podcast/stripe-ceo-patrick-collison-on-innovating-e-commerce/id1610419911?i=1000613083611 - participants: [Patrick Collison] - review_status: source-review-needed - - published_at: 2023-05-04 - title: "Building a culture of excellence | David Singleton" - url: https://www.youtube.com/watch?v=F0_IKKY3HCk - participants: [David Singleton] - review_status: source-review-needed - - published_at: 2023-03-06 - title: "Former Stripe COO Claire Hughes Johnson on scaling people" - url: https://podcasts.apple.com/us/podcast/128-former-coo-corporate-officer-at-stripe-claire-hughes/id1510985491?i=1000602919224 - participants: [Claire Hughes Johnson] - review_status: source-review-needed - - published_at: 2023-03-05 - title: "Lessons from scaling Stripe | Claire Hughes Johnson" - url: https://podcasts.apple.com/us/podcast/lessons-from-scaling-stripe-claire-hughes-johnson-ex/id1627920305?i=1000602823726 - participants: [Claire Hughes Johnson] - review_status: source-review-needed - - published_at: 2023-02-22 - title: "Extreme Product Design with Stripe CTO David Singleton" - url: https://podcasts.apple.com/us/podcast/saastr-636-extreme-product-design-building-things-people/id1089973241?i=1000601129097 - participants: [David Singleton] - review_status: source-review-needed - - published_at: 2023-02-14 - title: "Stripe's Patrick Collison: Micro Pessimism, Macro Optimism" - url: https://podcasts.apple.com/mu/podcast/stripes-patrick-collison-micro-pessimism-macro-optimism/id1089013200?i=1000599602701 - participants: [Patrick Collison] - review_status: source-review-needed - - published_at: 2022-07-13 - title: "Stripe's David Singleton on technology innovation, customers, and the CTO role" - url: https://podcasts.apple.com/us/podcast/stripes-david-singleton-on-technology-innovation-putting/id962121995?i=1000569774533 - participants: [David Singleton] - review_status: source-review-needed - - published_at: 2022-06-20 - title: "The future of the internet economy with John Collison" - url: https://podcasts.apple.com/ca/podcast/the-future-of-the-internet-economy-with-stripe/id1462649946?i=1000567104995 - participants: [John Collison] - review_status: source-review-needed - - published_at: 2022-06-10 - title: "John Collison in conversation with Stanley Druckenmiller | Sohn 2022" - url: https://www.youtube.com/watch?v=-7sWLIybWnQ - participants: [John Collison] - review_status: source-review-needed - - published_at: 2021-10-11 - title: "Stripe CRO Mike Clayville: Building Tornado Companies" - url: https://podcasts.apple.com/us/podcast/cro-stripe-mike-clayville-building-tornado-companies/id1510985491?i=1000538185612 - participants: [Mike Clayville] - review_status: source-review-needed - - published_at: 2021-05-10 - title: "Claire Hughes Johnson, COO of Stripe | The #ANGELS Podcast" - url: https://podcasts.apple.com/us/podcast/claire-hughes-johnson-coo-of-stripe/id1550832941?i=1000521087003 - participants: [Claire Hughes Johnson] - review_status: source-review-needed - - published_at: 2019-11-25 - title: "Tech and Progress with Patrick Collison and Tyler Cowen" - url: https://podcasts.apple.com/us/podcast/tech-and-progress-with-patrick-collison-and-tyler-cowen/id1460731098?i=1000457824338 - participants: [Patrick Collison] - review_status: source-review-needed - - published_at: 2018-05-02 - title: "Patrick Collison: Earning Your Stripes | The Knowledge Project" - url: https://podcasts.apple.com/us/podcast/32-patrick-collison-earning-your-stripes/id990149481?i=1000410487693 - participants: [Patrick Collison] - review_status: source-review-needed - - published_at: 2018-03-02 - title: "Stripe's Patrick Collison: I'm petrified of getting too big" - url: https://podcasts.apple.com/us/podcast/stripes-patrick-collison-im-petrified-of-getting-too/id1233991021?i=1000404469689 - participants: [Patrick Collison] - review_status: source-review-needed - - published_at: 2017-04-12 - title: "Patrick Collison has a few questions for Tyler (live)" - url: https://podcasts.apple.com/jp/podcast/patrick-collison-has-a-few-questions-for-tyler-live/id983795625?i=1000384289632 - participants: [Patrick Collison] - review_status: source-review-needed - - published_at: 2016-12-06 - title: "Stripe CEO Patrick Collison on management, rationalism, and the Enlightenment" - url: https://podcasts.apple.com/no/podcast/stripe-ceo-patrick-collison-on-management-rationalism/id1081584611?i=1000378637097 - participants: [Patrick Collison] - review_status: source-review-needed - - published_at: 2014-10-28 - title: "Hiring and Culture, Part 2 | Patrick and John Collison" - url: https://www.youtube.com/watch?v=H8Dl8rZ6qwE - participants: [Patrick Collison, John Collison] - review_status: source-review-needed - - published_at: 2013-08-13 - title: "unSEXY Conf 2013: Patrick Collison, Stripe" - url: https://www.youtube.com/watch?v=y_4emS6D4og - participants: [Patrick Collison] - review_status: source-review-needed diff --git a/public/research/appearances.yml b/public/research/appearances.yml index aca7368..2201ea2 100644 --- a/public/research/appearances.yml +++ b/public/research/appearances.yml @@ -34,6 +34,178 @@ appearances: detail: Checkout, delegation, fraud, payments, stablecoins, and model-token infrastructure must change when software agents initiate purchases and machines buy services from machines. source_ids: [source-523815a4d8be2b7368b9] review_status: reviewed + - id: appearance-2026-05-patrick-collison-replit + occurred_at: 2026-05-21 + date_precision: day + published_at: 2026-05-21 + title: The Best Time in History to Start a Company + venue: Replit + participants: + - name: Patrick Collison + role: interviewee + stripe_role: Co-founder and CEO + media: [video, transcript] + duration_seconds: 2111 + duration_precision: exact + transcript: + availability: automatic + language: en + source_id: source-119db9dd4efb34c354fa + topics: [ai, entrepreneurship, company-creation, software, internet-economy] + historical_periods: [stripe-2009-2026] + significance: Patrick uses current Stripe formation data to explain the acceleration in new company creation, then connects AI-assisted software development to smaller teams, faster revenue, and new entrepreneurial opportunities. + source_ids: [source-119db9dd4efb34c354fa] + review_status: reviewed + - id: appearance-2026-05-patrick-john-collison-friedman-gross + occurred_at: 2026-05-19 + date_precision: day + published_at: 2026-05-19 + title: Nat Friedman and Daniel Gross in conversation with John and Patrick Collison + venue: Stripe + participants: + - name: John Collison + role: speaker + stripe_role: Co-founder and President + - name: Patrick Collison + role: speaker + stripe_role: Co-founder and CEO + media: [video, transcript] + duration_seconds: 3358 + duration_precision: exact + transcript: + availability: automatic + language: en + source_id: source-18b5f3a0d6c6c83811f7 + topics: [ai, company-building, software, product-strategy, entrepreneurship] + historical_periods: [stripe-2009-2026] + significance: John and Patrick join Nat Friedman and Daniel Gross for a first-person discussion of how AI changes software creation, company formation, organizational design, and Stripe's product environment. + source_ids: [source-18b5f3a0d6c6c83811f7] + review_status: reviewed + - id: appearance-2026-05-john-collison-odd-lots + occurred_at: 2026-05-16 + date_precision: day + published_at: 2026-05-16 + title: How agentic commerce will reshape the internet + venue: Bloomberg Odd Lots + participants: + - name: John Collison + role: interviewee + stripe_role: Co-founder and President + media: [podcast, video, transcript] + duration_seconds: 2975 + duration_precision: exact + transcript: + availability: automatic + language: en + source_id: source-98566fabeed1b3474821 + topics: [agentic-commerce, payments, stablecoins, internet-economy, product-strategy] + historical_periods: [stripe-2009-2026] + significance: John explains how autonomous buyers alter discovery, checkout, delegated authority, fraud, and settlement, providing Stripe's current view of the infrastructure required for agentic commerce. + source_ids: [source-98566fabeed1b3474821] + review_status: reviewed + - id: appearance-2026-04-patrick-john-collison-a16z + occurred_at: 2026-04-28 + date_precision: day + published_at: 2026-04-28 + title: Stripe's growth, agent commerce, and the future of software + venue: a16z + series: The a16z Show + participants: + - name: John Collison + role: interviewee + stripe_role: Co-founder and President + - name: Patrick Collison + role: interviewee + stripe_role: Co-founder and CEO + media: [podcast] + transcript: + availability: none + topics: [growth, agentic-commerce, stablecoins, software, employee-liquidity] + historical_periods: [stripe-2009-2026] + significance: John and Patrick discuss Stripe's reported growth, employee tender, agent commerce, stablecoins, and the shift from mass-produced software toward bespoke systems generated when needed. + source_ids: [source-c8cf9fc9a738a7673ab5] + review_status: reviewed + - id: appearance-2026-02-patrick-collison-a16z + occurred_at: 2026-02-20 + date_precision: day + published_at: 2026-02-20 + title: Stripe's early choices, Smalltalk, and what comes after coding + venue: a16z + series: The a16z Show + participants: + - name: Patrick Collison + role: interviewee + stripe_role: Co-founder and CEO + media: [podcast] + transcript: + availability: none + topics: [programming-languages, early-company, software, ai, company-building] + historical_periods: [pre-stripe, stripe-2009-2026] + significance: Patrick revisits Stripe's early technical choices and Smalltalk roots while considering how AI changes programming, software architecture, and the work of building enduring technology companies. + source_ids: [source-3e4c405e9bd479571d83] + review_status: reviewed + - id: appearance-2025-11-will-gaybrick-the-peel + occurred_at: 2025-11-13 + date_precision: day + published_at: 2025-11-13 + title: "Inside Stripe: Stablecoins, AI, and (not) going public" + venue: The Peel + participants: + - name: Will Gaybrick + role: interviewee + stripe_role: President of Product and Business + media: [podcast, video, transcript] + duration_seconds: 5769 + duration_precision: exact + transcript: + availability: automatic + language: en + source_id: source-ef5f15ce3644987cd0d2 + topics: [stablecoins, ai, product-strategy, organization-design, public-markets] + historical_periods: [stripe-2015-2025] + significance: Will gives a long first-person account of Stripe's product expansion, stablecoin strategy, AI work, organization, capital allocation, and decision to remain private. + source_ids: [source-ef5f15ce3644987cd0d2] + review_status: reviewed + - id: appearance-2025-07-patrick-collison-cursor + occurred_at: 2025-07-17 + date_precision: day + published_at: 2025-07-17 + title: Programming languages, AI, and Stripe's biggest engineering decisions + venue: Cursor + participants: + - name: Patrick Collison + role: interviewee + stripe_role: Co-founder and CEO + media: [podcast] + transcript: + availability: none + topics: [programming-languages, ai, engineering, software-architecture, company-building] + historical_periods: [pre-stripe, stripe-2009-2025] + significance: Patrick discusses the programming-language ideas behind his early work, Stripe's major architectural decisions and rewrites, his use of AI, and the relationship between software and human organizations. + source_ids: [source-6c270caf7a0f7aea8142] + review_status: reviewed + - id: appearance-2025-06-patrick-collison-hard-fork + occurred_at: 2025-06-27 + date_precision: day + published_at: 2025-06-27 + title: Patrick Collison at Hard Fork Live + venue: Hard Fork Live + participants: + - name: Patrick Collison + role: interviewee + stripe_role: Co-founder and CEO + media: [podcast, video, transcript] + duration_seconds: 6598 + duration_precision: exact + transcript: + availability: automatic + language: en + source_id: source-af973a63a7068c0ccff9 + topics: [agentic-commerce, biotechnology, long-term-thinking, payments, progress] + historical_periods: [stripe-2009-2025] + significance: Patrick connects Stripe's approach to long-duration company building with agentic commerce and his work in biotechnology, including the Arc Institute and a broader case for institutional ambition. + source_ids: [source-af973a63a7068c0ccff9] + review_status: reviewed - id: appearance-2025-05-patrick-john-collison-sessions-ama occurred_at: 2025-05 date_precision: month @@ -74,6 +246,42 @@ appearances: significance: Patrick's written congressional testimony gives a first-person account of Stripe's founding, scale, payment-method coverage, Bridge acquisition, and policy case for stablecoins. source_ids: [source-18cef128fcb5c9083568, source-bbf6b0fb0b8942bc569f] review_status: reviewed + - id: appearance-2025-02-john-collison-squawk-pod + occurred_at: 2025-02-28 + date_precision: day + published_at: 2025-02-28 + title: Stripe CEO John Collison + venue: Squawk Pod + participants: + - name: John Collison + role: interviewee + stripe_role: Co-founder and President + media: [podcast] + transcript: + availability: none + topics: [growth, valuation, private-markets, payments, company-building] + historical_periods: [stripe-2009-2025] + significance: John discusses Stripe's scale, private valuation, long operating horizon, and the company's position in payments with Andrew Ross Sorkin in a rare current interview. + source_ids: [source-d5562f80014ab418430b] + review_status: reviewed + - id: appearance-2024-09-will-gaybrick-logan-bartlett + occurred_at: 2024-09-20 + date_precision: day + published_at: 2024-09-20 + title: Capital allocation, organization design, AI, and global growth + venue: The Logan Bartlett Show + participants: + - name: Will Gaybrick + role: interviewee + stripe_role: President of Product and Business + media: [podcast] + transcript: + availability: none + topics: [capital-allocation, organization-design, ai, global-growth, product-strategy] + historical_periods: [stripe-2015-2024] + significance: Will traces his path from investor to Stripe executive and explains how the company approaches capital allocation, product organization, AI, and international growth. + source_ids: [source-39cb086a5372e02b17bc] + review_status: reviewed - id: appearance-2024-04-patrick-john-collison-sessions-ama occurred_at: 2024-04-24 date_precision: day @@ -181,6 +389,250 @@ appearances: significance: Patrick and John discuss Stripe's strategy, culture, attention to detail, capital allocation, and the internet economy together in a long-form primary interview. source_ids: [source-1278271efc6181fee94f] review_status: reviewed + - id: appearance-2023-10-john-collison-stripe-ai-day + occurred_at: 2023-10-06 + date_precision: day + published_at: 2023-10-06 + title: Arthur Mensch and John Collison at Stripe AI Day Paris + venue: Stripe AI Day Paris + participants: + - name: John Collison + role: speaker + stripe_role: Co-founder and President + media: [video, transcript] + duration_seconds: 2330 + duration_precision: exact + transcript: + availability: automatic + language: en + source_id: source-daf244691067ecfd0a84 + topics: [ai, machine-learning, software, entrepreneurship, product-strategy] + historical_periods: [stripe-2009-2023] + significance: John discusses the AI company landscape with Mistral co-founder Arthur Mensch at a Stripe event, connecting model development, startup formation, and the infrastructure needs of fast-growing AI businesses. + source_ids: [source-daf244691067ecfd0a84] + review_status: reviewed + - id: appearance-2023-08-claire-hughes-johnson-newcomer + occurred_at: 2023-08-08 + date_precision: day + published_at: 2023-08-08 + title: Scaling People with Claire Hughes Johnson + venue: Newcomer + participants: + - name: Claire Hughes Johnson + role: interviewee + stripe_role: Corporate Officer and Adviser + media: [article] + transcript: + availability: none + topics: [operations, organization-design, hiring, management, company-building] + historical_periods: [stripe-2014-2021] + significance: Claire explains the operating systems, hiring practices, management expectations, and organizational mechanisms she used while helping Stripe scale from an early company into a global organization. + source_ids: [source-a83d235b649d61ebd04a] + review_status: reviewed + - id: appearance-2023-05-claire-hughes-johnson-stanford + occurred_at: 2023-05-24 + date_precision: day + published_at: 2023-05-24 + title: Scaling Operations and People + venue: Stanford eCorner + series: Entrepreneurial Thought Leaders + participants: + - name: Claire Hughes Johnson + role: interviewee + stripe_role: Corporate Officer and Adviser + media: [podcast] + transcript: + availability: none + topics: [operations, people, management, culture, company-building] + historical_periods: [stripe-2014-2021] + significance: Claire turns her experience scaling Stripe's operations and people systems into practical guidance on management, culture, organizational design, and the transition from startup improvisation to durable operating practice. + source_ids: [source-57a7fe4d5d7acd711d7b] + review_status: reviewed + - id: appearance-2023-05-patrick-collison-minor-consult + occurred_at: 2023-05-15 + date_precision: day + published_at: 2023-05-15 + title: Innovating e-commerce and accelerating biomedical research + venue: The Minor Consult + participants: + - name: Patrick Collison + role: interviewee + stripe_role: Co-founder and CEO + media: [podcast] + transcript: + availability: none + topics: [founding, ecommerce, biomedical-research, arc-institute, progress] + historical_periods: [pre-stripe, stripe-2009-2023] + significance: Patrick recounts his path into entrepreneurship and Stripe while explaining why he helped create Arc Institute and how stronger institutions could accelerate biomedical research. + source_ids: [source-d09d6a2687fa0f13d64c] + review_status: reviewed + - id: appearance-2023-05-david-singleton-lenny + occurred_at: 2023-05-04 + date_precision: day + published_at: 2023-05-04 + title: Building a culture of excellence + venue: Lenny's Podcast + participants: + - name: David Singleton + role: interviewee + stripe_role: Chief Technology Officer + media: [podcast, video, transcript] + duration_seconds: 5399 + duration_precision: exact + transcript: + availability: automatic + language: en + source_id: source-644e7df552ad28028b3a + topics: [engineering, culture, product-development, quality, management] + historical_periods: [stripe-2021-2023] + significance: David gives a detailed account of Stripe's engineering culture, product quality bar, user feedback loops, leadership expectations, and mechanisms for keeping technical teams focused on customer outcomes. + source_ids: [source-644e7df552ad28028b3a] + review_status: reviewed + - id: appearance-2023-03-claire-hughes-johnson-grit + occurred_at: 2023-03-06 + date_precision: day + published_at: 2023-03-06 + title: Scaling People + venue: Grit + participants: + - name: Claire Hughes Johnson + role: interviewee + stripe_role: Former Chief Operating Officer + media: [podcast] + transcript: + availability: none + topics: [management, hiring, operations, leadership, company-building] + historical_periods: [stripe-2014-2021] + significance: Claire explains the frameworks she developed while scaling Stripe, including how leaders establish operating principles, diagnose organizational problems, and build management systems without losing speed. + source_ids: [source-9dee161b28ef4003aeb3] + review_status: reviewed + - id: appearance-2023-03-claire-hughes-johnson-lenny + occurred_at: 2023-03-05 + date_precision: day + published_at: 2023-03-05 + title: Lessons from scaling Stripe + venue: Lenny's Podcast + participants: + - name: Claire Hughes Johnson + role: interviewee + stripe_role: Former Chief Operating Officer + media: [podcast] + transcript: + availability: none + topics: [operations, management, hiring, culture, performance] + historical_periods: [stripe-2014-2021] + significance: Claire describes the management infrastructure behind Stripe's growth, including goal setting, hiring, performance systems, feedback, and the operating cadences needed as a company moves through successive stages of scale. + source_ids: [source-34e9256f6b05d1c012cb] + review_status: reviewed + - id: appearance-2023-02-david-singleton-saastr + occurred_at: 2023-02-22 + date_precision: day + published_at: 2023-02-22 + title: Extreme Product Design + venue: SaaStr + participants: + - name: David Singleton + role: interviewee + stripe_role: Chief Technology Officer + media: [podcast] + transcript: + availability: none + topics: [product-design, user-research, engineering, quality, product-development] + historical_periods: [stripe-2021-2023] + significance: David explains how Stripe turns close user observation into product and engineering decisions, arguing for unusually direct feedback loops and a quality bar grounded in what customers actually do. + source_ids: [source-ff6b00bcb15ca05ca7f4] + review_status: reviewed + - id: appearance-2023-02-patrick-collison-greymatter + occurred_at: 2023-02-14 + date_precision: day + published_at: 2023-02-14 + title: Micro Pessimism, Macro Optimism + venue: Greymatter + participants: + - name: Patrick Collison + role: interviewee + stripe_role: Co-founder and CEO + media: [podcast] + transcript: + availability: none + topics: [company-building, economic-outlook, strategy, startups, long-term-thinking] + historical_periods: [stripe-2009-2023] + significance: Patrick discusses how Stripe and its users navigate a difficult economic cycle while maintaining a long-term view of internet business formation, technological progress, and the opportunity for new companies. + source_ids: [source-4cf5bde77c3a4330d227] + review_status: reviewed + - id: appearance-2022-07-david-singleton-seedcamp + occurred_at: 2022-07-13 + date_precision: day + published_at: 2022-07-13 + title: Technology innovation, customers, and the CTO role + venue: This Much I Know + series: The Seedcamp Podcast + participants: + - name: David Singleton + role: interviewee + stripe_role: Chief Technology Officer + media: [podcast] + transcript: + availability: none + topics: [engineering, customers, innovation, leadership, product-development] + historical_periods: [stripe-2021-2022] + significance: David describes the CTO role at Stripe, the company's customer-centered approach to technical innovation, and the leadership practices required to connect engineering investment with useful products. + source_ids: [source-15f3382443f13e368075] + review_status: reviewed + - id: appearance-2022-06-john-collison-david-mcwilliams + occurred_at: 2022-06-20 + date_precision: day + published_at: 2022-06-20 + title: The future of the internet economy + venue: The David McWilliams Podcast + participants: + - name: John Collison + role: interviewee + stripe_role: Co-founder and President + media: [podcast] + transcript: + availability: none + topics: [internet-economy, innovation, entrepreneurship, payments, global-growth] + historical_periods: [stripe-2009-2022] + significance: John connects Stripe's mission and product development to broader changes in internet business formation, innovation, globalization, and the economic conditions facing entrepreneurs. + source_ids: [source-6321e360d21ebafc1539] + review_status: reviewed + - id: appearance-2021-10-mike-clayville-grit + occurred_at: 2021-10-11 + date_precision: day + published_at: 2021-10-11 + title: Building Tornado Companies + venue: Grit + participants: + - name: Mike Clayville + role: interviewee + stripe_role: Chief Revenue Officer + media: [podcast] + transcript: + availability: none + topics: [sales, growth, leadership, organization-design, enterprise] + historical_periods: [stripe-2020-2021] + significance: Mike explains how Stripe was building its revenue organization for rapid enterprise growth, including leadership, go-to-market design, hiring, and the operating demands of a fast-scaling company. + source_ids: [source-28538b94e9867ad8ddea] + review_status: reviewed + - id: appearance-2021-05-claire-hughes-johnson-angels + occurred_at: 2021-05-10 + date_precision: day + published_at: 2021-05-10 + title: Claire Hughes Johnson, COO of Stripe + venue: "The #ANGELS Podcast" + participants: + - name: Claire Hughes Johnson + role: interviewee + stripe_role: Chief Operating Officer + media: [podcast] + transcript: + availability: none + topics: [operations, leadership, hiring, culture, company-building] + historical_periods: [stripe-2014-2021] + significance: Claire reflects on joining Stripe early, building its operating function, developing leaders and culture, and scaling the company across products, geographies, and organizational stages. + source_ids: [source-472eb2b12343ba3fa8e5] + review_status: reviewed - id: appearance-2020-06-john-collison-colossus occurred_at: 2020-06-16 date_precision: day @@ -220,6 +672,61 @@ appearances: significance: Patrick gives an unusually detailed account of his early programming, Auctomatic, Stripe's origin, reading practice, recruiting, and interest in technological progress. source_ids: [source-7365200928b2c76a48b7] review_status: reviewed + - id: appearance-2018-05-patrick-collison-knowledge-project + occurred_at: 2018-05-02 + date_precision: day + published_at: 2018-05-02 + title: Earning Your Stripes + venue: The Knowledge Project + series: Episode 32 + participants: + - name: Patrick Collison + role: interviewee + stripe_role: Co-founder and CEO + media: [podcast] + transcript: + availability: none + topics: [founding, company-building, decision-making, learning, payments] + historical_periods: [pre-stripe, stripe-2009-2018] + significance: Patrick gives a broad account of Stripe's origin and growth while discussing decision-making, learning, organizational quality, and the habits he uses to build a long-duration company. + source_ids: [source-5abe9c3805865ebd263c] + review_status: reviewed + - id: appearance-2018-03-patrick-collison-times-tech + occurred_at: 2018-03-02 + date_precision: day + published_at: 2018-03-02 + title: I'm petrified of getting too confident + venue: The Times Tech Podcast + participants: + - name: Patrick Collison + role: interviewee + stripe_role: Co-founder and CEO + media: [podcast] + transcript: + availability: none + topics: [company-building, payments, growth, competition, culture] + historical_periods: [stripe-2009-2018] + significance: Patrick discusses Stripe's position in financial infrastructure, its growth and valuation, and why maintaining uncertainty and intellectual humility mattered as the company became larger. + source_ids: [source-1c1ccd634b5f7d73f612] + review_status: reviewed + - id: appearance-2016-12-patrick-collison-gray-area + occurred_at: 2016-12-06 + date_precision: day + published_at: 2016-12-06 + title: Management, rationalism, and the Enlightenment + venue: The Gray Area + participants: + - name: Patrick Collison + role: interviewee + stripe_role: Co-founder and CEO + media: [podcast] + transcript: + availability: none + topics: [management, rationalism, company-building, culture, payments] + historical_periods: [stripe-2009-2016] + significance: Patrick explains Stripe's business and management philosophy while connecting the company's operating culture to rationalism, intellectual history, and a belief in technological and institutional progress. + source_ids: [source-4091456d98a90957fe07] + review_status: reviewed - id: appearance-2016-05-patrick-john-collison-cbs occurred_at: 2016-05-01 date_precision: day @@ -263,6 +770,54 @@ appearances: significance: John explains how celebrated startups repeatedly pass through uncertainty and failure, placing Stripe's early path in the context of startup evolution and durable company vision. source_ids: [source-a5d1d621862fa7f1cac0] review_status: reviewed + - id: appearance-2014-10-patrick-john-collison-yc + occurred_at: 2014-10-28 + date_precision: day + published_at: 2014-10-28 + title: Hiring and Culture, Part 2 + venue: Y Combinator + series: Hiring and Culture + participants: + - name: Patrick Collison + role: speaker + stripe_role: Co-founder and CEO + - name: John Collison + role: speaker + stripe_role: Co-founder and President + media: [video, transcript] + duration_seconds: 3037 + duration_precision: exact + transcript: + availability: automatic + language: en + source_id: source-c7d664518b9bba629716 + topics: [hiring, culture, management, early-company, company-building] + historical_periods: [stripe-2009-2014] + significance: Patrick and John explain Stripe's early hiring bar, interview process, cultural choices, and management lessons while the company was moving beyond its founding team. + source_ids: [source-c7d664518b9bba629716] + review_status: reviewed + - id: appearance-2013-08-patrick-collison-unsexy + occurred_at: 2013-08-13 + date_precision: day + published_at: 2013-08-13 + title: Patrick Collison at unSEXY Conf 2013 + venue: unSEXY Conference + participants: + - name: Patrick Collison + role: speaker + stripe_role: Co-founder and CEO + media: [video, transcript] + duration_seconds: 676 + duration_precision: exact + transcript: + availability: automatic + language: en + source_id: source-650f1c1afaf31f558df3 + topics: [founding, payments, early-company, product, entrepreneurship] + historical_periods: [stripe-2009-2013] + significance: Patrick gives a compact contemporaneous account of the payments problem Stripe set out to solve, the early product, and the company's progress while it was still a young startup. + source_ids: [source-650f1c1afaf31f558df3] + review_status: reviewed - id: appearance-2012-04-patrick-collison-startup-grind occurred_at: '2012' date_precision: year diff --git a/public/research/collections.yml b/public/research/collections.yml index a308933..60a7231 100644 --- a/public/research/collections.yml +++ b/public/research/collections.yml @@ -27,19 +27,47 @@ collections: - research/appearances.yml input_source_ids: - source-001e51b689b259d0b4e3 + - source-119db9dd4efb34c354fa - source-1278271efc6181fee94f + - source-15f3382443f13e368075 + - source-18b5f3a0d6c6c83811f7 - source-18cef128fcb5c9083568 + - source-1c1ccd634b5f7d73f612 - source-26410b426525f71187bb + - source-28538b94e9867ad8ddea + - source-34e9256f6b05d1c012cb + - source-39cb086a5372e02b17bc + - source-3e4c405e9bd479571d83 + - source-4091456d98a90957fe07 + - source-472eb2b12343ba3fa8e5 + - source-4cf5bde77c3a4330d227 - source-4d80199395399e9e47d8 - source-51a0e1edbe8fc1ce9d5a - source-523815a4d8be2b7368b9 + - source-57a7fe4d5d7acd711d7b + - source-5abe9c3805865ebd263c + - source-6321e360d21ebafc1539 + - source-644e7df552ad28028b3a + - source-650f1c1afaf31f558df3 + - source-6c270caf7a0f7aea8142 - source-7365200928b2c76a48b7 - source-7db75f16638fc07f166c + - source-98566fabeed1b3474821 + - source-9dee161b28ef4003aeb3 - source-a5d1d621862fa7f1cac0 + - source-a83d235b649d61ebd04a + - source-af973a63a7068c0ccff9 - source-bbf6b0fb0b8942bc569f - source-bda69e86e22cf8e2c66f + - source-c7d664518b9bba629716 + - source-c8cf9fc9a738a7673ab5 - source-ca9f69ba263dbc27bda3 + - source-d09d6a2687fa0f13d64c + - source-d5562f80014ab418430b - source-d8e4c6cb20568d496b94 + - source-daf244691067ecfd0a84 + - source-ef5f15ce3644987cd0d2 + - source-ff6b00bcb15ca05ca7f4 supporting_source_ids: [] discovery_sources: - https://stripe.com/newsroom/information diff --git a/public/research/runs.yml b/public/research/runs.yml index 09b4044..3d4ddf9 100644 --- a/public/research/runs.yml +++ b/public/research/runs.yml @@ -100,6 +100,381 @@ runs: status: complete evidence_path: evidence/source.html sha256: 19cb7d6ab7fd4e4fd12e6a9ca59bddd5432cd53a8964bdf1e9f7ce61dc126015 + - kind: backfill + collection: founder-appearances + status: complete + recorded_on: 2026-08-19 + completed_on: 2026-08-19 + review_window: + from: 2009-01-01 + through: 2026-08-19 + artifact_url: https://github.com/hraness/stripe-history/actions/runs/32265726670 + accepted_input_sha256: 429813dbfb2842dd711b5a6d3069724981a0e75b4a0f6cb82452f6ca6ea33a88 + accepted_source_ids: + - source-001e51b689b259d0b4e3 + - source-1278271efc6181fee94f + - source-18cef128fcb5c9083568 + - source-26410b426525f71187bb + - source-4d80199395399e9e47d8 + - source-51a0e1edbe8fc1ce9d5a + - source-523815a4d8be2b7368b9 + - source-7365200928b2c76a48b7 + - source-7db75f16638fc07f166c + - source-a5d1d621862fa7f1cac0 + - source-bbf6b0fb0b8942bc569f + - source-bda69e86e22cf8e2c66f + - source-ca9f69ba263dbc27bda3 + - source-d8e4c6cb20568d496b94 + plan_sha256: 6b072148a122798067e3f9846b6f6221393a4ee8ac309ffa9eb7577325ace725 + decisions: + - candidate_id: candidate-08034f0f05d785abe204 + candidate_url: https://podcasts.apple.com/us/podcast/bonus-episode-stripe-ceo-john-collison-2-28-25/id1480890290?i=1000696834852 + disposition: accepted + source_id: source-d5562f80014ab418430b + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: john-collison-bonus-podcast-2025 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: f38f6215c83abd0c27e4d21f4abf5ec80526c33485be94d7692a2875ed81d7b5 + - candidate_id: candidate-08906a117f80cb97e57e + candidate_url: https://podcasts.apple.com/us/podcast/saastr-636-extreme-product-design-building-things-people/id1089973241?i=1000601129097 + disposition: accepted + source_id: source-ff6b00bcb15ca05ca7f4 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: david-singleton-extreme-product-design-2023 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: b34e8f2b4312e0ee196962aa27deed8f6304172a3bda3c2d40d5f1f1bf1d08c9 + - candidate_id: candidate-08b9d49899a5e3373992 + candidate_url: https://www.youtube.com/watch?v=jdNwzYMtPN8 + native_id: youtube:jdNwzYMtPN8 + disposition: accepted + source_id: source-af973a63a7068c0ccff9 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: patrick-collison-hard-fork-live-2025 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 73006cef6a92e6affb7d188b70c95e074f8c1fce061d9792107d35f3dbfe1f8b + - candidate_id: candidate-0c6b8b8665b1dc406b2d + candidate_url: https://www.youtube.com/watch?v=H8Dl8rZ6qwE + native_id: youtube:H8Dl8rZ6qwE + disposition: accepted + source_id: source-c7d664518b9bba629716 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: patrick-john-collison-hiring-culture-2014 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: b502f4e293592683e173126453bb376c9d90b265202ecdfbe3d31f138ed42273 + - candidate_id: candidate-1127057da8a648bf1325 + candidate_url: https://podcasts.apple.com/mu/podcast/stripes-patrick-collison-micro-pessimism-macro-optimism/id1089013200?i=1000599602701 + disposition: accepted + source_id: source-4cf5bde77c3a4330d227 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: patrick-collison-micro-pessimism-macro-optimism-2023 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 493a556d2095a01b6072884c3334a8c25e981a3c4e08be52f406af5b41652b62 + - candidate_id: candidate-13936ecf14d65dd28c31 + candidate_url: https://podcasts.apple.com/us/podcast/claire-hughes-johnson-coo-of-stripe/id1550832941?i=1000521087003 + disposition: accepted + source_id: source-472eb2b12343ba3fa8e5 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: claire-hughes-johnson-angels-podcast-2021 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 152b20ef78d4529ebc15f9a0b2468857057cb0e2450164d388683dc27028d5fd + - candidate_id: candidate-1439b0c30bf1445c321a + candidate_url: https://www.youtube.com/watch?v=y_4emS6D4og + native_id: youtube:y_4emS6D4og + disposition: accepted + source_id: source-650f1c1afaf31f558df3 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: patrick-collison-unsexy-conf-2013 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 41b3089d7f16c2f6933b8f603b7981b738ef3ae26afb37fb5d2da4d4971e9255 + - candidate_id: candidate-1629cdd0b52b7485e8c3 + candidate_url: https://www.youtube.com/watch?v=AM1_NADNSgI + native_id: youtube:AM1_NADNSgI + disposition: accepted + source_id: source-ef5f15ce3644987cd0d2 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: will-gaybrick-inside-stripe-2025 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 87703359c15b05ddb8922c9714ae7b65f4c2b125d8ca01cc6d8ba8575625f8df + - candidate_id: candidate-185aa164d5de11d6c5df + candidate_url: https://podcasts.apple.com/us/podcast/claire-hughes-johnson-stripe-scaling-operations-and/id80867514?i=1000614322138 + disposition: accepted + source_id: source-57a7fe4d5d7acd711d7b + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: claire-hughes-johnson-scaling-operations-2023 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: b32e9afb9382c6b6aa4c55e0c6fdf021ddf8d479d8179b7ac1e411de6ae05a55 + - candidate_id: candidate-3d4f461f17d71f4cd763 + candidate_url: https://a16z.com/podcast/john-and-patrick-collison-on-stripes-growth-agent-commerce-and-the-future-of-software + disposition: accepted + source_id: source-c8cf9fc9a738a7673ab5 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: john-patrick-collison-stripe-growth-agent-commerce-2026 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 96312e0e64cf5cb3d26109b839fa15f0c0a489e54791c7012b6e54064b0db6fe + - candidate_id: candidate-41cecf83fd68f40211f7 + candidate_url: https://podcasts.apple.com/us/podcast/stripes-david-singleton-on-technology-innovation-putting/id962121995?i=1000569774533 + disposition: accepted + source_id: source-15f3382443f13e368075 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: david-singleton-technology-innovation-2022 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: a13a496da36a7dfd2ad0085fe599b82a071a3fbffb66c945c5f023f771d5477d + - candidate_id: candidate-45ffc95252f7c441f9ea + candidate_url: https://podcasts.apple.com/us/podcast/128-former-coo-corporate-officer-at-stripe-claire-hughes/id1510985491?i=1000602919224 + disposition: accepted + source_id: source-9dee161b28ef4003aeb3 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: claire-hughes-johnson-scaling-people-2023 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: d35a8712233fbffafd092a0ec9da60365ae42ec791f77c47ba8cc82d764ce14d + - candidate_id: candidate-55a7fe20f52aa39d04c8 + candidate_url: https://www.youtube.com/watch?v=yXN5xSXJ1Is + native_id: youtube:yXN5xSXJ1Is + disposition: accepted + source_id: source-daf244691067ecfd0a84 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: john-collison-stripe-ai-day-paris-2023 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 92548fb2c910ac19ca657ce54724d2dd9e8fc63c26392a2c8234314705697c78 + - candidate_id: candidate-57efd8e62dc65eb2b27d + candidate_url: https://www.youtube.com/watch?v=QhGqLqCzFac + native_id: youtube:QhGqLqCzFac + disposition: accepted + source_id: source-98566fabeed1b3474821 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: john-collison-odd-lots-agentic-commerce-2026 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 9ea29f6259f15d3939dd6c5ea2597180677d6828291b02fd19e597eb8eb2e282 + - candidate_id: candidate-67aa73c93b621ed7f57f + candidate_url: https://podcasts.apple.com/jp/podcast/patrick-collison-has-a-few-questions-for-tyler-live/id983795625?i=1000384289632 + disposition: rejected + reason: Patrick Collison is the interviewer, and the complete capture does not provide material first-person evidence about Stripe or its operating history. + evidence: + capture_slug: patrick-collison-questions-tyler-live-2017 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: a169461140e144ca5fcfd1899fab7db644dbb1bb1e282c33f37bf3789a663b3c + - candidate_id: candidate-706e2306f17330f3136f + candidate_url: https://podcasts.apple.com/us/podcast/stripe-ceo-patrick-collison-on-innovating-e-commerce/id1610419911?i=1000613083611 + disposition: accepted + source_id: source-d09d6a2687fa0f13d64c + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: patrick-collison-ecommerce-biomedical-research-2023 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: bdc4d6634d0ed81366000d6461450ba48f7f9f5b27b85adce78f0fc5a1054dbd + - candidate_id: candidate-77053ee631e0eb928516 + candidate_url: https://www.youtube.com/watch?v=F0_IKKY3HCk + native_id: youtube:F0_IKKY3HCk + disposition: accepted + source_id: source-644e7df552ad28028b3a + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: david-singleton-culture-excellence-2023 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 6f6b453e78cd17d4ce4dfb43bcefd2f34befb76305e0d02de31d1bdce0a51675 + - candidate_id: candidate-7d85ac896cc0297dfb63 + candidate_url: https://www.newcomer.co/p/scaling-people-with-claire-hughes + disposition: accepted + source_id: source-a83d235b649d61ebd04a + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: claire-hughes-johnson-scaling-people-newcomer-2023 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 715089f0a258f7e085dbd59b1ddd1e08a26066ac9fbafc4cf8b9be9cd7f03895 + - candidate_id: candidate-854f7cf473710458e390 + candidate_url: https://podcasts.apple.com/us/podcast/cro-stripe-mike-clayville-building-tornado-companies/id1510985491?i=1000538185612 + disposition: accepted + source_id: source-28538b94e9867ad8ddea + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: mike-clayville-building-tornado-companies-2021 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 2ca41b9f8aa88d2c43958098b52179a522ebb3d54ee31e35c4a6e83d45271b1a + - candidate_id: candidate-87e61f8d1c6c3e38fc93 + candidate_url: https://podcasts.apple.com/ca/podcast/the-future-of-the-internet-economy-with-stripe/id1462649946?i=1000567104995 + disposition: accepted + source_id: source-6321e360d21ebafc1539 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: john-collison-future-internet-economy-2022 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: ae73fcc54480b4c7423490bd8f051a9603bf07c2bc86d09346eee6dd55815b92 + - candidate_id: candidate-b861fb2001b954d8ecb3 + candidate_url: https://www.youtube.com/watch?v=YgYiF86h0yU + native_id: youtube:YgYiF86h0yU + disposition: accepted + source_id: source-119db9dd4efb34c354fa + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: patrick-collison-amjad-masad-start-company-2026 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: d6d3f3c9cc8cb0e2daeb49ce98cbe76fe52bb14f1bd2e6433bf94fd92af16a42 + - candidate_id: candidate-bf88346930cc77ac95f6 + candidate_url: https://podcasts.apple.com/no/podcast/stripe-ceo-patrick-collison-on-management-rationalism/id1081584611?i=1000378637097 + disposition: accepted + source_id: source-4091456d98a90957fe07 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: patrick-collison-management-rationalism-2016 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 9d3ce93a839804418f6937fb6e39e2463ffa087f7966ee45f2c68e2eac1121fc + - candidate_id: candidate-c09e1de34bf8384cefbb + candidate_url: https://podcasts.apple.com/us/podcast/stripes-patrick-collison-im-petrified-of-getting-too/id1233991021?i=1000404469689 + disposition: accepted + source_id: source-1c1ccd634b5f7d73f612 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: patrick-collison-petrified-getting-too-big-2018 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: e950fb84e7d2de2f17a665bd449b72b55fee1bad7a37d3d286377c1240129a69 + - candidate_id: candidate-d5c6c16bd5aafd553c08 + candidate_url: https://www.youtube.com/watch?v=-7sWLIybWnQ + native_id: youtube:-7sWLIybWnQ + disposition: rejected + reason: The complete capture is a macro-investing discussion with Stanley Druckenmiller; Stripe appears only in the introduction and receives no material first-person treatment. + evidence: + capture_slug: john-collison-druckenmiller-sohn-2022 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 36ffd0f932b8c7ed0c6af1d6ccb545027f3eac4eecf66a9e413f79bfb2dcef1e + - candidate_id: candidate-d647c9878e90aaa3081d + candidate_url: https://www.youtube.com/watch?v=l9wzs_QIyp0 + native_id: youtube:l9wzs_QIyp0 + disposition: accepted + source_id: source-18b5f3a0d6c6c83811f7 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: john-patrick-collison-friedman-gross-2026 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: b33850f66ab4b941ea1d096110ba39f6ab00f703707a0439e5579aae332132ad + - candidate_id: candidate-d85f3dcac8db9b98e403 + candidate_url: https://podcasts.apple.com/us/podcast/ep-118-will-gaybrick-president-of-product-and/id1606770839?i=1000670156025 + disposition: accepted + source_id: source-39cb086a5372e02b17bc + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: will-gaybrick-capital-allocation-org-design-2024 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 6f5045ab4c70bea73ae98109e872f9bf46570045e716c6d07a03e110a28e8aab + - candidate_id: candidate-ec971caf7ddb276570e0 + candidate_url: https://podcasts.apple.com/us/podcast/tech-and-progress-with-patrick-collison-and-tyler-cowen/id1460731098?i=1000457824338 + disposition: rejected + reason: The complete capture contains a general discussion of technology and progress, but no material first-person evidence about Stripe or its operating history. + evidence: + capture_slug: patrick-collison-tyler-cowen-tech-progress-2019 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: da69918b392e86f3a2fa8837ec9398414d526dc685680a5baebbe2646a3bd57b + - candidate_id: candidate-ef18153d6e91131beee7 + candidate_url: https://podcasts.apple.com/us/podcast/32-patrick-collison-earning-your-stripes/id990149481?i=1000410487693 + disposition: accepted + source_id: source-5abe9c3805865ebd263c + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: patrick-collison-knowledge-project-2018 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 6b7a186c0ddd38a788b5c70d9571294656dc796fcfcfb9f1c45a6640b95e7890 + - candidate_id: candidate-f3a7ae41832e7d6713fa + candidate_url: https://podcasts.apple.com/id/podcast/patrick-collison-on-programming-languages-ai-and/id1819406817?i=1000717598878 + disposition: accepted + source_id: source-6c270caf7a0f7aea8142 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: patrick-collison-programming-languages-ai-stripe-2025 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 446f5f67cded53729ab95ddda9c3aa0454f000efd2419ff4d7d6e30275f18bfe + - candidate_id: candidate-f8bdcfc7437b28cfe1c1 + candidate_url: https://a16z.com/podcast/patrick-collison-on-stripes-early-choices-smalltalk-and-what-comes-after-coding + disposition: accepted + source_id: source-3e4c405e9bd479571d83 + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: patrick-collison-stripe-early-choices-smalltalk-2026 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 4ba1f74be658ee2eed1b697218c6769736d58e1915a2997ebe2fbdb3ee1b46f8 + - candidate_id: candidate-f953cd0f071e44d1c27b + candidate_url: https://podcasts.apple.com/us/podcast/lessons-from-scaling-stripe-claire-hughes-johnson-ex/id1627920305?i=1000602823726 + disposition: accepted + source_id: source-34e9256f6b05d1c012cb + reason: Complete retained capture contains material first-person evidence about Stripe, its products, organization, strategy, or operating history. + evidence: + capture_slug: claire-hughes-johnson-lessons-scaling-stripe-2023 + captured_on: 2026-08-19 + status: complete + evidence_path: evidence/source.html + sha256: 9c8ab8cb6ad45b24f169047a19de8a428f1466f9cc27eefef06548790a9de237 - kind: baseline-import collection: founder-side-projects status: complete diff --git a/public/research/sources.yml b/public/research/sources.yml index 3e4e06a..6d9fb82 100644 --- a/public/research/sources.yml +++ b/public/research/sources.yml @@ -145,6 +145,15 @@ sources: url: https://stripe.com/blog/giving-agents-the-ability-to-pay id: source-10f2721c9aa4fdff57df media_type: article + - kind: interview + publisher: Replit + published_at: 2026-05-21 + title: "The Best Time in History to Start a Company | Patrick Collison & Amjad Masad" + url: https://www.youtube.com/watch?v=YgYiF86h0yU + id: source-119db9dd4efb34c354fa + language: en + media_type: video + native_id: youtube:YgYiF86h0yU - kind: interview publisher: Colossus published_at: 2023-10-17 @@ -154,6 +163,13 @@ sources: language: en media_type: transcript native_id: colossus:collison-a-business-state-of-mind + - kind: interview + publisher: Seedcamp + published_at: 2022-07-13 + title: "Stripe's David Singleton on technology innovation, customers, and the CTO role" + url: https://podcasts.apple.com/us/podcast/stripes-david-singleton-on-technology-innovation-putting/id962121995?i=1000569774533 + id: source-15f3382443f13e368075 + media_type: podcast - kind: primary publisher: Stripe published_at: 2018-09-17 @@ -168,6 +184,15 @@ sources: url: https://stripe.com/blog/a-primer-on-machine-learning-for-fraud-detection id: source-170ce598057aeb518fa4 media_type: article + - kind: interview + publisher: Stripe + published_at: 2026-05-19 + title: "Nat Friedman and Daniel Gross in conversation with John and Patrick Collison" + url: https://www.youtube.com/watch?v=l9wzs_QIyp0 + id: source-18b5f3a0d6c6c83811f7 + language: en + media_type: video + native_id: youtube:l9wzs_QIyp0 - kind: primary publisher: Stripe published_at: 2016-09-19 @@ -212,6 +237,13 @@ sources: url: https://www.ftc.gov/system/files/ftc_gov/pdf/stripe-debanking-letter.pdf id: source-1aceab1f7585dbec2798 media_type: pdf + - kind: interview + publisher: The Times Tech Podcast + published_at: 2018-03-02 + title: "Stripe's Patrick Collison: I'm petrified of getting too confident" + url: https://podcasts.apple.com/us/podcast/stripes-patrick-collison-im-petrified-of-getting-too/id1233991021?i=1000404469689 + id: source-1c1ccd634b5f7d73f612 + media_type: podcast - kind: reporting publisher: The Irish Times published_at: 2026-06-05 @@ -359,6 +391,13 @@ sources: url: https://stripe.com/blog/singapore-eng-office id: source-2770509db6a3e2e2cabd media_type: article + - kind: interview + publisher: Grit + published_at: 2021-10-11 + title: "Stripe CRO Mike Clayville: Building Tornado Companies" + url: https://podcasts.apple.com/us/podcast/cro-stripe-mike-clayville-building-tornado-companies/id1510985491?i=1000538185612 + id: source-28538b94e9867ad8ddea + media_type: podcast - kind: primary publisher: Stripe published_at: 2026-04-29 @@ -487,6 +526,13 @@ sources: url: https://stripe.com/en-ca/newsroom/news/stripe-terminal-accelerates-global-momentum id: source-34734b9c0fe2092013a9 media_type: article + - kind: interview + publisher: Lenny's Podcast + published_at: 2023-03-05 + title: "Lessons from scaling Stripe | Claire Hughes Johnson" + url: https://podcasts.apple.com/us/podcast/lessons-from-scaling-stripe-claire-hughes-johnson-ex/id1627920305?i=1000602823726 + id: source-34e9256f6b05d1c012cb + media_type: podcast - kind: reporting publisher: TechCentral.ie published_at: 2013-09-03 @@ -535,6 +581,13 @@ sources: url: https://press.stripe.com/scaling id: source-391821de004fb1a8d195 media_type: article + - kind: interview + publisher: The Logan Bartlett Show + published_at: 2024-09-20 + title: "Will Gaybrick on capital allocation, org design, AI, and global growth" + url: https://podcasts.apple.com/us/podcast/ep-118-will-gaybrick-president-of-product-and/id1606770839?i=1000670156025 + id: source-39cb086a5372e02b17bc + media_type: podcast - kind: reporting publisher: TechCrunch published_at: 2014-12-02 @@ -555,6 +608,20 @@ sources: url: https://news.bloomberglaw.com/coronavirus/riding-record-valuations-fintech-companies-keep-hiring-lawyers id: source-3d6c52f0fa2137ac7a41 media_type: article + - kind: interview + publisher: a16z + published_at: 2026-02-20 + title: "Patrick Collison on Stripe's early choices, Smalltalk, and what comes after coding" + url: https://a16z.com/podcast/patrick-collison-on-stripes-early-choices-smalltalk-and-what-comes-after-coding + id: source-3e4c405e9bd479571d83 + media_type: podcast + - kind: interview + publisher: The Gray Area + published_at: 2016-12-06 + title: "Stripe CEO Patrick Collison on management, rationalism, and the Enlightenment" + url: https://podcasts.apple.com/no/podcast/stripe-ceo-patrick-collison-on-management-rationalism/id1081584611?i=1000378637097 + id: source-4091456d98a90957fe07 + media_type: podcast - kind: primary publisher: Stripe Press title: Working in Public @@ -580,6 +647,13 @@ sources: url: https://press.stripe.com/scaling-people id: source-46bb338c33a88fca0929 media_type: article + - kind: interview + publisher: "The #ANGELS Podcast" + published_at: 2021-05-10 + title: "Claire Hughes Johnson, COO of Stripe" + url: https://podcasts.apple.com/us/podcast/claire-hughes-johnson-coo-of-stripe/id1550832941?i=1000521087003 + id: source-472eb2b12343ba3fa8e5 + media_type: podcast - kind: primary publisher: Meta published_at: 2025-04-11 @@ -635,6 +709,13 @@ sources: url: https://paystack.com/stripe id: source-4cba29dde5bde54884d6 media_type: article + - kind: interview + publisher: Greymatter + published_at: 2023-02-14 + title: "Stripe's Patrick Collison: Micro Pessimism, Macro Optimism" + url: https://podcasts.apple.com/mu/podcast/stripes-patrick-collison-micro-pessimism-macro-optimism/id1089013200?i=1000599602701 + id: source-4cf5bde77c3a4330d227 + media_type: podcast - kind: interview publisher: Colossus published_at: 2020-06-16 @@ -728,6 +809,13 @@ sources: url: https://stripe.com/en-cy/newsroom/news/toronto id: source-56f670931dbb37ef809e media_type: article + - kind: interview + publisher: Stanford eCorner + published_at: 2023-05-24 + title: "Claire Hughes Johnson on scaling operations and culture at Stripe" + url: https://podcasts.apple.com/us/podcast/claire-hughes-johnson-stripe-scaling-operations-and/id80867514?i=1000614322138 + id: source-57a7fe4d5d7acd711d7b + media_type: podcast - kind: interview publisher: Wharton FinTech Podcast published_at: 2026-01-14 @@ -755,6 +843,13 @@ sources: url: https://www.sfgate.com/tech/article/stripe-lays-off-1000-employees-17556389.php id: source-5a48b33330f710b1c700 media_type: article + - kind: interview + publisher: The Knowledge Project + published_at: 2018-05-02 + title: "Patrick Collison: Earning Your Stripes" + url: https://podcasts.apple.com/us/podcast/32-patrick-collison-earning-your-stripes/id990149481?i=1000410487693 + id: source-5abe9c3805865ebd263c + media_type: podcast - kind: primary publisher: Stripe Press title: An Elegant Puzzle @@ -801,6 +896,13 @@ sources: url: https://stripe.com/blog/ending-bitcoin-support id: source-61963e80f78f63567415 media_type: article + - kind: interview + publisher: The David McWilliams Podcast + published_at: 2022-06-20 + title: "The future of the internet economy with John Collison" + url: https://podcasts.apple.com/ca/podcast/the-future-of-the-internet-economy-with-stripe/id1462649946?i=1000567104995 + id: source-6321e360d21ebafc1539 + media_type: podcast - kind: primary publisher: Stripe published_at: 2020-12-03 @@ -808,6 +910,24 @@ sources: url: https://stripe.com/newsroom/news/treasury id: source-642ae265859bee92a254 media_type: article + - kind: interview + publisher: Lenny's Podcast + published_at: 2023-05-04 + title: "Building a culture of excellence | David Singleton" + url: https://www.youtube.com/watch?v=F0_IKKY3HCk + id: source-644e7df552ad28028b3a + language: en + media_type: video + native_id: youtube:F0_IKKY3HCk + - kind: interview + publisher: 500 Global + published_at: 2013-08-13 + title: "unSEXY Conf 2013: Patrick Collison, Stripe" + url: https://www.youtube.com/watch?v=y_4emS6D4og + id: source-650f1c1afaf31f558df3 + language: en + media_type: video + native_id: youtube:y_4emS6D4og - kind: primary publisher: Anthropic published_at: 2025-10-07 @@ -856,6 +976,13 @@ sources: url: https://rootsofprogress.org/about/ id: source-6a70e99c09c187ea49b2 media_type: article + - kind: interview + publisher: Cursor + published_at: 2025-07-17 + title: "Patrick Collison on programming languages, AI, and Stripe's biggest engineering decisions" + url: https://podcasts.apple.com/id/podcast/patrick-collison-on-programming-languages-ai-and/id1819406817?i=1000717598878 + id: source-6c270caf7a0f7aea8142 + media_type: podcast - kind: primary publisher: Stripe published_at: 2017-04-13 @@ -1211,6 +1338,15 @@ sources: url: https://stripe.com/legal/ssa-services-terms#stripe-next-day-settlement id: source-97444be68e85216131c3 media_type: article + - kind: interview + publisher: Bloomberg Odd Lots + published_at: 2026-05-16 + title: "Stripe's John Collison on how agentic commerce will reshape the internet" + url: https://www.youtube.com/watch?v=QhGqLqCzFac + id: source-98566fabeed1b3474821 + language: en + media_type: video + native_id: youtube:QhGqLqCzFac - kind: reporting publisher: Axios published_at: 2026-07-24 @@ -1259,6 +1395,13 @@ sources: url: https://press.stripe.com/we-are-as-gods id: source-9dc6403512fc204f5744 media_type: article + - kind: interview + publisher: Grit + published_at: 2023-03-06 + title: "Former Stripe COO Claire Hughes Johnson on scaling people" + url: https://podcasts.apple.com/us/podcast/128-former-coo-corporate-officer-at-stripe-claire-hughes/id1510985491?i=1000602919224 + id: source-9dee161b28ef4003aeb3 + media_type: podcast - kind: reporting publisher: VentureBeat published_at: 2017-06-22 @@ -1336,6 +1479,13 @@ sources: url: https://www.theguardian.com/technology/2014/jul/22/stripe-steps-up-paypal-rivalry-with-australian-launch id: source-a7f01b8f3120c54b2b6b media_type: article + - kind: interview + publisher: Newcomer + published_at: 2023-08-08 + title: "Scaling People with Claire Hughes Johnson" + url: https://www.newcomer.co/p/scaling-people-with-claire-hughes + id: source-a83d235b649d61ebd04a + media_type: article - kind: filing publisher: U.S. Securities and Exchange Commission published_at: 2025-04-11 @@ -1378,6 +1528,15 @@ sources: url: https://arcinstitute.org/about id: source-af73c6bed56faf7ea27e media_type: article + - kind: interview + publisher: Hard Fork + published_at: 2025-06-27 + title: "Hard Fork Live, with Patrick Collison, Kathryn Zealand, Sam Altman & Brad Lightcap" + url: https://www.youtube.com/watch?v=jdNwzYMtPN8 + id: source-af973a63a7068c0ccff9 + language: en + media_type: video + native_id: youtube:jdNwzYMtPN8 - kind: reporting publisher: TechCrunch published_at: 2011-03-28 @@ -1567,6 +1726,15 @@ sources: url: https://stripe.com/en-ca/newsroom/news/stripe-capital id: source-c5c46de8097c01eba667 media_type: article + - kind: interview + publisher: YC Root Access + published_at: 2014-10-28 + title: "Hiring and Culture, Part 2 | Patrick and John Collison" + url: https://www.youtube.com/watch?v=H8Dl8rZ6qwE + id: source-c7d664518b9bba629716 + language: en + media_type: video + native_id: youtube:H8Dl8rZ6qwE - kind: primary publisher: Stripe published_at: 2021-04-27 @@ -1574,6 +1742,13 @@ sources: url: https://stripe.com/en-fr/newsroom/news/taxjar id: source-c87c7df4d40a29c6f83b media_type: article + - kind: interview + publisher: a16z + published_at: 2026-04-28 + title: "John and Patrick Collison on Stripe's growth, agent commerce, and the future of software" + url: https://a16z.com/podcast/john-and-patrick-collison-on-stripes-growth-agent-commerce-and-the-future-of-software + id: source-c8cf9fc9a738a7673ab5 + media_type: podcast - kind: reporting publisher: TechCrunch published_at: 2012-07-09 @@ -1642,6 +1817,13 @@ sources: url: https://podcasts.apple.com/za/podcast/140-from-stripes-fifth-engineer-to-serving-millions/id1512227295?i=1000773198342 id: source-cf93160c4967b70fc148 media_type: podcast + - kind: interview + publisher: The Minor Consult + published_at: 2023-05-15 + title: "Stripe CEO Patrick Collison on innovating e-commerce and accelerating biomedical research" + url: https://podcasts.apple.com/us/podcast/stripe-ceo-patrick-collison-on-innovating-e-commerce/id1610419911?i=1000613083611 + id: source-d09d6a2687fa0f13d64c + media_type: podcast - kind: reporting publisher: Reuters published_at: 2024-10-21 @@ -1683,6 +1865,13 @@ sources: url: https://www.irishtimes.com/life-and-style/people/harvard-next-on-menu-for-knowledge-hungry-dot-com-high-flyer-1.738348 id: source-d506d7eb5c4011f06d96 media_type: article + - kind: interview + publisher: Squawk Pod + published_at: 2025-02-28 + title: "Bonus Episode: Stripe CEO John Collison" + url: https://podcasts.apple.com/us/podcast/bonus-episode-stripe-ceo-john-collison-2-28-25/id1480890290?i=1000696834852 + id: source-d5562f80014ab418430b + media_type: podcast - kind: primary publisher: Stripe published_at: 2016-02-24 @@ -1732,6 +1921,15 @@ sources: url: https://stripe.com/blog/sessions-keynote-2021 id: source-da5bc3eea46cefe0be5e media_type: article + - kind: interview + publisher: Stripe + published_at: 2023-10-06 + title: "Arthur Mensch and John Collison | Stripe AI Day Paris" + url: https://www.youtube.com/watch?v=yXN5xSXJ1Is + id: source-daf244691067ecfd0a84 + language: en + media_type: video + native_id: youtube:yXN5xSXJ1Is - kind: primary publisher: Arc Institute published_at: 2021-12-15 @@ -1923,6 +2121,15 @@ sources: url: https://techcrunch.com/2026/04/17/once-close-enough-for-an-acquisition-stripe-and-airwallex-are-now-going-after-each-other/ id: source-ee8d68525578975d8f67 media_type: article + - kind: interview + publisher: The Peel + published_at: 2025-11-13 + title: "Inside Stripe: Stablecoins, AI, and (not) going public | Will Gaybrick" + url: https://www.youtube.com/watch?v=AM1_NADNSgI + id: source-ef5f15ce3644987cd0d2 + language: en + media_type: video + native_id: youtube:AM1_NADNSgI - kind: primary publisher: Stripe published_at: 2020-05-26 @@ -2047,3 +2254,10 @@ sources: url: https://stripe.com/newsroom/news/stripe-launches-uae id: source-ff627c78180e70f274cb media_type: article + - kind: interview + publisher: SaaStr + published_at: 2023-02-22 + title: "Extreme Product Design with Stripe CTO David Singleton" + url: https://podcasts.apple.com/us/podcast/saastr-636-extreme-product-design-building-things-people/id1089973241?i=1000601129097 + id: source-ff6b00bcb15ca05ca7f4 + media_type: podcast diff --git a/scripts/audit-history-research.test.ts b/scripts/audit-history-research.test.ts index 58993ad..957381c 100644 --- a/scripts/audit-history-research.test.ts +++ b/scripts/audit-history-research.test.ts @@ -187,12 +187,12 @@ describe("Stripe history research audit", () => { expect(report.historyFiles).toBe(11); expect(report.events).toBeGreaterThan(200); expect(report.valuations).toBeGreaterThanOrEqual(25); - expect(report.appearances).toBe(13); + expect(report.appearances).toBe(41); expect(report.sources).toBeGreaterThan(250); expect(report.datasetReferencedSources).toBeLessThanOrEqual(report.referencedSources); expect(report.mutableSourceUrls).toBe(1); expect(report.mutableSourceSnapshots).toBe(5); - expect(report.researchRuns).toBe(4); + expect(report.researchRuns).toBe(5); expect(report.referencedSources + report.unreferencedSources).toBe(report.sources); expect(report.unreferencedSources).toBe(0); expect(report.collectionInputs).toBeGreaterThan(40); @@ -231,7 +231,7 @@ describe("Stripe history research audit", () => { const evolvedReport = await auditHistoryResearch(temporaryProject); expect(evolvedReport).toMatchObject({ - researchRuns: 5, + researchRuns: 6, }); const [unfinishedPlan] = await planHistoryResearchDiscovery( @@ -370,6 +370,23 @@ describe("Stripe history research audit", () => { ); }); + test("binds historical backfills to their prior accepted corpus", async () => { + const temporaryProject = await copyResearchProject(); + const runsPath = join(temporaryProject, "public", "research", "runs.yml"); + const runs = parse(await readFile(runsPath, "utf8")) as { + runs: Array>; + }; + const backfill = runs.runs.find(({ collection, kind }) => + kind === "backfill" && collection === "founder-appearances"); + if (backfill === undefined) throw new Error("Missing founder appearance backfill fixture"); + backfill.accepted_input_sha256 = "0".repeat(64); + await writeFile(runsPath, stringify(runs)); + + await expect(auditHistoryResearch(temporaryProject)).rejects.toThrow( + "founder-appearances backfill accepted-input digest is invalid", + ); + }); + test("requires complete evidence for every all-accepted input in strict archive mode", async () => { const temporaryProject = await copyResearchProject(); const captureRoot = await temporaryCaptureRoot(); @@ -379,13 +396,6 @@ describe("Stripe history research audit", () => { sourceUrl: "https://stripe.com/blog/changelog", status: "complete", }); - const appearanceEvidence = "complete a16z appearance capture evidence"; - await writeWebCapture(captureRoot, "tokens-are-the-new-dollars-evidence-2026-08-19", { - capturedAt: "2026-08-19T12:00:00.000Z", - evidence: appearanceEvidence, - sourceUrl: "https://www.youtube.com/watch?v=P5iICDVn5gc", - status: "complete", - }); const collectionsPath = join(temporaryProject, "public", "research", "collections.yml"); const collections = parse(await readFile(collectionsPath, "utf8")) as { mutable_sources: Array<{ capture_evidence: { sha256: string } }>; @@ -395,17 +405,32 @@ describe("Stripe history research audit", () => { mutable.capture_evidence.sha256 = createHash("sha256").update(evidence).digest("hex"); const runsPath = join(temporaryProject, "public", "research", "runs.yml"); const runs = parse(await readFile(runsPath, "utf8")) as { - runs: Array<{ collection: string; decisions?: Array<{ evidence?: { sha256: string } }> }>; + runs: Array<{ + decisions?: Array<{ + candidate_url: string; + evidence?: { + capture_slug: string; + captured_on: string; + sha256: string; + }; + }>; + }>; }; - const appearanceRun = runs.runs.find(({ collection, decisions }) => - collection === "founder-appearances" && decisions !== undefined && decisions.length > 0); - const appearanceDecision = appearanceRun?.decisions?.[0]; - if (appearanceDecision?.evidence === undefined) { - throw new Error("Missing appearance evidence fixture"); + for (const run of runs.runs) { + for (const decision of run.decisions ?? []) { + if (decision.evidence === undefined) continue; + const decisionEvidence = `complete evidence for ${decision.candidate_url}`; + await writeWebCapture(captureRoot, decision.evidence.capture_slug, { + capturedAt: `${decision.evidence.captured_on}T12:00:00.000Z`, + evidence: decisionEvidence, + sourceUrl: decision.candidate_url, + status: "complete", + }); + decision.evidence.sha256 = createHash("sha256") + .update(decisionEvidence) + .digest("hex"); + } } - appearanceDecision.evidence.sha256 = createHash("sha256") - .update(appearanceEvidence) - .digest("hex"); await Promise.all([ writeFile(collectionsPath, stringify(collections)), writeFile(runsPath, stringify(runs)), diff --git a/scripts/audit-history-research.ts b/scripts/audit-history-research.ts index c9c66eb..60ee8f9 100644 --- a/scripts/audit-history-research.ts +++ b/scripts/audit-history-research.ts @@ -492,6 +492,23 @@ function baselinePlanPayload( }; } +function backfillPlanPayload( + collection: ResearchCollection, + acceptedSourceIds: readonly string[], + artifactUrl: string, + reviewWindow: Readonly<{ from: string; through: string }>, +): Readonly> { + return { + acceptedInputSha256: sha256(canonicalJson(acceptedSourceIds)), + acceptedSourceIds, + artifactUrl, + collection: collection.id, + dataset: collection.dataset, + reviewWindow, + schema: "stripe-history/research-backfill-plan/v1", + }; +} + export function stableCandidateDecisionId( collection: string, planSha256: string, @@ -659,6 +676,68 @@ function verifyDiscoveryRun( } } +function verifyBackfillRun( + run: Extract, + collection: ResearchCollection, + sourceById: ReadonlyMap, +): void { + if (run.collection !== collection.id) { + throw new Error(`Backfill run ${run.plan_sha256} has inconsistent collection identity`); + } + if (run.review_window.through > collection.coverage.through) { + throw new Error(`${collection.id} backfill review exceeds collection coverage`); + } + const expectedAcceptedDigest = sha256(canonicalJson(run.accepted_source_ids)); + if (run.accepted_input_sha256 !== expectedAcceptedDigest) { + throw new Error(`${collection.id} backfill accepted-input digest is invalid`); + } + const expectedPlanDigest = sha256(canonicalJson(backfillPlanPayload( + collection, + run.accepted_source_ids, + run.artifact_url, + run.review_window, + ))); + if (run.plan_sha256 !== expectedPlanDigest) { + throw new Error(`${collection.id} backfill plan digest is invalid`); + } + assertCanonicalUrlValue(run.artifact_url, `${collection.id} backfill artifact`); + for (const sourceId of run.accepted_source_ids) { + if (!sourceById.has(sourceId)) { + throw new Error(`${collection.id} backfill input references missing ${sourceId}`); + } + } + for (const decision of run.decisions) { + assertCanonicalUrlValue(decision.candidate_url, `${collection.id} ${decision.candidate_id}`); + const expectedId = stableCandidateDecisionId( + collection.id, + run.plan_sha256, + decision.candidate_url, + decision.native_id, + ); + if (decision.candidate_id !== expectedId) { + throw new Error(`${collection.id} candidate ${decision.candidate_id} must use ${expectedId}`); + } + if (decision.disposition === "accepted") { + const source = sourceById.get(decision.source_id); + if (source === undefined) { + throw new Error(`${collection.id} accepted candidate references missing ${decision.source_id}`); + } + if (canonicalCaptureUrl(source.url) !== canonicalCaptureUrl(decision.candidate_url)) { + throw new Error(`${collection.id} accepted candidate URL does not match ${decision.source_id}`); + } + if (decision.evidence.status !== "complete") { + throw new Error(`${collection.id} accepted candidate requires complete capture evidence`); + } + } else if (decision.disposition === "duplicate") { + if (!sourceById.has(decision.duplicate_of_source_id)) { + throw new Error( + `${collection.id} duplicate candidate references missing ${decision.duplicate_of_source_id}`, + ); + } + } + } +} + function verifyResearchRuns( loaded: LoadedResearch, sourceById: ReadonlyMap, @@ -674,6 +753,7 @@ function verifyResearchRuns( throw new Error(`${collection.id} does not accept discovery-run ledger entries`); } if (run.kind === "discovery") verifyDiscoveryRun(run, collection, sourceById); + if (run.kind === "backfill") verifyBackfillRun(run, collection, sourceById); } for (const collection of loaded.collections) { @@ -682,13 +762,22 @@ function verifyResearchRuns( const completeRuns = runs .filter((run) => run.status === "complete") .toSorted((left, right) => { - const leftTarget = left.kind === "baseline-import" - ? left.target_through - : left.plan.watermark.targetThrough; - const rightTarget = right.kind === "baseline-import" - ? right.target_through - : right.plan.watermark.targetThrough; - return leftTarget.localeCompare(rightTarget); + const target = (run: ResearchRun): string => { + if (run.kind === "baseline-import") return run.target_through; + if (run.kind === "discovery") return run.plan.watermark.targetThrough; + return run.completed_on; + }; + const rank = (run: ResearchRun): number => { + if (run.kind === "baseline-import") return 0; + if (run.kind === "discovery") return 1; + return 2; + }; + const digest = (run: ResearchRun): string => run.kind === "discovery" + ? run.plan.planSha256 + : run.plan_sha256; + return target(left).localeCompare(target(right)) + || rank(left) - rank(right) + || digest(left).localeCompare(digest(right)); }); const baselineRuns = completeRuns.filter((run) => run.kind === "baseline-import"); if (baselineRuns.length !== 1 || completeRuns[0]?.kind !== "baseline-import") { @@ -721,25 +810,28 @@ function verifyResearchRuns( let acceptedSourceIds = [...imported]; let reviewedThrough = baseline.target_through; for (const run of completeRuns.slice(1)) { - if (run.kind !== "discovery") { + if (run.kind === "baseline-import") { throw new Error(`${collection.id} cannot contain a second baseline import`); } - if (run.plan.watermark.reviewedThrough !== reviewedThrough) { - throw new Error(`${collection.id} complete discovery runs must form a watermark chain`); + const runAcceptedSourceIds = run.kind === "discovery" + ? run.plan.acceptedSourceIds + : run.accepted_source_ids; + if (!sameValues(runAcceptedSourceIds, acceptedSourceIds)) { + const label = run.kind === "discovery" ? "discovery" : "backfill"; + throw new Error(`${collection.id} ${label} inputs do not match the prior complete run`); } - if (!sameValues(run.plan.acceptedSourceIds, acceptedSourceIds)) { - throw new Error(`${collection.id} discovery inputs do not match the prior complete run`); + if (run.kind === "discovery" && run.plan.watermark.reviewedThrough !== reviewedThrough) { + throw new Error(`${collection.id} complete discovery runs must form a watermark chain`); } acceptedSourceIds = [ ...acceptedSourceIds, - ...run.decisions - .filter((decision) => decision.disposition === "accepted") - .map(({ source_id: sourceId }) => sourceId), + ...run.decisions.flatMap((decision) => + decision.disposition === "accepted" ? [decision.source_id] : []), ].toSorted(); if (new Set(acceptedSourceIds).size !== acceptedSourceIds.length) { - throw new Error(`${collection.id} complete discovery run re-accepts an existing source`); + throw new Error(`${collection.id} complete run re-accepts an existing source`); } - reviewedThrough = run.plan.watermark.targetThrough; + if (run.kind === "discovery") reviewedThrough = run.plan.watermark.targetThrough; } if (reviewedThrough !== collection.coverage.through) { throw new Error( @@ -1202,7 +1294,7 @@ async function verifyDeclaredCaptureEvidence( ); } for (const run of loaded.researchRuns) { - if (run.kind !== "discovery") continue; + if (run.kind === "baseline-import") continue; for (const decision of run.decisions) { if (decision.evidence !== undefined) { await verifyCaptureEvidenceBundle(