Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion docs/rules/DEV-050.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ id: DEV-050
title: "Keep the Problem Statement Short"
status: "active"
enforcement: "manual"
severity: "warning"
severity: "error"
depends_on: ["DEV-020"]
---

Expand All @@ -19,6 +19,12 @@ single broken thing and stop. Motivation, context, alternatives, and any
restating of the title belong in the Solution, or nowhere. The character cap is
the forcing function: if you are over it, you are explaining, not stating.

This governs every Problem statement, whatever carries it: the `## Problem`
section of a rule file, and the `# Problem` section of a Problem issue written
per [DEV-160](./DEV-160.md). A rule is a Problem too; it is a rule only because
the barrier recurs on the ops side instead of in the product, which does not
change what its statement has to do. One cap, one place.

### Acceptance Criteria

- [ ] The Problem paragraph is 250 characters or fewer
Expand Down
57 changes: 46 additions & 11 deletions docs/rules/DEV-160.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
---
id: DEV-160
title: "Write a Clear Problem Statement"
title: "Write a Problem Issue Stakeholders Can Act On"
status: "active"
enforcement: "manual"
severity: "error"
depends_on: ["DEV-150"]
depends_on: ["DEV-150", "DEV-050"]
---

## Problem

A Problem titled "missing balance API" or "pinned post needs upgrade" tells a
stakeholder nothing about what a user cannot do. Neither names the user or
business outcome being blocked, so neither can be prioritized.
A Problem titled "missing balance API" names no user and no outcome, so it
cannot be prioritized. Its Solution section drifts the same way, arriving as a
list of steps to perform, so a reviewer cannot tell what the business gains when
it merges.

## Solution

Write each Problem so a non-technical stakeholder understands it at a glance. If
you cannot state an inability, there is nothing to file: routine work an
Write each Problem so a non-technical stakeholder understands it at a glance.
The issue carries the pain and the direction. How to execute belongs to the pull
request that resolves it, per [DEV-170](./DEV-170.md).

Both halves fail the same way. A title that names a missing artifact, and a
Solution that lists accounts to provision and READMEs to update, describe steps
performed rather than outcome delivered, which is what [DEV-440](./DEV-440.md)
says not to do. Length is what lets it happen: given room, the inability and the
outcome end up buried under execution detail. The caps below take the room away.

If you cannot state an inability, there is nothing to file: routine work an
experienced person would simply do is process, not a barrier, and belongs in the
work itself.

Expand All @@ -25,10 +35,17 @@ work itself.
of the work, do it instead of filing it.
1. Title it `Problem: [statement]`, under 65 characters.
1. State what the user or business cannot do, in plain terms, not the solution's
technicalities.
technicalities. Keep it within the Problem cap in [DEV-050](./DEV-050.md).
1. Open the `# Solution` section with one sentence naming what the user or
business can do once this merges. Any recommended direction follows that
sentence. Keep the Solution prose to 450 characters or fewer.
1. Open it as a sub-issue of the Goal and link the Goal in the description.
1. Give the body a `# Problem` section and a `# Solution` section describing the
recommended approach before work begins.

Both caps count prose only. Importance, urgency, and priority lines, the
references list, and links do not count against them. They are deliberately
tight: at that length there is no room for implementation steps, which is the
point. Detail that does not fit was never the statement, it was the execution,
and it belongs in the pull request.

```text
Good: Problem: operators can't view their account balance
Expand All @@ -37,17 +54,35 @@ Bad: Problem: CSV export missing (no actor, no action)
Bad: Problem: pinned post needs upgrade (routine work, not a barrier)
```

For the Solution's opening sentence:

```text
Good: The platform stays reachable under attack and our servers cannot be
targeted directly.
Bad: Put both domains behind Cloudflare and accept origin traffic only from
Cloudflare. (a provisioning step, not an outcome)
```

Filing routine work as Problems splits the work into micro-chunks. Each one adds
an issue to track, a notification on every PR that touches it, and a status
nobody updates, while tracking nothing that was ever blocked. Three open issues
asking for a pinned post to be swapped are not three barriers; they are one
unperformed task.

Both caps are machine-checkable, and the Problem cap already is: the rules audit
enforces [DEV-050](./DEV-050.md) on every rule file it checks. On issues the
reviewer checks them, until the bot does.

### Acceptance Criteria

- [ ] The title is `Problem: ...`, under 65 characters
- [ ] It names a barrier that blocks the goal, not routine work a doer would
simply perform
- [ ] It states a user or business inability, not a solution technicality
- [ ] A non-technical stakeholder can understand it
- [ ] The Problem prose is within the cap in [DEV-050](./DEV-050.md)
- [ ] The Solution's first sentence states what the user or business can do once
this merges
- [ ] The Solution prose is 450 characters or fewer
- [ ] A non-technical stakeholder understands both sections without asking a
follow-up
- [ ] It is a sub-issue of the Goal and has a Problem and a Solution section
13 changes: 10 additions & 3 deletions docs/rules/DEV-360.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ depends_on: ["DEV-170"]

## Problem

Work started without a draft PR, or a PR that never links its Problem, is
invisible: no one can see it is underway, and it does not close its Problem when
it merges.
Work with no draft PR, or a PR that never links its Problem, is invisible: no
one sees it is underway, and merging it does not close its Problem. A
description opening with edits performed hides it too: no reviewer can tell what
the business gains.

## Solution

Expand All @@ -24,9 +25,15 @@ track progress and lets the merge close its Problem.
1. Link the PR to its Problem issue with a closing keyword (for example
`Closes #123`), so merging the PR closes the Problem.
1. Assign yourself, so it is clear who owns it.
1. Open the description with one sentence naming what the user or business can
do once this merges, in the same plain terms the Problem uses per
[DEV-160](./DEV-160.md). The changes made follow that sentence, and are the
evidence for it, not a substitute.

### Acceptance Criteria

- [ ] A draft PR is opened at the start of the work
- [ ] It links its Problem issue with a closing keyword
- [ ] The author is assigned to it
- [ ] The description opens with the outcome the merge delivers, not the list of
changes made
2 changes: 1 addition & 1 deletion docs/rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Solution, Spec.
- [DEV-140](./DEV-140.md): give an ETA once the goal is clear
- [DEV-150](./DEV-150.md): map every barrier blocking the goal
- [DEV-155](./DEV-155.md): log a bottleneck as a Problem and design it out
- [DEV-160](./DEV-160.md): write a clear Problem statement
- [DEV-160](./DEV-160.md): write a Problem issue stakeholders can act on
- [DEV-170](./DEV-170.md): deliver work as a pull request
- [DEV-180](./DEV-180.md): keep the Spec as unimplemented behavior and graduate
it
Expand Down
Loading