Test Cases
A test case is the reusable scenario your team runs against the work. Verification plans link test cases as snapshots; results are recorded through one strict path so the audit trail is honest about what was checked, when, and by whom.
A test case is the reusable scenario your team runs against the work. Export 6 months of data at 50,000 rows and verify the CSV format matches the customer spec. Submit the contact form with a 200-character message and confirm the email lands. Sign up as a new customer with a coupon code and verify the discount applies. Each one is a written set of steps with an expected result, a parent initiative it belongs to, and a status the team updates as it gets exercised.
What makes a test case a record rather than a note in a wiki is that it sits inside the work model and connects to the rest of it. A verification plan links the test cases it covers and records results against them; a bug found while exercising a test case carries a typed found-by relation back to it; the record reserves an external ID field so a future sync with Azure DevOps can mirror the test case alongside the rest of the work. The work model treats the test case as a first-class entity, not as a freeform document.
If you are coming from a dedicated test-management tool, this is closer to TestRail or Zephyr than to a Confluence page; the test case is structured data with steps, status, and result history rather than prose. If you are coming from Jira, a test case in Disco Parrot is a Test-type issue with stronger discipline on how its status moves: passing and failing are not statuses you can flip from a status dropdown; they are recorded by exercising the test case from a verification plan. That is the part most teams find unfamiliar at first and useful within a week.
How a test case sits in the work model
A test case lives under an initiative (required), can also point at a plan as an optional secondary parent, carries an inline list of steps, and is linked by the verification plans that cover it. Bugs found while exercising a test case point back through the found-by relation; an external work item can mirror the test case through an integration.
How it looks in practice
Continuing the worked example.
The CSV format verification plan on Sarah's CSV Export initiative links five test cases, one per real customer fixture. The team gathered the fixtures by asking the customer-success team for the export data shapes their largest customers actually generate; each fixture has its own scenario, its own expected CSV output, and its own status that updates as the verifier runs through it.
| Title | Priority | Status | Last result |
|---|---|---|---|
| Customer-impact export at 200k rows | Critical | Passing | 2026-06-12 14:00 (Sarah) |
| Export 6 months of data, 50k rows | High | Passing | 2026-06-12 14:22 (Sarah) |
| Export with archived rows excluded | Medium | Passing | 2026-06-12 14:38 (Sarah) |
| Export across timezone boundaries | High | Failing | 2026-06-13 09:15 (Sarah) |
| Export with multi-byte characters | Medium | Passing | 2026-06-13 09:42 (Sarah) |
| Export with empty result set | Low | Draft | (never run) |
Each test case carries between three and eight steps. The Export 6 months of data, 50k rows test case looks like this.
| # | Action | Expected result |
|---|---|---|
| 1 | Open the reporting page logged in as a Pro-tier customer | Page loads with default filters |
| 2 | Set the date filter to the last 6 months | Filter chip shows the date range |
| 3 | Apply a filter for active rows only | Row count drops to roughly 50,000 |
| 4 | Click Export | A CSV downloads within 8 seconds |
| 5 | Open the downloaded CSV in a spreadsheet | File opens cleanly; column headers match the spec |
| 6 | Spot-check three random rows against the platform | Values match exactly, including null handling |
Now look at how the test cases connect.
Upward. All five test cases live under the CSV Export on the Reporting Page initiative; the CSV format verification plan is their optional secondary parent. On the initiative's Test Cases tab, all five appear as a list. On the plan's Test Cases tab, the verifier sees the linked subset with the per-link snapshot states (the same five test cases, but rendered with their last result for this plan instead of their current global status; the two can differ briefly between recordings).
Sideways through the verification plan. The plan's Test Cases tab is the working surface for the verifier. Each row has a status picker that records a fresh result; picking Passing or Failing writes a new snapshot to both the plan and the test case in one round-trip, with the verifier's user and the timestamp stamped on both records.
Through the bug graph. The Export across timezone boundaries test case failed; the verifier clicked the row's File Bug action, which spawned the Export timeout on large date ranges bug pre-populated with a found-by relation pointing at this test case and a sourceTestCaseId field set to the test case's ID. The relation makes the bug queryable through the graph; the source field makes the origin unambiguous. The bug rolls up to the initiative (required parent) and to the plan (optional parent), and it sits on Sprint 24 alongside the plans the team is shipping in the same window.
Rollups at a glance. On the initiative, the Test Cases tab shows 5 total, 3 passing, 1 failing, 1 draft. On the verification plan, the Test Cases tab shows the same 5 with the per-plan snapshot states; the plan's status guard refuses to move from In progress to Complete while any linked test case sits at Failing or Draft, so the team cannot accidentally close the plan with an open failure.
When you create one
The flow is short.
- Open the parent. Most teams create test cases from the initiative's Test Cases tab; some create them from a verification plan's Test Cases tab. Both surfaces have a New Test Case affordance.
- Enter the title. Required. Keep it short and scenario-shaped: Export 6 months of data, 50k rows is the bar.
- Add steps inline. The Steps editor renders a three-column table (number, action, expected result). Press Enter to add a step after the current one; press Tab from the last step's expected result to add a fresh step at the bottom.
- Save. The test case lands at status Draft.
The status picker on the New Test Case form does not offer Passing or Failing. Neither does the test case's own detail-page status field. Those two statuses are not free to set; they are recorded through a different path described in the next section.
Statuses
Five values. Two are author-facing (Draft and Active), one is terminal-ish (Obsolete), and two are recorded rather than set (Passing and Failing).
| Status | What it means | How it is set |
|---|---|---|
| Draft | Authored, not yet ready to run | Set by the author through the inline picker |
| Active | Ready to be exercised | Set by the author through the inline picker |
| Passing | Last exercise succeeded | Recorded through the result endpoint from a verification plan |
| Failing | Last exercise failed | Recorded through the result endpoint from a verification plan |
| Obsolete | Deprecated; kept for history | Set by the author through the inline picker |
Obsolete and soft-delete
Obsolete is the deprecate but keep status; a test case marked Obsolete stays visible in lists and reports as a record of past work, but the team can read it as a clear signal that the scenario no longer applies. Use this when the test case has historical value worth preserving but should not be exercised in new verification plans.
Soft-delete is the hide entirely path. Open the test case's detail view, click the Delete action in the Danger Zone, confirm. The test case drops out of default lists. The platform preserves the record so the audit trail stays intact; restoring it returns the test case at its previous status with steps and relationships intact, through the platform's restore endpoint. Hard-delete is the irreversible cleanup path; the team reaches for it rarely and the audit log records every hard delete with the actor and the timestamp.
Status is recorded, not set
The most distinctive thing about a test case in Disco Parrot is not the shape of the record. It is the discipline around how its status moves. The Passing and Failing statuses are not values you set from a status dropdown; they are recorded through a dedicated path that knows about the verifier, the verification plan, and the timestamp at once. The discipline is small to live with day to day and pays off the moment you ask a real question of the data.
Why the result endpoint exists
Every other tool in this category lets you flip Passing from a status picker. What you get is a status field that means whatever the last person who clicked thought they were communicating. A quarterly review reading the test cases six weeks later cannot tell who set the status, when, against what build, or with what intent. The record is a label, not a fact.
The result endpoint is the structural fix. To move a test case to Passing or Failing, the verifier opens it from inside a verification plan's Test Cases tab and clicks the inline result control. The platform writes the result through a single dedicated path that requires (and stamps onto the record) three things simultaneously: the verifier's user, the verification plan the recording belongs to, and the timestamp. Setting Passing or Failing through the regular PUT path is rejected with a clear use the result endpoint error. There is no second way to get a test case to Passing.
The constraint feels like friction for the first few minutes and then disappears. What stays is the property that every Passing recording on every test case in the workspace carries a verifier, a plan, and a timestamp on the record. The audit trail is real.
What the audit trail can answer
The discipline pays off when you ask questions a sloppy status field cannot answer. When was this test case last exercised under any plan? Under this plan specifically? Who is the most-frequent verifier on this initiative? Which test cases have never been recorded under any verification plan? Which test cases moved from Passing to Failing between Sprint 23 and Sprint 24 (and against which plans)? None of these require a dashboard project; the result endpoint records the data at write time, and the audit log lets you read the answers months later.
A quarter-end review reading the CSV format verification plan can see, in order: every test case the plan covered, the last-recorded status for each, the verifier who recorded it, the date and time of the recording. The plan is a real record of work done by people, not a status field someone touched and forgot.
The dual gate that protects the recording
The result endpoint is gated by both test-cases.manage and plans.manage. The verifier has to have real authority over both the test case they are exercising and the plan they are recording against, on the same call. This is what keeps a stray contractor with one of the scopes but not the other from flipping the team's test cases green from the URL bar; the dual gate makes the recording a genuine action, not a sneaky write.
The result endpoint also carries three wire-level guards beyond the dual scope check. A soft-deleted test case returns 410 (so the verifier cannot quietly resurrect a deleted record by recording against it). A test case not linked to the calling plan returns 404 (so the verifier cannot record against a test case the plan does not actually cover). And a test case that has been reparented to a different initiative since the plan linked it returns 409 with an unlink-and-relink instruction (so the verifier knows the plan's coverage has drifted before they record). The four guards together are what make the recording trustworthy as a record of what happened.
Snapshot isolation per verification plan
A test case linked by two verification plans keeps two independent snapshots, one per plan. If verification plan A records Passing and verification plan B has not yet been exercised, the test case's current status reads Passing (the most-recent recording across any plan), but plan B's snapshot still reads its baseline (its own state has not moved). The next time plan B's verifier records a result, only plan B's snapshot changes; plan A's snapshot stays frozen until plan A's verifier records again.
The concrete shape: Sarah's CSV format verification plan in Sprint 24 records all five linked test cases as Passing on June 12. Six months later, the team runs a second verification plan covering the same five test cases for a regression check on the year-end release. The Sprint 24 plan's snapshots are still readable as they were on June 12, regardless of what the regression plan records in December. The test case's own current status field reads the most-recent recording across both plans (a latest-known convenience), but the per-plan snapshots are the trustworthy facts.
This is what makes a verification plan stand up as an honest record. What Sarah's verifier saw on June 12 and what the December verifier saw on December 18 are both real, separately preserved facts about the same test cases.
The drift indicator on a verification plan
When the test case's current global status diverges from a verification plan's snapshot (because a different plan recorded a fresh result since this plan last recorded one), the row on this plan's Test Cases tab carries a small drift indicator. The badge shows both states side by side with a tooltip explaining the drift: this plan's snapshot is Passing as of June 12; the test case's current status is Failing as of December 18, recorded against the year-end regression plan. The verifier can read at a glance whether the snapshot they are looking at is still aligned with the test case's most recent reality.
The drift indicator is the visual consequence of snapshot isolation. A team running multiple verification plans against overlapping test cases reads the drift badge as a prompt: do we need to re-exercise this test case under this plan? If the failure on the other plan was unrelated to this plan's coverage, the team can leave the snapshot frozen and the drift simply documents the state. If the failure matters here too, the team re-exercises and the drift clears the next time the recording lands.
The steps editor
Steps are a structured inline list on the test case, not a markdown body. Each step has a number (auto-renumbered as you reorder), an action (what the tester does), and an optional expected result (what should happen).
The editor is shaped for keyboard-driven authoring. Tab from the last expected result adds a new step. Enter inside a step adds a step after it. The arrow keys reorder rows. A row can be deleted with the inline delete control; the platform renumbers the rest.
File a bug from a step
When a step fails, the verifier highlights the row and clicks File Bug. The bug-create form opens with the specific step ID pre-filled as the sourceStepId and the relation row pre-filled as { type: "affects-step", targetType: "step", targetId: stepId, targetLabel: "Step N" }. The verifier adjusts the title and saves.
Filing a bug from the test case as a whole (the File Bug button in the page header) is the parallel path: the bug gets the test case ID stamped as sourceTestCaseId and a { type: "found-by", targetType: "test-case", targetId: testCaseId } relation row. The two paths give the team a graph rich enough to ask which step of which test case has spawned the most bugs, or which test cases overall have surfaced the most issues, without writing a dashboard. The grid filter is the dashboard.
Linking test cases to verification plans
A verification plan carries an array of linked test case snapshots. Each snapshot records the test case ID, the test case's status as of the link time (so the plan starts with a known baseline), and the timestamp.
How linking works
Open the verification plan, click into the Test Cases tab, click Link a Test Case, pick from the list of test cases scoped to the same initiative. The link writes a snapshot entry on the plan; the test case itself is not modified at link time.
The picker only shows test cases that share the plan's initiative, and it excludes both Obsolete and soft-deleted test cases (so a verifier cannot link a deprecated or trashed scenario into a fresh release). The platform also refuses to link a test case from a different initiative on the API; the cross-initiative gate keeps verification plans honest as a record of what they cover for their initiative's work.
If you submit the same test case ID twice in the same link request (a stray double-click, a script bug), the platform dedupes server-side and only stores one snapshot entry. Existing linked entries are preserved as they were; only the new IDs in the request get fresh snapshots.
What happens when a test case is reparented
A test case can be reparented to a different initiative through its detail view (a rare move; usually a test case stays under its original initiative). If a verification plan had linked the test case before the reparent, the link is now cross-initiative, and the platform refuses to let the plan record a fresh result against that test case. The result endpoint returns 409 test case has been reparented; unlink and relink before recording a result.
The verifier unlinks the test case (the old snapshot stays in history; the team can read it), then re-links the test case if the new initiative is the same plan's parent, or removes the link entirely if the test case has moved away. The discipline prevents a verification plan from silently recording results against a test case that no longer belongs to the initiative the plan covers.
The completion guard on verification plans
A verification plan refuses to move to Complete while any linked test case sits at a status other than Passing or Obsolete. Draft, Active, and Failing all trigger the guard. The platform prompts for confirmation with a clear N test cases are still draft, active, or failing message that lists the offending links. The team can override and complete the plan anyway (some teams ship with known-failing tests they have triaged into bugs), but the choice is explicit and stamped on the audit log.
The guard is the verification plan's equivalent of all tests green before merge. Obsolete counts as a clean exit because the team has explicitly retired the scenario; Draft and Active count as not-yet-finished because the team has not exercised the test case under this plan. The shape is what makes the completion gate honest: an unrecorded test case is not the same as a passing one, and the guard refuses to let the team accidentally collapse the distinction.
How a quality team works with test cases day to day
A team running test cases on the platform settles into a rhythm within a sprint or two. At the start of a release window, the verifier reads the linked test cases on the verification plan as a coverage list: are there gaps for the scenarios real customers run? If the suite is thin, the verifier writes the missing test cases first, links them to the plan, and only then starts exercising. The discipline of writing missing scenarios before recording any results is what keeps a verification plan honest as a record of what the team checked rather than what the team had time to check.
Through the sprint, the verifier exercises the linked test cases in order, recording Passing or Failing as each one is run. Failures spawn bugs through the inline File Bug control; the bug is real work, not a tracking row, and it lands on the sprint backlog alongside the implementation plans. The verifier's read on their own work is the verification plan's Test Cases tab: rows green, coral, gray at a glance, with the Last recorded timestamp showing the cadence. At sprint end, the verification plan either passes the completion guard (every linked test case Passing or Obsolete) or the team makes an explicit override call with the offending links listed; both paths are stamped on the audit log.
The Test Cases tab on the verifier's verification plan is the working surface for the entire window. The grid is keyboard-navigable; the recording picker is one click; the inline drift indicator (when a test case was recorded under a different plan in between) tells the verifier whether they are looking at a stale state. A team that has been running this loop for a quarter develops a real intuition for how long the verification window takes, which is the number a quality lead can plan against for the next release.
Reading the test-case graph for engineering analytics
The structured relations between test cases, verification plans, and bugs add up to a real graph the team can query through the grid without writing a dashboard project. Which test cases under the CSV Export initiative have spawned the most bugs? Filter the bug grid on sourceTestCaseId populated, group by source test case, sort by count. Which test cases have never been exercised under any verification plan? Filter test cases on Last recorded: never. Which steps are the failure-prone steps across the whole quarter? Filter bugs on sourceStepId populated, group by step, sort by count.
The graph reads cleanly because the data was recorded honestly at write time. A team accustomed to running quality analytics out of a separate BI tool (or worse, a hand-maintained spreadsheet) finds the platform's grid filters cover the questions they were running monthly reports on. The platform's posture is to ship the structured graph, not a fleet of pre-built quality dashboards; the team's questions are answerable from the grid because the recording discipline put the right data in the right place at the right time.
The quality lead's quarterly read often looks like this: which initiatives shipped with verification plans, and which shipped without? (filter plans on type=verification, group by initiative, sort by sprint); what fraction of the bugs filed this quarter came from verification activity? (filter bugs on source=test-execution, count); which test cases have we never exercised in a real verification window? (filter test cases on last-recorded empty). All three are one filter away because the recording discipline persists the right shape.
What stays out of test cases
A test case is not the right home for every check the team wants to run. Three boundaries are worth stating clearly.
One-shot sanity checks belong in the plan body, not in a test case. Confirm the migration ran cleanly in the body of an infrastructure plan is fine; promoting it to a reusable test case adds a row to the catalog that no future verification plan will ever link. The reuse line is what earns a test case its keep; a check that runs once and never again is plan-body shape.
Engineering unit tests stay in the repository, not in the test-case catalog. A pytest or vitest assertion is part of the implementation, runs on every commit, and is the engineer's instrument. A platform test case is the verifier's instrument: it covers a customer-shaped scenario that the team exercises against a release window, not an internal invariant. The two coexist; the platform handles the customer-shaped one and the repository handles the implementation-shaped one.
Exploratory testing does not need a test case at all. A verifier given two hours to poke at the new feature before release files bugs directly as they find them; the bugs carry their own typed relations and the audit trail captures the session. Wrapping exploratory work into a test case after the fact is paperwork; the platform does not ask for it and the team should not pretend to. A team that wants the discipline of we ran exploratory testing this release tracks it on the verification plan body as a one-shot check.
Authoring test cases well
A test case is small to author once you know the shape. The keyboard flow lets a team write a 30-test-case suite for a launch in a single sitting; the action + expected-result split is what makes the bugs that fall out useful months later.
The action + expected-result split
Every step has two columns. The action is what the tester does. The expected result is what should happen. The split makes failures specific: a verifier can record exactly which step broke and what the actual behavior was, because the action and the expected result are separable rather than collapsed into one prose line. Click Export, the CSV downloads within 8 seconds hides the failure mode (is the click broken? does the download time out? both?); split into Click Export and A CSV downloads within 8 seconds and the verifier can tell you which line broke. The bug filed from the right line carries the right affects-step relation. The graph stays honest.
When to split a step
If the expected result has an and in it, split. Click Save and the row appears in the table and a toast confirms is three checks pretending to be one. The verifier with three real checks files a bug against the specific check that failed; the verifier with one composite check files a vague Save broken bug that someone has to triage. Splitting at authoring time saves the triage owner real work later.
Keyboard authoring
The Steps editor is keyboard-first by design. Tab from the last expected result adds a fresh step at the bottom. Enter inside a step adds a step after it. The arrow keys reorder rows. Delete (or the inline delete control) removes a row; the platform renumbers the rest. A team writing a launch suite at 9am with coffee in hand stays in the keyboard the entire time. The discipline matters because the suite that takes 90 minutes to author by mouse takes 25 minutes by keyboard; the same author who would not survive the mouse path can finish the keyboard one before the standup.
Test case, verification plan, or verification step in the plan body
A common question at the boundary: when you want to verify something, where does the check go? The answer is usually obvious once the team learns the three shapes.
Use a test case when the scenario is reusable, has a clear pass/fail outcome, and the team will want to re-exercise it across releases or against multiple verification plans. Export 6 months of data, 50,000 rows is a test case because it will get exercised against the v1 launch, against the regression check three months later, against the year-end release. The reusability is the test of whether the check belongs as a test case.
Use a verification plan when you are gathering a batch of test cases against a specific release window. The plan is the record of what was checked, when, by whom for that window; it links a set of test cases and records snapshots against them. CSV format verification is a verification plan because it is one batch of checks for one release. The plan ships when the release ships, and its snapshots stay as the historical record.
Use a verification step in the plan body when the check is one-shot, specific to this plan, and not worth promoting to a reusable test case. Confirm the API returns 200 with the new field set in the body of an implementation plan is fine; it covers this plan's work and no other. If the check matters for every future release, lift it out of the body and create it as a test case under the initiative; the next verification plan can link it.
The deeper tradeoff between the three shapes is durability versus speed. A test case is the most durable; it earns its keep across releases and shows up in the analytics graph months later. A verification step in the plan body is the fastest to write and the most disposable; the plan ships and the check disappears with it. A verification plan sits in between; it covers one release window with real recorded snapshots that survive the release. A team that defaults to test cases gets the analytics depth; a team that defaults to plan-body steps moves faster but trades the analytics graph away. Most healthy teams land at roughly a 60/30/10 split between the three shapes (reusable scenarios as test cases, per-release batches as verification plans, one-shots as plan-body steps); the team's own ratio is a useful read on whether they are over-rotating in one direction.
Migrating from a spreadsheet, TestRail, or Jira test issues
Most teams arriving at the platform have an existing test-case catalog living somewhere. The migration is a one-time engineering exercise; the platform's create API accepts test cases one at a time, and a small script that walks a source list and posts each row is the canonical path. The discipline of the migration is in the mapping, not in the mechanics.
From a spreadsheet
A Google Sheet with one row per test case is the most common starting point. The columns usually map cleanly: title, priority, status, steps (often in a single body column the team can split out). Map each spreadsheet row to a POST /initiatives/:initiativeId/test-cases call against the right initiative; the steps land as the structured TestStep array. Set the imported status to Draft regardless of what the sheet says; the team re-exercises under verification plans rather than trusting the sheet's hand-maintained status, which is the conservative move. The first time a bug filed against an imported test case carries the found-by relation back to the row, the team understands the upgrade.
From TestRail or Zephyr
The shape is the same as the spreadsheet path; both tools export to CSV with comparable columns. The migration script reads the CSV, creates each test case through the API, and writes the structured TestStep array from the source rows. The history in TestRail (per-cycle run results) does not come across; the platform's per-plan snapshot is the equivalent shape, and the team starts fresh against the next verification plan. This is the conservative move, not a loss: the test cases earn their status under the next verification plan rather than inheriting an unaudited status from a tool the team is leaving behind.
From Jira test issues
A Test-type issue with a structured Steps custom field maps cleanly. A Jira test that holds steps in the description body needs a one-time cleanup pass to extract the structured shape; the cleanup is well worth the effort, because the unstructured body never made the failures specific anyway. A team with 200 Jira test issues usually migrates the active ones (status Active or recently Passing) and archives the rest in Jira as a frozen record.
From "we have not been writing test cases yet"
A team adopting test cases for the first time is the harder migration. There is no source catalog to import; the team writes scenarios from scratch. The right first move is to read the bug grid filtered to the last quarter, group by initiative, and write a single test case per recurring scenario. The bugs are the team's existing record of where the product breaks for customers; the test cases that come out of them are the team's first credible coverage layer. After one quarter of this practice the test-case catalog reflects the actual shape of customer impact, not the theoretical shape from a planning doc.
How the agent works with test cases
Test cases are author-led on purpose. The team's domain knowledge of what real customers do is the input the agent does not have, and the test cases the team writes are how the agent learns what to verify. When the agent runs against an initiative or a verification plan, the test cases materialize into the sandbox alongside the rest of the initiative's work, and the agent grounds its work against them: a flow running against a verification plan reads the linked test cases as the contract for what success looks like; a chat session about the work can reference specific test cases by ID and reason about which scenarios are covered and which still need coverage.
Bugs filed from the test case detail view or from a specific step are real bug records authored by the verifier. The platform stamps the source field as manual and the bug shows up on the bug list with the verifier as the reporter, the test case (or step) pre-populated through the relation graph and the source-ID fields. The audit trail keeps the human as the author of the work; the agent enriches the context but does not take the byline.
The detail page
A test case has a focused detail page. Three sections:
- General holds the title, the description (free text), the priority picker (Critical, High, Medium, Low), and the external ID (a read-only display when the test case is mirrored to an external system; the field is set by integrations, not by hand).
- Steps is the inline editor described above, plus the per-row File Bug affordance.
- Danger Zone is the soft-delete control.
Every change you make on the detail page autosaves after a short delay; there is no explicit Save button. The page header carries the All Test Cases back link and the File Bug affordance for the test case as a whole. There is no inline Passing / Failing picker on the page; the status field is read-only and the work of recording results happens from a verification plan.
The list
There are two places test cases show up as a list.
The initiative Test Cases tab is the per-initiative canonical surface. Every test case under the initiative shows up here, with sort and filter affordances and inline-create at the top.
The plan Test Cases tab (on verification plans) shows the linked subset, with the per-link snapshot states rendered. This is the working surface for the verifier.
Test cases are always scoped to a parent (initiative or plan) by design; the verifier reads them in the context of the work they apply to, not as a workspace-wide pile. The scoping is what keeps the lists short and the filter affordances directly useful. A cross-initiative read is available through the audit log when a leader needs one.
Permissions
Two scopes govern test cases.
test-cases.readlets a person list and view test cases anywhere they appear.test-cases.managelets a person create, edit, delete, restore, and reorder test cases.
The result endpoint (the one that records Passing / Failing) gates on both test-cases.manage and plans.manage. This is the dual gate that makes recording a result a real action: the actor has to have authority over both records they are touching, the test case and the plan, before the result lands.