Skip to content

Extend the data model so narrative culture memos like Netflix fit cleanly #91

Description

@tig

The force fit is #90 (head 588aad05a93ac59c137fcb4b9872f132f7832d3a). The picker companion is kindel/biq#72. Both are demonstrations. This issue is the model change that would make a memo like Netflix fit. The candidate set itself remains #89. Source of the words: https://www.jobs.netflix.com/culture, heading "The Best Work of Our Lives."

The page is a narrative, four named principles, eight values inside The Dream Team, and operating practices inside People Over Process (context not control, informed captains, highly aligned and loosely coupled, farming for dissent, disagree then commit, the almost-no-rules rule), plus the keeper test, extraordinary candor, decency, top of market pay, footnotes, and a Saint-Exupéry quotation. Pull request 90 stored twenty flat principle records because that is the only shape the corpus has.

Recommended path

Add optional fields. Leave every existing company valid without a migration. Keep one record per addressable idea, so Porridge and BIQ can still attach a table and questions. Put the essay, the footnotes, and the Saint-Exupéry lines on the company, not in a fake principle.

Three changes do the work:

  1. A set-level narrative on the company.
  2. A kind on the record (principle, value, or practice) and an optional parent id, so values can sit under The Dream Team and practices under the principle they come from.
  3. Let a quotation contain an em dash. The style check keeps rejecting em dashes in authored rows, term labels, and docs. definition, and any row marked words: "quoted", may keep the company's dash. SCHEMA.md already says company punctuation stands, and then takes that back for the dash. The exception is what deleted the keeper test, the context-not-control clause, top of market pay, and the sentence that says the culture is four principles.

Calibration facets stay the shared table. They do not become a place to store narrative.

Fields

Company narrative. On the company in scripts/companies.py, beside preamble. preamble stays the one-line introduction the index already ships. narrative is an ordered list of blocks:

  • prose, the company's paragraphs, quoted.
  • quote, an attributed passage. Saint-Exupéry is one of these.
  • note, a footnote. The keeper-test fish story and the Q1 2024 audience note are notes.

A block is { "kind", "text" } and a quote adds attribution. Text is a quotation. The dash exception applies. A consumer that does not know narrative keeps using preamble and the principle list.

Record kind and parent. Optional kind on data/<company>/<slug>.json, default principle when omitted. Optional parent, a principle id in the same company. Sort stays one through n in page order, so a flat reader still works. For Netflix, the four principles have no parent. The eight values parent to The Dream Team. Context not control, informed captain, farming for dissent, disagree then commit, and almost no rules parent to People Over Process. Decency and the keeper test parent to The Dream Team. Highly aligned and loosely coupled is a term of the informed captain only if we keep treating it as the name of that approach. If we want it addressable on its own, it is a practice whose parent is the informed captain, not an equivalent term. Top of market becomes a practice once the quotation can hold the sentence, at the next free id in block 10000. Ids already issued stay put.

Quotation exception. scripts/validate.py check_style skips the em dash and en dash checks for definition and for under, justRight, and over when the row is words: "quoted". Authored and generated rows, term labels, preambles that we write, SCHEMA.md, and AGENTS.md stay clean. The Netflix definitions in pull request 90 can then be replaced with the sentences the page actually uses, including the clause after the dash. That replacement is a follow-on data change, not this issue's schema change by itself.

How the three surfaces render and edit

Porridge. The company page renders narrative in order, then the records grouped by parent, with kind as a label (Principle, Value, Practice). A record page still shows definition and the facet's generated calibration table. Teaching files stay optional and separate from the memo. The picker groups by parent so The Dream Team opens onto its values instead of twenty peers. The index has to carry kind and parent for that grouping. A stub sync is still how singles get a Hugo page. Narrative does not need one stub per paragraph.

BIQ. item stops being inferred only from the set title. Per-record kind is the noun in the how-to: a value is a value, a practice is a practice, and the set title can be "The Best Work of Our Lives" or "Culture Memo" without the how-to saying "per assigned Culture Memo." Stored questions on a principle already override the facet list. Use that for Netflix practices whose facet neighbor is the wrong interview. The keeper test should not inherit low-performer questions once real questions exist. New question text still needs a Junior, Senior, and Exec pack. This model change does not write those questions. Narrative blocks and footnotes are not interview items. Search should match the company's own terms first. Copying the facet label into aliases, so "are right a lot" finds Netflix Judgment, is a sync choice to drop or to mark as a facet hit rather than a principle alias. File today: scripts/sync_from_principles.py in kindel/biq.

Facet. data/facets.json does not grow a narrative or a kind. Membership stays "these records share a calibration table." An editor shows kind and parent as read-only context so a practice is not merged into a neighboring principle to make the list shorter. A value and a practice may share a facet with another company's principle when the behavior matches, which is the rule pull request 90 already tried to follow. Generated rows stay company-agnostic. Netflix published no calibration, so record rows stay authored. That split is working and should stay.

Options and tradeoffs

Option A, keep the force fit. No migration. The cost is the strain list on pull request 90: definitions that quote the caveat instead of the practice, a preamble that cannot mention four principles, twenty peers with no sections, and interview questions borrowed from Amazon. Fine as a demo. Wrong as the published set.

Option B, one memo page, fewer records. Store the essay as narrative and only promote the four principles and eight values to records. Practices stay inside the essay. Porridge gets a readable memo. BIQ and the picker lose the keeper test, context not control, and farming for dissent as things you can assign. Those are the lines people would actually interview on. The essay is a poor substitute for a record with rows and questions.

Option C, the recommendation above. Optional narrative, kind, parent, and a dash exception on quotations. Existing files stay valid. Netflix can be re-cut without a new document type. Cost: the index gains fields, Porridge and BIQ learn to group by parent, and the style check grows one context. Kind and parent can ship before the dash exception, but without the exception the keeper test and context not control remain the wrong sentences.

Option D, a document model that generates records. Blocks, marks, and footnotes as the source, principle records generated from headings. One source of truth. Cost: every consumer learns the document, or we maintain the generator forever. The memo is one page. Option C covers it. A document model is the right answer if a second and third narrative memo show up and option C's blocks get too weak. It is early for this one page.

What I would do first

Ship option C in three patches, each shippable alone.

  1. Kind and parent, optional, defaulting so the current corpus does not change. Extend the index. Porridge groups when parent is present. BIQ uses kind for the how-to noun.
  2. The dash exception on quotations, then a data revision of the Netflix definitions so the stored sentence is the one the page uses. Top of market can become a record at the next id.
  3. Company narrative for the essay, the footnotes, and Saint-Exupéry. Porridge renders it. BIQ links the source and does not assign questions to blocks.

Questions with packs stay a content task on kindel/biq, listed on pull request 90, after the records say the right thing.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions