DocsGENERALTEAM-SPECIFICILLUSTRATIVE

A Reading Strategy for an Unfamiliar Library

Given a library's documentation and no prior knowledge, find five things and stop: how to install it, the one abstraction everything else is built on, one API call you can run, what it does when something goes wrong, and one limitation that would matter in production.

The moveWorked exampleNext questions

The situation, the reflex, and why it stalls

Every lesson starts where being stuck starts: someone has a problem, and the first move that comes to mind feels like progress.

The question

You have been pointed at an unfamiliar library's documentation and told to evaluate it by tomorrow. What are the five things you must find before you have read enough, and how do you find each one?

The situation

The team is considering a job-queue library for sending order emails and generating invoices in the background. Its documentation has a home page, an installation page, a concepts section, an API reference with dozens of entries, a deployment guide and an FAQ. You have an afternoon and no idea which of it matters.

The reflex

Read the concepts section end to end, because that is where understanding lives, and then skim the API reference for anything that looks relevant. It feels thorough, and the concepts section is usually well written.

Why it stalls

The concepts section is read and remembered as a set of words — job, queue, worker, retry, backoff — with no idea which of them the store would use or how they behave at the edges. Understanding the author's model is not the same as knowing whether the library fits.

What the reflex produces — and fails to produce
  • The concepts section is read and remembered as a set of words — job, queue, worker, retry, backoff — with no idea which of them the store would use or how they behave at the edges. Understanding the author's model is not the same as knowing whether the library fits.
  • The reference skim finds many calls and runs none, so the evaluation is a summary of what the docs claim, and tomorrow's decision is made on claims.
  • The parts of the documentation that would decide the question — what happens when a worker dies mid-job, how many jobs it can hold, what storage it needs — are in the deployment guide and the FAQ, which the reflex reads last or not at all.
  • The afternoon ends with a feeling of having learned a lot and a recommendation that amounts to "it seems fine".
ProblemUnderstandRequirementsConstraintsUnknownsDecompositionSmallest StepModelExperimentObserveDebugLearnIterate

The move

Precisely enough to apply it to a problem you have never seen — not a slogan.

  • Decompose "read the docs" into five findable things, each with a test for having found it: install (it runs on your machine), the core abstraction (you can name the one thing everything else is built on and say what it is not), one API (you have called it and seen the result), error behaviour (you have caused a failure and seen what the library did), and one production limitation (you can name a constraint that would matter for your load, your deployment or your data).
  • Find each in the section that owns it, in an order that lets each finding support the next: install first because nothing can be run without it; the core abstraction next because it tells you which API to try; the API because running it makes the abstraction concrete; the error behaviour by breaking what you just ran; the limitation last, from the deployment guide, the FAQ and the issue tracker.
  • Stop when all five exist as evidence — a running install, a named abstraction, an executed call, an observed failure, a quoted limitation. Everything else in the documentation is answers to questions you can ask when they arise.
  • Report the five things, not a summary of the docs. Five concrete findings decide the question; a summary restates it.

"Read the docs", decomposed

"Read the documentation" is a heading, not a task: it has no test for being done. Decomposed, it becomes five subproblems, each of which has an observation that shows it is finished. The tree is deliberately shallow; the point is that every leaf can be checked in an afternoon.

The "why" on each node says what the finding is for, and that is what keeps the five from becoming fifty: a finding that does not help decide whether the library fits is not on the tree.

Evaluating an unfamiliar library
Do we understand this library well enough to decide?
  • It runsnothing else can be observed until it does
    • Install in an empty projecttestable The library imports and its smallest example runs; whatever it needed to get there — a broker, a database, a credential — is written down as an operating cost.
  • We know what it isthe core abstraction decides which API matters and what the library will never do
    • Name the core abstractiontestable One sentence saying what it is, one saying what it is not; the noun appears in every other section of the docs.
  • We have used ita call that ran makes the abstraction concrete and the docs checkable
    • Run one API calltestable The call that creates or consumes the core abstraction executes against the install and its output matches — or does not match — the reference entry.
  • We have broken itthe failure behaviour is what the store will meet in production
    • Cause a handler failuretestable A thrown error produces an observed retry, drop or dead-letter, written down as observed.
    • Kill it mid-worktestable The state left behind and the time until recovery are observed, and compared with what the docs claimed.
  • We know one way it would hurt usa limitation that touches a real requirement decides more than any feature
    • Quote one production limitationtestable A sentence from the deployment guide, FAQ or issue tracker, paired with the store requirement it touches.

Every leaf is an observation, not a reading assignment. "Read the concepts section" is not a leaf, because there is no way to tell when it is done.

Where each finding lives

Documentation is organised for the author's general case, so the five findings are scattered across it in a predictable way. The matrix is a rough map: where each thing is usually found, what it looks like when found, and the trap that makes you think you found it when you did not.

The pattern worth noticing is that the two findings that decide most — error behaviour and limitations — live in the sections the reflex reads last.

FindingUsually lives inLooks like, when foundLooks like, when not
InstallGetting started; requirementsThe smallest example runs on your machine; the dependencies it pulled in are listedA copied install command that has not been run, or has been run in the store instead of an empty project
Core abstractionConcepts; the first page of the referenceOne noun that every other section uses, with a sentence on what it is notA list of all the nouns in the concepts section
One APIReference entry for the abstraction's create/consume callA call you executed and whose output you sawA signature you read and could paraphrase
Error behaviourReference notes; a "reliability" or "errors" page; the source of the retry logicA failure you caused and the library's observed response, compared against the docsThe docs' statement that it "handles failures gracefully"
Production limitationDeployment guide; FAQ; limits page; open issuesA quoted sentence paired with a store requirement it touchesAn interesting limitation that touches nothing you are building

What the afternoon leaves on the board

The five findings answer whether to continue. They also raise the questions the next step will need, and those belong on the unknowns board as specific questions with experiments, not in the evaluation as caveats.

The board below is the job-queue afternoon's output. Notice that every unknown was found by running or breaking something, and every one has an experiment small enough to do before the decision is final.

After evaluating the job-queue library
known
  • It needs a broker; operating it means operating the broker.
  • The core abstraction is a job — payload plus handler — with no dependencies between jobs.
  • A thrown handler is retried with backoff; a killed worker leaves a job "running" until stalled-job detection fires.
  • Jobs are in broker memory unless persistence is configured, and it is off by default.
assumed
  • ~The store needs at most a handful of job types — emails, invoices — and no workflow between them. To check against the product roadmap before committing.
unknown → question → experiment
  1. ? Is it reliable enough for invoices?

    becomes With persistence on and the broker restarted while a job is queued, is the job still there afterwards, and is it run exactly once or at least once?

    experiment Enqueue a job, restart the broker, start a worker; count how many times the handler runs.

  2. ? What about the stalled thing?

    becomes If a worker dies mid-invoice, how long until another worker retries, and can the handler tell it is a retry so it does not generate the invoice twice?

    experiment Kill a worker mid-handler with the timeout set low; log the attempt number the library passes to the handler.

  3. ? Will it scale?

    becomes Nothing in the store's current load justifies the question; it is filed, not researched, until there is a measured backlog.

    experiment None yet — record the queue depth in production and revisit when it is non-trivial (Add Complexity Only When Required).

The third item is deliberately left as a non-experiment. An unknown with no requirement behind it is not researched; it is written down so that it is not forgotten when the requirement arrives.

How to do it

Most important first.

  • Install it in an empty project first. If installation needs a service you do not have — a broker, a database — that is your first finding about operating cost, and it decides whether the afternoon continues (Integration and Operating Cost).
  • Open the concepts section and look for the one noun that appears in every other section. That is the core abstraction. Write one sentence about what it is and one about what it is not.
  • Pick the API call that creates or consumes that abstraction — enqueue a job, run a worker — and run it against the install. Observe the output, not the docs' description of it.
  • Break it: enqueue a job whose handler throws; kill the worker mid-job; enqueue with a bad payload. Observe what the library does and compare with what the docs said it would do (Failure Injection).
  • Read the deployment guide, the FAQ and the open issues for the words "limit", "max", "not supported", "known". Quote one limitation that would touch the store — job size, persistence, ordering, concurrency.
  • Write the five findings on one page and the questions they raised on the unknowns board. That page is the evaluation (Evaluating a Technology).

Worked on a concrete problem

The move has to produce something. This is what it produced.

  • The job-queue library. Install: it needs a broker; installing one locally took most of an hour, which is itself a finding — operating this means operating the broker. Core abstraction: the job, a serialised payload plus a handler name; what it is not is a workflow — there is no notion of one job depending on another. One API: enqueue a "send confirmation" job with an order id; a worker picked it up and logged it.
  • Error behaviour, by breaking it: a handler that throws was retried with backoff, as documented; a worker killed mid-job left the job in a "running" state that a second worker did not pick up until a timeout the docs called "stalled job detection" — which the concepts section had not mentioned at all. A payload with a non-serialisable field failed at enqueue time with a clear error.
  • One limitation: the FAQ says jobs live in the broker's memory unless persistence is configured, and the deployment guide says persistence is off by default. For invoices that must be generated, that decides the configuration before any code is written. Five findings, one page, one afternoon — and the recommendation is specific: fits, provided persistence is on and the stalled-job timeout is set below the invoice deadline.

How you know it worked

What now exists that did not before, and what question you can now ask.

  • The library runs on your machine and you know what it needed to get there.
  • You can name the core abstraction in one sentence and say one thing it deliberately is not.
  • You have run one call and caused at least one failure, and the failure behaviour is written down as observed rather than as documented.
  • You can quote one limitation and say which requirement of the store it touches.
  • The evaluation fits on a page and every line on it is evidence.

The questions you can now ask

The field this whole domain exists for. After this lesson, these are the questions to put to an unfamiliar problem.

Next questions
  • ?What does this library need in order to run at all, and is that a cost I am willing to operate?
  • ?What is the one abstraction everything else here is built on, and what is it explicitly not?
  • ?Which single call would make that abstraction concrete if I ran it now?
  • ?What happens when the handler throws, the process dies, or the input is wrong — as observed, not as documented?
  • ?Which limitation in the deployment guide or FAQ touches a requirement I actually have?

What can go wrong

How the move itself fails
  • The five become fifty: every abstraction is explored, every API run, every failure induced, and the afternoon becomes a week. Five is enough to decide whether to continue; continuing is a separate decision.
  • The five are found from the docs alone and none is run. An abstraction named from the concepts page and an API described from the reference are claims; the strategy is built on evidence, and evidence comes from running.
  • The limitation is chosen for being interesting rather than for touching the store. A limitation about clustering does not matter for a single worker; the one about persistence does.
  • The strategy is applied to a library the team already knows, out of ritual, and finds nothing the team could not have said in a minute. The strategy is for first contact.
What the move costs
  • Five findings is a first evaluation, not a complete one; a library can pass all five and fail on the sixth thing you never looked for. The strategy trades coverage for a decision by tomorrow.
  • Running and breaking costs an install and a scratch project that reading does not; for a library you are curious about rather than considering, that is wasted.
  • The limitation you find is one of many; choosing it by relevance to today's requirements means tomorrow's requirement may meet a different one.
Misreads
  • "Five is the right number." Five is the smallest set that covers running it, understanding it, using it, breaking it and operating it. A library with two core abstractions needs both named; the number is a floor, not a template.
  • "The concepts section is where understanding lives, so read it fully." It is where the author's model lives. Your understanding lives in the call you ran and the failure you observed; the concepts section is consulted to name them.
  • "A limitation found means the library is out." A limitation found means a requirement is now explicit. Persistence off by default is a configuration line, not a rejection; the point is that you know it before it costs an invoice.

Where this applies

Problem-solving advice is stated as universal far more often than it is. These labels say what each method is specific to — and where CONTESTED appears, the note gives the strongest form of the opposing view.

  • GENERALInstall, core abstraction, one API, error behaviour, one limitation apply to any library, service or tool — for a hosted service "install" becomes "get a working credential and make one call", and the limitation usually lives on a pricing or limits page.
  • TEAM-SPECIFICA solo learner runs the five to build understanding; a team lead runs them to decide, and reports the five findings rather than the learning. On a team with someone who already operates the library, the strategy collapses to asking them the five questions.
  • ILLUSTRATIVEThe job-queue library, its broker, its stalled-job timeout and its persistence default are invented to show the shape of the evaluation; no real library is being reviewed.

Where the depth lives

This domain asks the question and hands the answer off by name.

Further
  • The manifesto at /manifesto/delegating: a job queue delegates scheduling and retry; whether the handler is safe to run twice stays yours, and that is the first experiment on the board.