When would you model a suite's results in a bespoke schema rather than an interchange shape existing tools already read?
answer
- Ask who reads it first
- Free readers versus exact expression
- Rich inside, common shape outside
- Every bespoke field needs a reader
- Projection is lossy one way only
basics
~20 sChoose by who reads it. An interchange shape everything already parses buys integration you never maintain and costs expressiveness; a bespoke model expresses your statuses and attempt history exactly and costs you every reader you must now write and keep writing.
solid answer
~40 sThe decision is rarely either-or. Most teams should keep a **rich internal model** as the source of truth — status vocabulary, reason codes, attempts, typed attachments, stable identities — and **project** it onto a widely-parsed shape at the boundary, accepting a documented one-way loss. Bespoke-only earns its place when you already own the readers, when the distinctions are load-bearing for a decision people make daily, and when the suite's shape is genuinely unusual. It is the wrong call when no reader has been named yet, when other suites in the organisation will eventually be viewed alongside yours, or when turnover means the vocabulary outlives everyone who understood it. If you do go bespoke, you owe three things: a versioned schema, definitions written beside the model, and a projection kept anyway.
code
pseudocode · 15 lines# the internal model is the source of truth; the common shape is a projection
project(case_result):
common.name = case_result.stable_id # never the display title
common.duration = case_result.total_duration
match case_result.status:
PASSED -> common.outcome = "pass"
FAILED -> common.outcome = "fail"
FLAKED -> common.outcome = "pass"; common.note = "flaked: " + attempt_summary
KNOWN_ISSUE -> common.outcome = "skip"; common.note = "known-issue: " + reason
BLOCKED -> common.outcome = "skip"; common.note = "blocked: " + reason
SKIPPED -> common.outcome = "skip"; common.note = "skipped: " + reason
# three internal statuses collapse into one common outcome.
# the loss is deliberate, documented, and never read back in.go deeper
Know that a suite's results have to be read by something other than the person who ran them, and that emitting a shape other tools already understand is the reason results show up in a viewer at all.
Explain what a widely-parsed shape can and cannot express, and why extra statuses so often end up smuggled into free-text fields. Be able to describe a projection from a richer internal model onto a common shape.
Show the year-two costs of a bespoke schema: every reader is yours, every field change needs a version and a migration, and cross-team aggregation stops working. Argue the emit-both position and say precisely where the projection loses information.
Own the decision and the conditions that settle it. Name the readers before the schema, decide which distinctions are load-bearing enough to justify bespoke fields, and commit publicly to versioning, written definitions and a projection you keep maintaining.
## The decision is "who reads this", not "which format is better" A result model has two audiences and they pull in opposite directions. **Existing tools** — viewers, history stores, dashboards, review surfaces — already parse a small number of widely-adopted shapes, and emitting one of those buys integration you never write and never maintain. **Your own suite** produces facts those shapes were not designed to carry: a status vocabulary richer than pass and fail, an attempt list, typed attachments hanging off the right node, a case identity independent of the display name. So the real question is never "is a bespoke model better". It is: *how much of what my suite knows is worth the readers I would have to write, and keep writing?* ## What each choice actually costs | | Widely-parsed interchange shape | Bespoke model | |---|---|---| | Readers | Exist already, for free | Every one of them is yours to build | | Expressiveness | Limited to what the shape defines | Exactly your vocabulary | | Schema change | Not yours to make | Needs a version and a migration | | Onboarding | Recognised on sight | A vocabulary documented nowhere else | | Cross-team aggregation | Works by default | Works only if both teams agree first | | Longevity | Outlives your harness | Lives and dies with your harness | The asymmetry that decides most of these arguments: the interchange shape's limits are visible on day one, while the bespoke model's costs arrive in month nine — when the second reader is needed, when a field has to change meaning, and when somebody else's view has to include your suite. ## The answer that is usually right: emit both Treat the rich internal model as the source of truth and the common shape as a **projection** produced at the boundary: 1. The suite writes its full model — statuses, reason codes, attempts, attachment references, stable identities. 2. A projection maps that onto the common shape for everything that already reads it, collapsing what the shape cannot express and putting the lost detail into whatever free-text field the shape offers. 3. The projection is **lossy in one direction only**. Nothing consumes the projection to rebuild the internal model, and no field exists in the projection that the internal model does not already hold. That costs one mapping function and removes the argument entirely. The failure mode to guard against is the mirror image: teams that make the common shape the source of truth and then bolt their extra statuses into its free-text fields, so the real model exists only as a convention inside strings that nothing validates. ## When bespoke-only is genuinely right Conditions that favour it: - You already own the readers, because the output feeds a history store or an internal surface you built and maintain anyway. The marginal cost of one more reader is small; for a team with none, it is the whole cost. - The distinctions are **load-bearing for a decision people make daily**, and collapsing them into the common vocabulary would destroy that decision rather than merely blur it. - The suite's shape is genuinely unusual — long attempt chains, evidence at several levels, results merged from many independent sources. Conditions that argue against it, which teams talk themselves out of too easily: - **Nobody has named a reader yet.** A schema with no consumer is a guess about the future, and the guess is usually wrong in exactly the details that felt most important. - **The suite is one of several** that will eventually be looked at together. Two bespoke vocabularies are worse than one imperfect shared one, because the merge cost lands on whoever comes third. - **Turnover is high enough** that the vocabulary will outlive everyone who remembers why it has six statuses rather than four. ## If you go bespoke, three obligations - **Version the schema** from its first release, and treat a field's *meaning* changing as a version change rather than an edit. Silent meaning changes are the failure that readers cannot detect. - **Write the vocabulary down** beside the model: every status, its definition, and the action it implies. A status set without definitions drifts within two quarters, and the drift is invisible until someone builds a combined view. - **Keep a projection anyway.** The day someone asks for a view spanning teams, the projection is the entire answer; written after the fact it is a migration, written up front it is a function. The summary a lead should be able to give in one sentence: name the readers first, keep the rich model internal, project it outward, and pay for bespoke fields only where a decision depends on them.
- Two teams each built a bespoke result model. What has to happen before a shared view over both is possible?Agree the vocabulary and its meanings first — which statuses exist, what each asserts, what a reader does about it. Then map each model onto one common shape rather than onto each other, so a third team can join later without renegotiating. Building the view before the agreement produces columns that mean different things depending on the row.
- What makes a bespoke result model expensive a year after you adopt it, rather than on the day you write it?Every reader you wrote is now yours to maintain, each field whose meaning changes needs a version and a backfill, and newcomers must learn a vocabulary documented nowhere outside your own repository. On day one there is one producer and one reader; by month nine there are several readers and at least one of them belongs to another team.
saying these in an interview costs you the question
- Designs a bespoke schema before naming a single reader
- Assumes a common shape can express every status
- Smuggles extra statuses into free-text comment fields
- Treats a lossy projection as a defect to fix
- Ships schema changes with no version and no migration