From 5b77bedeb023d5539e9dbe45b3b9fe7a9c6745e0 Mon Sep 17 00:00:00 2001 From: Vadim Zolotokrylin <1125014+zolotokrylin@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:21:20 +0800 Subject: [PATCH 1/6] docs(rules): write a Spec around its objects and key results --- docs/rules/DEV-125.md | 84 ++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/docs/rules/DEV-125.md b/docs/rules/DEV-125.md index 317dfcc..f1d1437 100644 --- a/docs/rules/DEV-125.md +++ b/docs/rules/DEV-125.md @@ -10,8 +10,8 @@ depends_on: ["DEV-180", "DEV-350"] ## Problem A Spec written without a shared structure is hard to read and review: readers -cannot tell where the goal, the overview, or the behavior sections are, and -specs drift into describing internals instead of user behavior. +cannot tell where the objective, the user types, or the behavior sections are, +and specs drift into describing internals instead of user behavior. ## Solution @@ -21,19 +21,25 @@ about what users can do, not how the system works. 1. Store the Spec as a markdown file under `docs/specs/`, linked from its Goal under `# Spec`; its sections graduate to `docs/product/` per [DEV-180](./DEV-180.md). -1. Start with `goal:` frontmatter linking the Goal, then an H1 feature name and - a `## Overview` of what the Goal enables for users. +1. Start with `goal:` frontmatter linking the Goal, then an H1 feature name of + at most 45 characters. +1. State in `## Objective`, in at most 250 characters, the business value, the + user problem it solves, and the definition of success. +1. List exactly three `## Key Results`, each at most 160 characters. 1. List every user type in `## User Types`, including operator and administrator - types that are not the client's end-users. If a type's account is provisioned - outside the product (database seed, manual setup), say so, and say whether - the product can create more of them. -1. Treat the user account as a key concept, not as a separate administration - area: creating, listing, granting access to, and removing accounts are - actions on it like any other. -1. Name the permitted user type in every action. An action with an implicit + types that are not the client's end-users. In at most 150 characters, each + item gives the definition, where the account is provisioned (outside the + product, such as a database seed or manual setup, or within it), and whether + the product can create more of that type. +1. Give each object users interact with its own `##` section, and each function + on that object its own `###` subsection. Treat the user account as an object, + not as a separate administration area: creating, listing, granting access to, + and removing accounts are actions on it like any other. +1. Name the permitted user types in every action. An action with an implicit actor cannot be reviewed against what the product actually allows. -1. Add author-defined `##` sections that describe observable user behavior, not - internal mechanics. +1. Describe observable user behavior, not internal mechanics. +1. Treat the italic `*Constraint*`, `*Description*`, and `*Requirements*` lines + as authoring guidance: remove them once the section is written. 1. Include a `## Design` section using the markup in [DEV-350](./DEV-350.md) when the Goal has a design component. @@ -42,40 +48,52 @@ about what users can do, not how the system works. goal: --- -# Feature Name (max 45 chars) +# [Feature Name] +*Constraint: Maximum 45 characters, including spaces.* ## Objective -(describes business objective, max 250 chars) +*Constraint: Maximum 250 characters, including spaces.* +*Description: Describe the high-level business value, the user problem it solves, and the definition of success.* -## Key results -(three items; max 160 chars each) +## Key Results +*Constraint: Exactly three bullet points. Maximum 160 characters per bullet point.* +- [Key Result 1] +- [Key Result 2] +- [Key Result 3] ## User Types -(list of every user type and its short definition, operators and -administrators included; each item max 150 chars. Note any type whose -account is provisioned outside the product, and whether more can be -created in the product) +*Constraint: Bulleted list. Maximum 150 characters per bullet point.* +*For every user type (including operators and admins), you must explicitly state:* +1. Definition of the role. +2. Where the account is provisioned (e.g., "Provisioned outside the product" or "Created within the product"). +3. Account scalability (e.g., "Can create more in-product" or "Fixed system role"). -## Key Concepts +- **[User Type Name]:** [Definition]. [Provisioning method]. [Scalability]. -(subsections describing key concepts users need to know about; the -relevant methods (actions) each permitted user type can use. Include the -user account itself as a concept, with its create, list, access, and -remove actions. Name the permitted user types in every action) +## [Object Name] +*Description: A core entity or concept the user interacts with (e.g., "User Account", "Invoice", "Project"). Repeat this section for each distinct object.* -## [Section] +### [Function/Feature Name] +*Description: A specific capability or action set tied to the parent object. Repeat this subsection for each feature attributed to the object.* -Describe what users can do, not how the system works internally. +*Requirements:* +- Clearly detail the actions permitted on this object. +- You **must** explicitly name the allowed User Types for every single action or permission described. ``` ### Acceptance Criteria -- [ ] The Spec is a `docs/specs/` file with `goal:` frontmatter, an H1 name, and - a `## Overview` +- [ ] The Spec is a `docs/specs/` file with `goal:` frontmatter and an H1 name + of at most 45 characters +- [ ] `## Objective` states the business value, the user problem, and the + definition of success in at most 250 characters +- [ ] `## Key Results` has exactly three items of at most 160 characters each - [ ] `## User Types` covers every type, operators and administrators included, - states how any externally provisioned account comes into existence, and - says whether the product can create more of that type -- [ ] The user account appears in `## Key Concepts` with its own actions + and each item gives the definition, where the account is provisioned, and + whether the product can create more of that type +- [ ] Each object has its own `##` section with a `###` subsection per function, + and the user account is one of those objects - [ ] Every action names the user types permitted to perform it - [ ] Sections describe user-observable behavior, not internal mechanics +- [ ] No authoring guidance lines remain in the Spec - [ ] A Goal with a design component includes a `## Design` section per DEV-350 From 3aa66af661492a56d9afb3e97f7e656e81e56fdb Mon Sep 17 00:00:00 2001 From: Vadim Zolotokrylin <1125014+zolotokrylin@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:44:53 +0800 Subject: [PATCH 2/6] docs(rules): link shipped behavior instead of restating it in a Spec --- docs/rules/DEV-125.md | 144 ++++++++++++++++++++++++++++-------------- 1 file changed, 96 insertions(+), 48 deletions(-) diff --git a/docs/rules/DEV-125.md b/docs/rules/DEV-125.md index f1d1437..ef0821b 100644 --- a/docs/rules/DEV-125.md +++ b/docs/rules/DEV-125.md @@ -22,24 +22,34 @@ about what users can do, not how the system works. under `# Spec`; its sections graduate to `docs/product/` per [DEV-180](./DEV-180.md). 1. Start with `goal:` frontmatter linking the Goal, then an H1 feature name of - at most 45 characters. -1. State in `## Objective`, in at most 250 characters, the business value, the - user problem it solves, and the definition of success. -1. List exactly three `## Key Results`, each at most 160 characters. -1. List every user type in `## User Types`, including operator and administrator - types that are not the client's end-users. In at most 150 characters, each - item gives the definition, where the account is provisioned (outside the - product, such as a database seed or manual setup, or within it), and whether - the product can create more of that type. -1. Give each object users interact with its own `##` section, and each function - on that object its own `###` subsection. Treat the user account as an object, - not as a separate administration area: creating, listing, granting access to, - and removing accounts are actions on it like any other. -1. Name the permitted user types in every action. An action with an implicit - actor cannot be reviewed against what the product actually allows. + at most 30 characters. Name the feature as a noun phrase, not a sentence. +1. State in `## Objective`, in at most 250 characters, the business value and + the user problem it solves. +1. List exactly three `## Key Results` as a numbered list, each at most 160 + characters. Each is a measurable outcome, and together they define success. +1. Write only what the Goal adds or changes. Where a user type, object, or + capability already ships and the product docs describe it, link that page + instead of restating it. If the product docs do not describe it yet, add it + there in the same PR, then link it. +1. List every user type the Spec's actions name in `## User Types`, including + operator and administrator types that are not the client's end-users. A type + the product docs already define is a link. A new or changed type gets, in at + most 150 characters, its definition and who creates the account: another user + type, the user by signing up, or a process outside the product such as a + database seed or manual setup. For an account created outside the product, + say whether the product can create more. +1. Give each object users interact with its own `##` section, starting with + `## User Account`. Treat the user account as an object, not as a separate + administration area: creating, listing, editing, granting access to, and + removing accounts are actions on it like any other. +1. Give each capability on an object its own `###` subsection, named for what + the user does, such as "Funding an account". +1. Write each action as its own item that starts with the user types permitted + to perform it: `- [User Type], [User Type] can [action].` An action with an + implicit actor cannot be reviewed against what the product actually allows. 1. Describe observable user behavior, not internal mechanics. -1. Treat the italic `*Constraint*`, `*Description*`, and `*Requirements*` lines - as authoring guidance: remove them once the section is written. +1. Keep the template's guidance in HTML comments. They do not render, so a + partly written Spec shows readers only its content. 1. Include a `## Design` section using the markup in [DEV-350](./DEV-350.md) when the Goal has a design component. @@ -49,51 +59,89 @@ goal: --- # [Feature Name] -*Constraint: Maximum 45 characters, including spaces.* + + ## Objective -*Constraint: Maximum 250 characters, including spaces.* -*Description: Describe the high-level business value, the user problem it solves, and the definition of success.* + + + ## Key Results -*Constraint: Exactly three bullet points. Maximum 160 characters per bullet point.* -- [Key Result 1] -- [Key Result 2] -- [Key Result 3] + + + + +1. [Key Result 1] +1. [Key Result 2] +1. [Key Result 3] ## User Types -*Constraint: Bulleted list. Maximum 150 characters per bullet point.* -*For every user type (including operators and admins), you must explicitly state:* -1. Definition of the role. -2. Where the account is provisioned (e.g., "Provisioned outside the product" or "Created within the product"). -3. Account scalability (e.g., "Can create more in-product" or "Fixed system role"). -- **[User Type Name]:** [Definition]. [Provisioning method]. [Scalability]. + + + +- **[User Type]:** Defined in [the product docs](../product/[page].md). +- **[User Type]:** [Definition]. Created by [User Type, or self sign-up]. +- **[User Type]:** [Definition]. Created outside the product by [database seed, manual setup]. The product [can, cannot] create more. + +## User Account + + + +Already shipped: [User Account](../product/[page].md). + +### Creating an account + +- [User Type], [User Type] can create a [User Type] account. + +### Listing accounts + +- [User Type] can list [User Type] accounts. + +### Editing an account + +- [User Type] can edit a [User Type] account's [details]. + +### Granting access + +- [User Type] can grant a [User Type] account access to [Object]. + +### Removing an account + +- [User Type] can remove a [User Type] account. ## [Object Name] -*Description: A core entity or concept the user interacts with (e.g., "User Account", "Invoice", "Project"). Repeat this section for each distinct object.* -### [Function/Feature Name] -*Description: A specific capability or action set tied to the parent object. Repeat this subsection for each feature attributed to the object.* + + +Already shipped: [Object Name](../product/[page].md). + +### [What the User Does] + + + -*Requirements:* -- Clearly detail the actions permitted on this object. -- You **must** explicitly name the allowed User Types for every single action or permission described. +- [User Type], [User Type] can [action]. ``` ### Acceptance Criteria -- [ ] The Spec is a `docs/specs/` file with `goal:` frontmatter and an H1 name - of at most 45 characters -- [ ] `## Objective` states the business value, the user problem, and the - definition of success in at most 250 characters -- [ ] `## Key Results` has exactly three items of at most 160 characters each -- [ ] `## User Types` covers every type, operators and administrators included, - and each item gives the definition, where the account is provisioned, and - whether the product can create more of that type -- [ ] Each object has its own `##` section with a `###` subsection per function, - and the user account is one of those objects -- [ ] Every action names the user types permitted to perform it +- [ ] The Spec is a `docs/specs/` file with `goal:` frontmatter and an H1 noun + phrase of at most 30 characters +- [ ] `## Objective` states the business value and the user problem in at most + 250 characters +- [ ] `## Key Results` is a numbered list of exactly three measurable outcomes + of at most 160 characters each +- [ ] Nothing the product docs already describe is restated; it is linked +- [ ] `## User Types` covers every type the actions name, operators and + administrators included, linking existing types and defining new or + changed ones with who creates the account +- [ ] `## User Account` is the first object section, covering creating, listing, + editing, granting access to, and removing accounts, by content or by link +- [ ] Each object has its own `##` section with a `###` subsection per + capability, named for what the user does +- [ ] Every action is its own item starting with the user types permitted to + perform it - [ ] Sections describe user-observable behavior, not internal mechanics -- [ ] No authoring guidance lines remain in the Spec - [ ] A Goal with a design component includes a `## Design` section per DEV-350 From 7e21870417bb6034c848ef5c159809e2b4815c3d Mon Sep 17 00:00:00 2001 From: Vadim Zolotokrylin <1125014+zolotokrylin@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:48:18 +0800 Subject: [PATCH 3/6] docs(rules): rely on DEV-390 when linking shipped behavior from a Spec --- docs/rules/DEV-125.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/rules/DEV-125.md b/docs/rules/DEV-125.md index ef0821b..dee1952 100644 --- a/docs/rules/DEV-125.md +++ b/docs/rules/DEV-125.md @@ -4,7 +4,7 @@ title: "Write a Spec in the Standard Format" status: "active" enforcement: "manual" severity: "error" -depends_on: ["DEV-180", "DEV-350"] +depends_on: ["DEV-180", "DEV-350", "DEV-390"] --- ## Problem @@ -29,8 +29,9 @@ about what users can do, not how the system works. characters. Each is a measurable outcome, and together they define success. 1. Write only what the Goal adds or changes. Where a user type, object, or capability already ships and the product docs describe it, link that page - instead of restating it. If the product docs do not describe it yet, add it - there in the same PR, then link it. + instead of restating it; [DEV-390](./DEV-390.md) keeps those docs matching + the product. If the product docs do not describe it yet, add it there in the + same PR, then link it. 1. List every user type the Spec's actions name in `## User Types`, including operator and administrator types that are not the client's end-users. A type the product docs already define is a link. A new or changed type gets, in at From b3fb55fd7493f38ce8b803161a0007cf13b04e24 Mon Sep 17 00:00:00 2001 From: Vadim Zolotokrylin <1125014+zolotokrylin@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:52:27 +0800 Subject: [PATCH 4/6] docs(rules): link a Spec's references to their product docs definitions --- docs/rules/DEV-125.md | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/docs/rules/DEV-125.md b/docs/rules/DEV-125.md index dee1952..fddf109 100644 --- a/docs/rules/DEV-125.md +++ b/docs/rules/DEV-125.md @@ -21,24 +21,27 @@ about what users can do, not how the system works. 1. Store the Spec as a markdown file under `docs/specs/`, linked from its Goal under `# Spec`; its sections graduate to `docs/product/` per [DEV-180](./DEV-180.md). +1. Carry only what is new: behavior the Goal adds or changes. Never repeat what + the product docs already carry. Where the Spec refers to something they + define, such as a user type, an object, a capability, or a term, link to its + definition there (the heading that defines it, not just the page) the first + time the Spec names it. [DEV-390](./DEV-390.md) keeps those definitions + matching the product. If the product docs do not define it yet, add the + definition there in the same PR, then link it. 1. Start with `goal:` frontmatter linking the Goal, then an H1 feature name of at most 30 characters. Name the feature as a noun phrase, not a sentence. 1. State in `## Objective`, in at most 250 characters, the business value and the user problem it solves. 1. List exactly three `## Key Results` as a numbered list, each at most 160 characters. Each is a measurable outcome, and together they define success. -1. Write only what the Goal adds or changes. Where a user type, object, or - capability already ships and the product docs describe it, link that page - instead of restating it; [DEV-390](./DEV-390.md) keeps those docs matching - the product. If the product docs do not describe it yet, add it there in the - same PR, then link it. 1. List every user type the Spec's actions name in `## User Types`, including operator and administrator types that are not the client's end-users. A type - the product docs already define is a link. A new or changed type gets, in at - most 150 characters, its definition and who creates the account: another user - type, the user by signing up, or a process outside the product such as a - database seed or manual setup. For an account created outside the product, - say whether the product can create more. + the product docs already define is a link to that definition, with nothing + restated. A new or changed type gets, in at most 150 characters, its + definition and who creates the account: another user type, the user by + signing up, or a process outside the product such as a database seed or + manual setup. For an account created outside the product, say whether the + product can create more. 1. Give each object users interact with its own `##` section, starting with `## User Account`. Treat the user account as an object, not as a separate administration area: creating, listing, editing, granting access to, and @@ -80,17 +83,17 @@ goal: ## User Types - + -- **[User Type]:** Defined in [the product docs](../product/[page].md). +- **[User Type]:** Defined in [the product docs](../product/[page].md#[user-type]). - **[User Type]:** [Definition]. Created by [User Type, or self sign-up]. - **[User Type]:** [Definition]. Created outside the product by [database seed, manual setup]. The product [can, cannot] create more. ## User Account - + -Already shipped: [User Account](../product/[page].md). +Defined in [the product docs](../product/[page].md#user-account). ### Creating an account @@ -114,9 +117,9 @@ Already shipped: [User Account](../product/[page].md). ## [Object Name] - + -Already shipped: [Object Name](../product/[page].md). +Defined in [the product docs](../product/[page].md#[object-name]). ### [What the User Does] @@ -130,11 +133,14 @@ Already shipped: [Object Name](../product/[page].md). - [ ] The Spec is a `docs/specs/` file with `goal:` frontmatter and an H1 noun phrase of at most 30 characters +- [ ] The Spec carries only what the Goal adds or changes, and repeats nothing + the product docs already carry +- [ ] Anything the Spec refers to that the product docs define links to that + definition, not just to its page - [ ] `## Objective` states the business value and the user problem in at most 250 characters - [ ] `## Key Results` is a numbered list of exactly three measurable outcomes of at most 160 characters each -- [ ] Nothing the product docs already describe is restated; it is linked - [ ] `## User Types` covers every type the actions name, operators and administrators included, linking existing types and defining new or changed ones with who creates the account From a03bd02e1c109ac40784d09a92aab4cac044cfc3 Mon Sep 17 00:00:00 2001 From: Vadim Zolotokrylin <1125014+zolotokrylin@users.noreply.github.com> Date: Thu, 17 Sep 2026 16:04:25 +0800 Subject: [PATCH 5/6] docs(rules): name and link what the product docs explain instead of re-explaining it --- docs/rules/DEV-125.md | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/rules/DEV-125.md b/docs/rules/DEV-125.md index fddf109..88578fc 100644 --- a/docs/rules/DEV-125.md +++ b/docs/rules/DEV-125.md @@ -21,13 +21,13 @@ about what users can do, not how the system works. 1. Store the Spec as a markdown file under `docs/specs/`, linked from its Goal under `# Spec`; its sections graduate to `docs/product/` per [DEV-180](./DEV-180.md). -1. Carry only what is new: behavior the Goal adds or changes. Never repeat what - the product docs already carry. Where the Spec refers to something they - define, such as a user type, an object, a capability, or a term, link to its - definition there (the heading that defines it, not just the page) the first - time the Spec names it. [DEV-390](./DEV-390.md) keeps those definitions - matching the product. If the product docs do not define it yet, add the - definition there in the same PR, then link it. +1. Carry only what is new: behavior the Goal adds or changes. Where the product + docs already explain something the Spec refers to, such as a user type, an + object, a capability, or a term, do not explain it again: name it as the + product docs do and link to the section that explains it. + [DEV-390](./DEV-390.md) keeps that section matching the product. The product + docs change only when behavior ships, per [DEV-180](./DEV-180.md), not when + the Spec is written. 1. Start with `goal:` frontmatter linking the Goal, then an H1 feature name of at most 30 characters. Name the feature as a noun phrase, not a sentence. 1. State in `## Objective`, in at most 250 characters, the business value and @@ -36,12 +36,12 @@ about what users can do, not how the system works. characters. Each is a measurable outcome, and together they define success. 1. List every user type the Spec's actions name in `## User Types`, including operator and administrator types that are not the client's end-users. A type - the product docs already define is a link to that definition, with nothing - restated. A new or changed type gets, in at most 150 characters, its - definition and who creates the account: another user type, the user by - signing up, or a process outside the product such as a database seed or - manual setup. For an account created outside the product, say whether the - product can create more. + the product docs already explain is named and linked to that section, with + nothing explained again. A new or changed type gets, in at most 150 + characters, its definition and who creates the account: another user type, + the user by signing up, or a process outside the product such as a database + seed or manual setup. For an account created outside the product, say whether + the product can create more. 1. Give each object users interact with its own `##` section, starting with `## User Account`. Treat the user account as an object, not as a separate administration area: creating, listing, editing, granting access to, and @@ -83,7 +83,7 @@ goal: ## User Types - + - **[User Type]:** Defined in [the product docs](../product/[page].md#[user-type]). - **[User Type]:** [Definition]. Created by [User Type, or self sign-up]. @@ -91,7 +91,7 @@ goal: ## User Account - + Defined in [the product docs](../product/[page].md#user-account). @@ -117,7 +117,7 @@ Defined in [the product docs](../product/[page].md#user-account). ## [Object Name] - + Defined in [the product docs](../product/[page].md#[object-name]). @@ -133,17 +133,17 @@ Defined in [the product docs](../product/[page].md#[object-name]). - [ ] The Spec is a `docs/specs/` file with `goal:` frontmatter and an H1 noun phrase of at most 30 characters -- [ ] The Spec carries only what the Goal adds or changes, and repeats nothing - the product docs already carry -- [ ] Anything the Spec refers to that the product docs define links to that - definition, not just to its page +- [ ] The Spec carries only what the Goal adds or changes +- [ ] Nothing the product docs already explain is explained again; the Spec + names it and links to the section that explains it +- [ ] Writing the Spec adds nothing to the product docs - [ ] `## Objective` states the business value and the user problem in at most 250 characters - [ ] `## Key Results` is a numbered list of exactly three measurable outcomes of at most 160 characters each - [ ] `## User Types` covers every type the actions name, operators and - administrators included, linking existing types and defining new or - changed ones with who creates the account + administrators included, linking types the product docs explain and + defining new or changed ones with who creates the account - [ ] `## User Account` is the first object section, covering creating, listing, editing, granting access to, and removing accounts, by content or by link - [ ] Each object has its own `##` section with a `###` subsection per From 5f0ca0f56df30ccdd2c2410db2d08ad055bcb2b7 Mon Sep 17 00:00:00 2001 From: Vadim Zolotokrylin <1125014+zolotokrylin@users.noreply.github.com> Date: Thu, 17 Sep 2026 16:15:37 +0800 Subject: [PATCH 6/6] docs(rules): check a Spec's Goal link and extra external accounts --- docs/rules/DEV-125.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/rules/DEV-125.md b/docs/rules/DEV-125.md index 88578fc..8ed1c58 100644 --- a/docs/rules/DEV-125.md +++ b/docs/rules/DEV-125.md @@ -131,8 +131,8 @@ Defined in [the product docs](../product/[page].md#[object-name]). ### Acceptance Criteria -- [ ] The Spec is a `docs/specs/` file with `goal:` frontmatter and an H1 noun - phrase of at most 30 characters +- [ ] The Spec is a `docs/specs/` file whose `goal:` frontmatter links its Goal, + with an H1 noun phrase of at most 30 characters - [ ] The Spec carries only what the Goal adds or changes - [ ] Nothing the product docs already explain is explained again; the Spec names it and links to the section that explains it @@ -143,7 +143,8 @@ Defined in [the product docs](../product/[page].md#[object-name]). of at most 160 characters each - [ ] `## User Types` covers every type the actions name, operators and administrators included, linking types the product docs explain and - defining new or changed ones with who creates the account + defining new or changed ones with who creates the account, and, for an + account created outside the product, whether the product can create more - [ ] `## User Account` is the first object section, covering creating, listing, editing, granting access to, and removing accounts, by content or by link - [ ] Each object has its own `##` section with a `###` subsection per