Capstone: Write a Service Docs Pack
LESSON
Capstone: Write a Service Docs Pack
By the end of this lesson, you will be able to...
Design a small documentation pack in which each artifact has one reader, promise, and next action.
Produce or review an explanation, how-to, reference slice, runbook, decision record, ownership plan, and revision log for one bounded service.
Evaluate the pack for reader fit, technical fidelity, findability, safe action, maintenance, and links between artifacts.
Idea in one sentence: A trustworthy documentation pack is a set of connected reader paths, not one long page that asks every reader to sift out what they need.
Core Insight
Parcel has released a small import service. A customer wants to send a first file. An API user wants to know what queued, processing, and failed mean. An on-call engineer needs a safe response when queue age rises. A product engineer needs to remember why production concurrency stays at 8 before the pilot at 10. Six months later, a new maintainer needs to know who verifies those pages after the retry contract changes.
The naive answer is a page called Everything about imports. It begins with a system overview, contains a curl command, lists every status, explains the concurrency decision, and ends with a troubleshooting paragraph. It is comprehensive in the way a junk drawer is comprehensive. Every reader finds some relevant words, but must decide which ones are instructions, which are background, and which are no longer true.
The problem is not merely length. Each reader arrives with a different question, risk, time horizon, and next action. A first-time customer needs a path to success. An integrator needs values and edge cases. An on-call engineer needs a bounded procedure under pressure. A future teammate needs evidence and ownership. Putting these jobs in one route makes the document responsible for too many incompatible promises.
This capstone asks you to build a service docs pack: a small, private set of linked artifacts for one bounded service or mechanism. You are not asked to document a whole platform. Choose a service small enough to explain honestly: file import, webhook delivery, scheduled report generation, a feature-flag rollout, a token refresh flow, or another mechanism you can verify.
The pack proves the track's central model: technical writing is an interface for understanding and action. Its quality is visible in the paths readers can take, the evidence they can inspect, the limits they can see, and the maintenance loop that keeps the paths safe.
The Scenario and Constraints
Use the Parcel import service as the worked model, then apply the same structure to your own service. The service accepts a file, validates it, creates an asynchronous import, and exposes its status. It has three constraints:
- A customer should reach a first successful import without already knowing the service internals.
- An API user should be able to construct a valid request and diagnose a
422validation error without reading a tutorial from top to bottom. - An on-call engineer should be able to respond to a queue-age alert without treating a product-capacity decision as an emergency command.
The pack must stay bounded. It should have seven artifacts, each no longer than needed to answer its reader's immediate question. The artifacts may be Markdown files, pages in an internal docs system, or a small folder in a repository. Use fictional names, redacted examples, or a sandbox service if real details are sensitive.
| Artifact | Primary reader and moment | Promise and next action |
|---|---|---|
| Reader map | Writer and reviewers before drafting | Name each reader job, prior knowledge, anxiety, trust need, and handoff. |
| Explanation | A customer or teammate asking “why is import asynchronous?” | Build a mental model; point to the first-import path and status reference. |
| How-to or quickstart | A first-time customer with a file ready | Reach a verified first success; then link to reference and troubleshooting. |
| Reference slice | An integrator looking up a request, status, error, or limit | Construct and interpret one valid interaction; link to the how-to and decision boundary. |
| Runbook | On-call engineer facing a queue-age alert | Verify, take a bounded action, confirm, escalate, and roll back when needed. |
| Decision record | Team member asking why a constraint exists | Recover evidence, alternatives, owner, trade-off, and revisit condition. |
| Ownership and revision log | Maintainer or reviewer after a change | Identify review triggers, verification, links checked, deliberate preservation, and remaining uncertainty. |
This is not seven versions of the same explanation. The explanation may say why a file stays queued. The reference says what queued means and when it changes. The runbook says what an operator checks when it stays queued too long. The decision record says why the team will not raise concurrency as the first response. The reader should be able to follow the links rather than re-learn the service on every page.
Design Goal: Make the Handoffs Visible
Plain meaning:
Give each page one job, then make the next likely question easy to reach.
In the Parcel pack:
The quickstart ends when a user has submitted a file and seen an import ID. It does not need a full explanation of worker scheduling. It links to the status reference when the user asks “what does this value mean?” and to troubleshooting when the result is failed.
Technical name:
This is a documentation surface: several pages that work as one reader journey. Each artifact is a boundary with an explicit handoff, not an isolated page with a generic “see also” list.
Start with a reader map before drafting prose. A small map for Parcel looks like this:
| Reader | Moment and question | What they already know | What must not go wrong | Handoff after this page |
|---|---|---|---|---|
| Noor, customer developer | “Can I import this CSV today?” | Has an API key and sample file. | Sends invalid data without seeing the error path. | Status reference and validation troubleshooting. |
| Lin, integrator | “Can I retry this request, and what does failed mean?” |
Knows HTTP and the endpoint name. | Guesses field values or treats retry as universally safe. | Idempotency boundary and error reference. |
| Mira, on-call engineer | “Queue age is above five minutes. What do I do now?” | Can access dashboards and approved commands. | Raises concurrency or pauses intake without a stop condition. | Escalation policy and concurrency decision record. |
| Jules, new service owner | “Which docs change when retry expiry changes?” | Knows the product change. | Updates one page while leaving a contradictory one live. | Ownership matrix and verification checklist. |
The map prevents a common capstone failure: writing pages that are individually clear but leave the reader stranded at the next question.
Check: A draft page gives a customer a valid curl request, explains the worker architecture, lists every status code, and tells on-call engineers how to pause intake. What is the first design repair?
Think first, then reveal.
Answer: Split the reader jobs before editing the sentences. Keep the first-success path in the quickstart, put reusable fields and errors in reference, keep the mechanism in an explanation, and isolate the alert response in a runbook. A table of contents cannot make four incompatible promises become one reader path.
A Worked Pack Walkthrough
The following walkthrough shows the minimum useful content, not prose to copy. Treat it as a trace from input to connected decisions.
1. Explanation: establish the shared model
The explanation starts with a situation, not a definition:
A customer uploads a 400 MB CSV. The API accepts the file quickly, but the import does not finish immediately. Why not report success at upload time?
It then names the visible pieces: the API accepts the request, the queue holds work, a worker validates rows, and the status endpoint reports the latest known stage. The naive model is “the upload succeeded, so the import succeeded.” It breaks when parsing finds an invalid row after the request has returned.
The explanation earns its main term with a short trace:
| Time | What happens | Status the customer can observe |
|---|---|---|
| 10:00 | API validates request shape and stores the file. | queued with an import ID. |
| 10:01 | Worker claims the job and starts parsing rows. | processing. |
| 10:03 | Worker finds an invalid date in row 41 and stops. | failed with a problem report. |
| 10:05 | Customer corrects the file and submits a new import with a new request key. | A new queued import. |
The output is a mental model: accepting a request is not the same as completing the work. The page ends with the quickstart for a first request and the reference for status fields. It also states its boundary: it explains the stages; it does not authorize an operator to manipulate the queue.
2. How-to and reference: separate doing from looking up
The quickstart leads Noor through one happy path. It names the prerequisite, gives one valid request, says what success looks like, and names the next action if the response differs.
1. Create a CSV with the required `email` and `joined_at` columns.
2. POST the file to `/v1/imports` with an idempotency key unique to this submission.
3. Save the returned `import_id`; the initial status is `queued`.
4. GET `/v1/imports/{import_id}` until it becomes `completed` or `failed`.
5. If it is `failed`, read `problem_report_url` before submitting a corrected file.
The reference slice does different work. It lets Lin retrieve one field, error, or edge case without replaying the tutorial.
| Item | Contract | Boundary or next question |
|---|---|---|
POST /v1/imports |
Accepts a CSV and returns 202 plus import_id. |
202 means accepted for processing, not completed. |
idempotency_key |
Prevents accidental duplicate acceptance for 24 hours. | It does not make an old failed import succeed; see retry guidance. |
status |
queued, processing, completed, or failed. |
failed includes a report URL; do not infer row-level errors from the status alone. |
422 invalid_schema |
Required column or file shape is invalid. | Fix the file; retrying the unchanged request repeats the error. |
The naive failure is to bury this table in the quickstart. The new customer then has to learn every edge case before first success, while the returning integrator must scroll through setup instructions to find a field. The pack uses two paths and links them where the reader's question changes.
3. Runbook and decision record: separate safe response from policy
At 14:10, queue age reaches seven minutes. Mira opens the runbook, not the explanation. The runbook begins with the symptom, exact verification, bounded action, success check, stop condition, escalation, and rollback.
| Input | Transition and intermediate state | Output or decision |
|---|---|---|
| Queue-age alert exceeds 5 minutes for two intervals. | Mira checks the queue-age dashboard, worker error rate, and database-pool use. Pool use is 68%; worker errors are normal. | Confirm a backlog rather than a worker failure. |
| Backlog is confirmed and pool use is below 70%. | Mira pauses new imports using the approved flag and watches queue age for one interval. | Intake pause is a reversible mitigation, not a capacity fix. |
| Queue age falls below 3 minutes. | Mira resumes intake and records the time, metrics, and customer impact. | Incident is mitigated; no concurrency change is made. |
| Queue age does not fall or pool use exceeds 70%. | Mira stops the procedure, pages the import owner, and links the incident record. | Escalation prevents an unsafe improvisation. |
The decision record answers the question the runbook deliberately refuses to answer: why not increase concurrency first? It records that 12 jobs caused unacceptable queue age in the representative test, that 8 is the public-launch limit, that a two-customer pilot at 10 is reversible, and that the service owner reopens the decision after seven days below the queue-age target.
The naïve failure is to put “increase concurrency” in the runbook because it sounds like a direct response to a queue. That confuses a policy choice with an immediate mitigation. The decision record retains the trade-off and evidence; the runbook retains the safe action under pressure.
So far, the pack has made different kinds of knowledge available without making them compete in one page: a model, a path to success, a contract, an operational response, and a traceable judgment.
Maintenance and Revision Evidence
A pack is not complete when its links work on the day it is written. Add a small ownership table that connects each promise to a trigger and a verification method.
| Artifact promise | Accountable role | Review trigger | Verification |
|---|---|---|---|
| “Submit your first import.” | Onboarding owner | Credential, prerequisite, or supported file-format change. | Run the quickstart in a clean account. |
| “This field and error mean this.” | API owner | Contract, default, error, or limit change. | Test request and compare response to the reference. |
| “Use this action when queue age rises.” | Import on-call owner | Alert, flag, dashboard, or rollback change; incident review. | Dry-run command and confirm stop condition. |
| “This is why concurrency is limited.” | Service design owner | Load-test evidence, capacity change, or pilot result. | Review evidence, owner, trade-off, and revisit condition. |
Now apply the four revision passes from the previous lesson. In the revision log, record one change from meaning, shape, style, and proof. For example: split the worker explanation from the runbook (meaning and shape); replace “watch the queue” with a stated metric and interval (style); and test the flag command after a tooling change (proof).
The trade-off is real. A pack takes more coordination than a single page. Its links can break, ownership can be unclear, and readers may still start in the wrong place. The gain is that each artifact can be short, specific, and reviewed against the risk it carries. You can see the boundary when a reader repeatedly follows the wrong link, support invents answers outside the docs, or a product change updates one page but leaves another contradictory.
Check: The API team changes idempotency-key expiry from 24 hours to 6 hours. Which artifacts should be reviewed, and why?
Think first, then reveal.
Answer: Review the reference slice and its retry boundary because they make the public contract. Review the quickstart if it tells the reader how to retry, and the decision record if the change alters its rationale or trade-off. The ownership table should make the API contract change the trigger. The runbook might not change unless it promises that retry behavior; do not update pages merely because they share a folder.
Final Challenge
Build a service docs pack for one bounded service or mechanism you can inspect. Work privately when the subject is real; remove secrets, customer data, and internal URLs from any learning copy. Your pack may use a fictional service, but its contracts and failure paths must still be internally consistent.
Deliver these seven items:
- A reader map with at least three distinct reader jobs and explicit handoffs.
- A 350–600 word explanation with a concrete opening, one visible mechanism or timeline, a boundary, and links to the next reader paths.
- A how-to or quickstart that produces one verifiable success and names the failure route.
- A reference slice with a request or field contract, one valid example, one error or edge case, and retrieval-friendly headings or a table.
- A runbook slice with symptom, verification, bounded action, success check, stop condition, escalation, and rollback or recovery path.
- A short decision record that states a decision, evidence, rejected or deferred alternative, trade-off, owner, and revisit condition.
- An ownership matrix plus a four-pass revision log that names what you changed, preserved, verified, and still do not know.
Use this readiness rubric before calling the pack done:
| Criterion | Evidence of readiness |
|---|---|
| Reader fit | Every artifact identifies one primary reader, moment, promise, and next action; no page tries to serve incompatible jobs. |
| Technical fidelity | Claims, examples, status transitions, commands, and limits agree with the bounded service model. Uncertain claims are marked rather than smoothed over. |
| Findability and handoff | A reader can find the first needed answer and reach the next likely page through a purposeful link. |
| Actionability | The how-to reaches a checkable result; the runbook includes verification, stop conditions, escalation, and recovery. |
| Judgment and trade-offs | The decision record distinguishes evidence from preference and states an accepted cost and revisit condition. |
| Maintenance | Important promises have owners, triggers, verification, and a way to retire or replace obsolete guidance. |
| Revision evidence | The log shows meaning, shape, style, and proof changes, plus one deliberate preservation and one remaining uncertainty. |
If a reviewer can use the pack to submit a file, look up a failure, respond safely to an alert, recover a past decision, and identify who checks the pages after a change, the pack has demonstrated synthesis. If they must ask the author where to look next, the missing piece is probably a reader promise or handoff, not another paragraph of overview.
Resources
- [TUTORIAL] Diátaxis: tutorials, how-to guides, reference, and explanation — Focus: Check that each artifact is shaped around one reader need instead of mixing incompatible modes.
- [REFERENCE] Google developer documentation style guide — Focus: Use it during the style and proof passes for terminology, procedures, links, and examples.
- [GUIDE] AWS architectural decision record process — Focus: Check that a decision remains traceable through context, consequences, ownership, and later revision.
- [GUIDE] Google SRE Workbook: incident response — Focus: Review operational instructions for clear roles, safe actions, escalation, and learning after an incident.
Key Takeaways
- A documentation pack coordinates reader paths; it is not a long page split into arbitrary files.
- Explanation, how-to, reference, runbook, decision record, and maintenance plan each answer a different question and should hand the reader to the next one deliberately.
- A bounded service and a visible trace are more useful than broad coverage with invented certainty.
- Ownership, review triggers, verification, and a revision log keep a clear pack from becoming a collection of stale promises.
← Back to Clear Technical Writing, Rhetoric, and Explanation