From 71ee262f73323154e1feb41f269667e715312ed9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 31 Oct 2026 17:04:36 +0100 Subject: [PATCH 1/6] Add feature intake routing and form structure checks --- tests/FeatureIntake.Tests.ps1 | 122 ++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 tests/FeatureIntake.Tests.ps1 diff --git a/tests/FeatureIntake.Tests.ps1 b/tests/FeatureIntake.Tests.ps1 new file mode 100644 index 0000000..9c63b9c --- /dev/null +++ b/tests/FeatureIntake.Tests.ps1 @@ -0,0 +1,122 @@ +#Requires -Version 7.4 +#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '6.1.0'; MaximumVersion = '6.*' } +#Requires -Modules @{ ModuleName = 'powershell-yaml'; ModuleVersion = '0.4.12' } + +<# + .SYNOPSIS + Check the organization-owned feature intake contract. + + .DESCRIPTION + Verify GitHub issue-form structure, submission usability, and preserved routing. + + .EXAMPLE + Invoke-Pester -Path .\tests\FeatureIntake.Tests.ps1 -Output Detailed -CI + + .LINK + https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms +#> +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', '', + Justification = 'Pester setup variables are read in separate test blocks.' +)] +[CmdletBinding()] +param() + +$ErrorActionPreference = 'Stop' + +BeforeAll { + $repositoryRoot = [System.IO.Path]::GetFullPath((Join-Path -Path $PSScriptRoot -ChildPath '..')) + $formPath = Join-Path -Path $repositoryRoot -ChildPath '.github\ISSUE_TEMPLATE\10-feature.yml' + $configPath = Join-Path -Path $repositoryRoot -ChildPath '.github\ISSUE_TEMPLATE\config.yml' + $form = ConvertFrom-Yaml -Yaml ([System.IO.File]::ReadAllText($formPath)) + $configuration = ConvertFrom-Yaml -Yaml ([System.IO.File]::ReadAllText($configPath)) + $introduction = $form.body[0] + $response = $form.body[1] +} + +Describe 'Feature intake GitHub form structure' { + It 'uses only the existing supported top-level keys' { + $form | Should -BeOfType ([System.Collections.IDictionary]) + @($form.Keys) | Should -HaveCount 5 + @($form.Keys | Where-Object -FilterScript { + $_ -notin @('name', 'description', 'title', 'labels', 'body') + }) | Should -HaveCount 0 + } + + It 'provides nonempty strings for the template chooser and title' { + foreach ($value in @($form.name, $form.description, $form.title)) { + $value | Should -BeOfType ([string]) + [string]::IsNullOrWhiteSpace($value) | Should -BeFalse + } + } + + It 'keeps introductory Markdown followed by one textarea' { + ($form.body -is [System.Collections.IList]) | Should -BeTrue + $form.body | Should -HaveCount 2 + $introduction.type | Should -BeExactly 'markdown' + $response.type | Should -BeExactly 'textarea' + } + + It 'uses the documented Markdown element keys' { + @($introduction.Keys | Sort-Object) | Should -Be @('attributes', 'type') + @($introduction.attributes.Keys) | Should -Be @('value') + $introduction.attributes.value | Should -BeOfType ([string]) + [string]::IsNullOrWhiteSpace($introduction.attributes.value) | Should -BeFalse + } + + It 'uses the documented textarea element keys' { + @($response.Keys | Sort-Object) | Should -Be @('attributes', 'id', 'type', 'validations') + @($response.attributes.Keys | Where-Object -FilterScript { + $_ -notin @('label', 'description', 'placeholder') + }) | Should -HaveCount 0 + foreach ($value in @($response.attributes.label, $response.attributes.description)) { + $value | Should -BeOfType ([string]) + [string]::IsNullOrWhiteSpace($value) | Should -BeFalse + } + } + + It 'keeps the existing valid and unique URL-prefill field ID' { + $response.id | Should -BeExactly 'description' + $response.id | Should -Match '^[a-zA-Z0-9_-]+$' + @($form.body | Where-Object -FilterScript { $_.id }) | Should -HaveCount 1 + } + + It 'requires a real response without adding submission constraints' { + @($response.validations.Keys) | Should -Be @('required') + $response.validations.required | Should -BeOfType ([bool]) + $response.validations.required | Should -BeTrue + $response.attributes.ContainsKey('value') | Should -BeFalse + $response.attributes.ContainsKey('render') | Should -BeFalse + } +} + +Describe 'Feature intake preserved routing' { + It 'preserves the feature template name' { + $form.name | Should -BeExactly ([char]::ConvertFromUtf32(0x1F680) + ' [Feature]') + } + + It 'preserves the feature template chooser description' { + $form.description | Should -BeExactly 'Suggest/request a new feature' + } + + It 'preserves the existing title prefix' { + $form.title | Should -BeExactly ([char]::ConvertFromUtf32(0x1F680) + '[Feature]: ') + } + + It 'preserves only the feature and triage labels in their existing order' { + ($form.labels -is [System.Collections.IList]) | Should -BeTrue + $form.labels | Should -Be @('feature', 'triage') + } + + It 'does not assign an internal native type, assignee, or project to feedback' { + foreach ($key in @('type', 'assignees', 'projects')) { + $form.ContainsKey($key) | Should -BeFalse + } + } + + It 'leaves blank issue intake enabled' { + @($configuration.Keys) | Should -Be @('blank_issues_enabled') + $configuration.blank_issues_enabled | Should -BeOfType ([bool]) + $configuration.blank_issues_enabled | Should -BeTrue + } +} From bd2ec03b49e5f2b32367db2baecd50dd3daa6eb8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 31 Oct 2026 17:10:09 +0100 Subject: [PATCH 2/6] Specify consumer feature request expectations --- tests/FeatureIntake.Tests.ps1 | 73 ++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/tests/FeatureIntake.Tests.ps1 b/tests/FeatureIntake.Tests.ps1 index 9c63b9c..2092e57 100644 --- a/tests/FeatureIntake.Tests.ps1 +++ b/tests/FeatureIntake.Tests.ps1 @@ -7,7 +7,7 @@ Check the organization-owned feature intake contract. .DESCRIPTION - Verify GitHub issue-form structure, submission usability, and preserved routing. + Verify consumer prompts, GitHub issue-form structure, submission usability, and preserved routing. .EXAMPLE Invoke-Pester -Path .\tests\FeatureIntake.Tests.ps1 -Output Detailed -CI @@ -39,8 +39,8 @@ Describe 'Feature intake GitHub form structure' { $form | Should -BeOfType ([System.Collections.IDictionary]) @($form.Keys) | Should -HaveCount 5 @($form.Keys | Where-Object -FilterScript { - $_ -notin @('name', 'description', 'title', 'labels', 'body') - }) | Should -HaveCount 0 + $_ -notin @('name', 'description', 'title', 'labels', 'body') + }) | Should -HaveCount 0 } It 'provides nonempty strings for the template chooser and title' { @@ -67,8 +67,8 @@ Describe 'Feature intake GitHub form structure' { It 'uses the documented textarea element keys' { @($response.Keys | Sort-Object) | Should -Be @('attributes', 'id', 'type', 'validations') @($response.attributes.Keys | Where-Object -FilterScript { - $_ -notin @('label', 'description', 'placeholder') - }) | Should -HaveCount 0 + $_ -notin @('label', 'description', 'placeholder') + }) | Should -HaveCount 0 foreach ($value in @($response.attributes.label, $response.attributes.description)) { $value | Should -BeOfType ([string]) [string]::IsNullOrWhiteSpace($value) | Should -BeFalse @@ -120,3 +120,66 @@ Describe 'Feature intake preserved routing' { $configuration.blank_issues_enabled | Should -BeTrue } } + +Describe 'Feature intake consumer expectations' -Tag 'ConsumerExpectations' { + It 'labels the response as consumer need and expected behavior' { + $response.attributes.label | Should -BeExactly 'Consumer need and expected behavior' + } + + It 'asks what the contributor wants to do and who benefits' { + ($response.attributes.description -split '\r?\n')[0] | + Should -BeExactly 'What are you trying to do, and who would benefit?' + } + + It 'asks why the need matters and what is difficult or missing' { + ($response.attributes.description -split '\r?\n')[1] | + Should -BeExactly 'Why does it matter, and what is difficult or missing today?' + } + + It 'asks for expected behavior in a real situation' { + ($response.attributes.description -split '\r?\n')[2] | + Should -BeExactly 'In a real situation, what would you do and expect to happen?' + } + + It 'offers optional ordinary-language starters instead of a prefilled answer' { + $response.attributes.placeholder | Should -Not -BeNullOrEmpty + ($response.attributes.placeholder.TrimEnd() -split '\r?\n') | Should -Be @( + 'I need to ...' + 'This matters because ...' + 'When I ..., I expect ...' + ) + } + + It 'does not solicit implementation choices or prescribe Gherkin syntax' { + (@( + $introduction.attributes.value + $response.attributes.description + $response.attributes.placeholder + ) -join ' ') | + Should -Not -Match '\b(implement(?:ed|ation)?|architecture|Gherkin|Given|Then)\b' + $response.attributes.description | + Should -Not -Match 'Are there alternatives you.ve considered\?' + } + + It 'invites the contributor to use their own words without a technical plan' { + $introduction.attributes.value | + Should -Match 'in your own words\.\s+No technical plan is needed\.' + } + + It 'keeps feedback review and routing with maintainers' { + $introduction.attributes.value | + Should -Match 'Maintainers will review your feedback and decide how to route it\.' + } + + It 'links the canonical MSX issue guidance' { + $introduction.attributes.value | Should -Match '\[MSX issue guidance\]\[issues\]' + $introduction.attributes.value | + Should -Match '(?m)^\[issues\]: https://msx\.no/docs/Ways-of-Working/Issues/\r?$' + } + + It 'links the canonical MSX planning guidance' { + $introduction.attributes.value | Should -Match '\[planning guidance\]\[planning\]' + $introduction.attributes.value | + Should -Match '(?m)^\[planning\]: https://msx\.no/docs/Ways-of-Working/Issues/Process/Planning/\r?$' + } +} From a747f719e55056056ab4053e423643c031bf9028 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 31 Oct 2026 17:12:54 +0100 Subject: [PATCH 3/6] Ask feature contributors for needs and expected behavior --- .github/ISSUE_TEMPLATE/10-feature.yml | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/10-feature.yml b/.github/ISSUE_TEMPLATE/10-feature.yml index fe3cf02..4239150 100644 --- a/.github/ISSUE_TEMPLATE/10-feature.yml +++ b/.github/ISSUE_TEMPLATE/10-feature.yml @@ -1,5 +1,6 @@ # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema +--- name: 🚀 [Feature] description: Suggest/request a new feature title: '🚀[Feature]: ' @@ -8,14 +9,26 @@ body: - type: markdown attributes: value: | - Thank you for suggesting a new feature. Please provide as much information as possible so we can understand your request better. + Thank you for suggesting a feature. Tell us about your need and + the result you expect in your own words. No technical plan is needed. + Maintainers will review your feedback and decide how to route it. + + See the [MSX issue guidance][issues] and + [planning guidance][planning] for how feedback becomes planned work. + + [issues]: https://msx.no/docs/Ways-of-Working/Issues/ + [planning]: https://msx.no/docs/Ways-of-Working/Issues/Process/Planning/ - type: textarea id: description attributes: - label: Description + label: Consumer need and expected behavior description: | - Please describe your idea/request - Feel free to add suggestions how you would like to see this implemented. - Are there alternatives you've considered? + What are you trying to do, and who would benefit? + Why does it matter, and what is difficult or missing today? + In a real situation, what would you do and expect to happen? + placeholder: | + I need to ... + This matters because ... + When I ..., I expect ... validations: required: true From 54b07712718d5f61e14d633e5de29ff8184659cf Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 4 Nov 2026 12:17:44 +0100 Subject: [PATCH 4/6] Start feature requests with current situation and user value --- .github/ISSUE_TEMPLATE/10-feature.yml | 18 +++++++++------ tests/FeatureIntake.Tests.ps1 | 33 +++++++++++++++++++-------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/10-feature.yml b/.github/ISSUE_TEMPLATE/10-feature.yml index 4239150..8fb4a88 100644 --- a/.github/ISSUE_TEMPLATE/10-feature.yml +++ b/.github/ISSUE_TEMPLATE/10-feature.yml @@ -9,8 +9,10 @@ body: - type: markdown attributes: value: | - Thank you for suggesting a feature. Tell us about your need and - the result you expect in your own words. No technical plan is needed. + Thank you for suggesting a feature. Start with how things work today. + Then explain why a change would help the user and what should change. + Describe the result you expect in your own words. + No technical plan is needed. Maintainers will review your feedback and decide how to route it. See the [MSX issue guidance][issues] and @@ -21,14 +23,16 @@ body: - type: textarea id: description attributes: - label: Consumer need and expected behavior + label: Current situation and desired change description: | - What are you trying to do, and who would benefit? - Why does it matter, and what is difficult or missing today? + How do things work today, and what is difficult or missing? + Who would benefit from a change, and why would it be valuable? + What additional need or change would you like to see? In a real situation, what would you do and expect to happen? placeholder: | - I need to ... - This matters because ... + Today, ... + This would help ... because ... + I would like to ... When I ..., I expect ... validations: required: true diff --git a/tests/FeatureIntake.Tests.ps1 b/tests/FeatureIntake.Tests.ps1 index 2092e57..26275f2 100644 --- a/tests/FeatureIntake.Tests.ps1 +++ b/tests/FeatureIntake.Tests.ps1 @@ -122,41 +122,54 @@ Describe 'Feature intake preserved routing' { } Describe 'Feature intake consumer expectations' -Tag 'ConsumerExpectations' { - It 'labels the response as consumer need and expected behavior' { - $response.attributes.label | Should -BeExactly 'Consumer need and expected behavior' + It 'labels the response as current situation and desired change' { + $response.attributes.label | Should -BeExactly 'Current situation and desired change' } - It 'asks what the contributor wants to do and who benefits' { + It 'starts with how things work today and what is difficult or missing' { ($response.attributes.description -split '\r?\n')[0] | - Should -BeExactly 'What are you trying to do, and who would benefit?' + Should -BeExactly 'How do things work today, and what is difficult or missing?' } - It 'asks why the need matters and what is difficult or missing' { + It 'establishes user value before asking for the desired change' { ($response.attributes.description -split '\r?\n')[1] | - Should -BeExactly 'Why does it matter, and what is difficult or missing today?' + Should -BeExactly 'Who would benefit from a change, and why would it be valuable?' } - It 'asks for expected behavior in a real situation' { + It 'asks for the additional need or desired change after its value' { ($response.attributes.description -split '\r?\n')[2] | + Should -BeExactly 'What additional need or change would you like to see?' + } + + It 'asks for expected behavior in a real situation' { + ($response.attributes.description -split '\r?\n')[3] | Should -BeExactly 'In a real situation, what would you do and expect to happen?' } It 'offers optional ordinary-language starters instead of a prefilled answer' { $response.attributes.placeholder | Should -Not -BeNullOrEmpty ($response.attributes.placeholder.TrimEnd() -split '\r?\n') | Should -Be @( - 'I need to ...' - 'This matters because ...' + 'Today, ...' + 'This would help ... because ...' + 'I would like to ...' 'When I ..., I expect ...' ) } + It 'introduces the current situation before the value and desired change' { + $introduction.attributes.value | Should -Match ( + 'Start with how things work today\.\s+' + + 'Then explain why a change would help the user and what should change\.' + ) + } + It 'does not solicit implementation choices or prescribe Gherkin syntax' { (@( $introduction.attributes.value $response.attributes.description $response.attributes.placeholder ) -join ' ') | - Should -Not -Match '\b(implement(?:ed|ation)?|architecture|Gherkin|Given|Then)\b' + Should -Not -Match '\b(implement(?:ed|ation)?|architecture|Gherkin)\b|Given\s*/\s*When\s*/\s*Then' $response.attributes.description | Should -Not -Match 'Are there alternatives you.ve considered\?' } From e7a14f7eb35eb77bff8b6ba7730c8870a660185d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 4 Nov 2026 12:25:04 +0100 Subject: [PATCH 5/6] Remove feature form snapshots to follow testing policy --- tests/FeatureIntake.Tests.ps1 | 198 ---------------------------------- 1 file changed, 198 deletions(-) delete mode 100644 tests/FeatureIntake.Tests.ps1 diff --git a/tests/FeatureIntake.Tests.ps1 b/tests/FeatureIntake.Tests.ps1 deleted file mode 100644 index 26275f2..0000000 --- a/tests/FeatureIntake.Tests.ps1 +++ /dev/null @@ -1,198 +0,0 @@ -#Requires -Version 7.4 -#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '6.1.0'; MaximumVersion = '6.*' } -#Requires -Modules @{ ModuleName = 'powershell-yaml'; ModuleVersion = '0.4.12' } - -<# - .SYNOPSIS - Check the organization-owned feature intake contract. - - .DESCRIPTION - Verify consumer prompts, GitHub issue-form structure, submission usability, and preserved routing. - - .EXAMPLE - Invoke-Pester -Path .\tests\FeatureIntake.Tests.ps1 -Output Detailed -CI - - .LINK - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms -#> -[Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSUseDeclaredVarsMoreThanAssignments', '', - Justification = 'Pester setup variables are read in separate test blocks.' -)] -[CmdletBinding()] -param() - -$ErrorActionPreference = 'Stop' - -BeforeAll { - $repositoryRoot = [System.IO.Path]::GetFullPath((Join-Path -Path $PSScriptRoot -ChildPath '..')) - $formPath = Join-Path -Path $repositoryRoot -ChildPath '.github\ISSUE_TEMPLATE\10-feature.yml' - $configPath = Join-Path -Path $repositoryRoot -ChildPath '.github\ISSUE_TEMPLATE\config.yml' - $form = ConvertFrom-Yaml -Yaml ([System.IO.File]::ReadAllText($formPath)) - $configuration = ConvertFrom-Yaml -Yaml ([System.IO.File]::ReadAllText($configPath)) - $introduction = $form.body[0] - $response = $form.body[1] -} - -Describe 'Feature intake GitHub form structure' { - It 'uses only the existing supported top-level keys' { - $form | Should -BeOfType ([System.Collections.IDictionary]) - @($form.Keys) | Should -HaveCount 5 - @($form.Keys | Where-Object -FilterScript { - $_ -notin @('name', 'description', 'title', 'labels', 'body') - }) | Should -HaveCount 0 - } - - It 'provides nonempty strings for the template chooser and title' { - foreach ($value in @($form.name, $form.description, $form.title)) { - $value | Should -BeOfType ([string]) - [string]::IsNullOrWhiteSpace($value) | Should -BeFalse - } - } - - It 'keeps introductory Markdown followed by one textarea' { - ($form.body -is [System.Collections.IList]) | Should -BeTrue - $form.body | Should -HaveCount 2 - $introduction.type | Should -BeExactly 'markdown' - $response.type | Should -BeExactly 'textarea' - } - - It 'uses the documented Markdown element keys' { - @($introduction.Keys | Sort-Object) | Should -Be @('attributes', 'type') - @($introduction.attributes.Keys) | Should -Be @('value') - $introduction.attributes.value | Should -BeOfType ([string]) - [string]::IsNullOrWhiteSpace($introduction.attributes.value) | Should -BeFalse - } - - It 'uses the documented textarea element keys' { - @($response.Keys | Sort-Object) | Should -Be @('attributes', 'id', 'type', 'validations') - @($response.attributes.Keys | Where-Object -FilterScript { - $_ -notin @('label', 'description', 'placeholder') - }) | Should -HaveCount 0 - foreach ($value in @($response.attributes.label, $response.attributes.description)) { - $value | Should -BeOfType ([string]) - [string]::IsNullOrWhiteSpace($value) | Should -BeFalse - } - } - - It 'keeps the existing valid and unique URL-prefill field ID' { - $response.id | Should -BeExactly 'description' - $response.id | Should -Match '^[a-zA-Z0-9_-]+$' - @($form.body | Where-Object -FilterScript { $_.id }) | Should -HaveCount 1 - } - - It 'requires a real response without adding submission constraints' { - @($response.validations.Keys) | Should -Be @('required') - $response.validations.required | Should -BeOfType ([bool]) - $response.validations.required | Should -BeTrue - $response.attributes.ContainsKey('value') | Should -BeFalse - $response.attributes.ContainsKey('render') | Should -BeFalse - } -} - -Describe 'Feature intake preserved routing' { - It 'preserves the feature template name' { - $form.name | Should -BeExactly ([char]::ConvertFromUtf32(0x1F680) + ' [Feature]') - } - - It 'preserves the feature template chooser description' { - $form.description | Should -BeExactly 'Suggest/request a new feature' - } - - It 'preserves the existing title prefix' { - $form.title | Should -BeExactly ([char]::ConvertFromUtf32(0x1F680) + '[Feature]: ') - } - - It 'preserves only the feature and triage labels in their existing order' { - ($form.labels -is [System.Collections.IList]) | Should -BeTrue - $form.labels | Should -Be @('feature', 'triage') - } - - It 'does not assign an internal native type, assignee, or project to feedback' { - foreach ($key in @('type', 'assignees', 'projects')) { - $form.ContainsKey($key) | Should -BeFalse - } - } - - It 'leaves blank issue intake enabled' { - @($configuration.Keys) | Should -Be @('blank_issues_enabled') - $configuration.blank_issues_enabled | Should -BeOfType ([bool]) - $configuration.blank_issues_enabled | Should -BeTrue - } -} - -Describe 'Feature intake consumer expectations' -Tag 'ConsumerExpectations' { - It 'labels the response as current situation and desired change' { - $response.attributes.label | Should -BeExactly 'Current situation and desired change' - } - - It 'starts with how things work today and what is difficult or missing' { - ($response.attributes.description -split '\r?\n')[0] | - Should -BeExactly 'How do things work today, and what is difficult or missing?' - } - - It 'establishes user value before asking for the desired change' { - ($response.attributes.description -split '\r?\n')[1] | - Should -BeExactly 'Who would benefit from a change, and why would it be valuable?' - } - - It 'asks for the additional need or desired change after its value' { - ($response.attributes.description -split '\r?\n')[2] | - Should -BeExactly 'What additional need or change would you like to see?' - } - - It 'asks for expected behavior in a real situation' { - ($response.attributes.description -split '\r?\n')[3] | - Should -BeExactly 'In a real situation, what would you do and expect to happen?' - } - - It 'offers optional ordinary-language starters instead of a prefilled answer' { - $response.attributes.placeholder | Should -Not -BeNullOrEmpty - ($response.attributes.placeholder.TrimEnd() -split '\r?\n') | Should -Be @( - 'Today, ...' - 'This would help ... because ...' - 'I would like to ...' - 'When I ..., I expect ...' - ) - } - - It 'introduces the current situation before the value and desired change' { - $introduction.attributes.value | Should -Match ( - 'Start with how things work today\.\s+' + - 'Then explain why a change would help the user and what should change\.' - ) - } - - It 'does not solicit implementation choices or prescribe Gherkin syntax' { - (@( - $introduction.attributes.value - $response.attributes.description - $response.attributes.placeholder - ) -join ' ') | - Should -Not -Match '\b(implement(?:ed|ation)?|architecture|Gherkin)\b|Given\s*/\s*When\s*/\s*Then' - $response.attributes.description | - Should -Not -Match 'Are there alternatives you.ve considered\?' - } - - It 'invites the contributor to use their own words without a technical plan' { - $introduction.attributes.value | - Should -Match 'in your own words\.\s+No technical plan is needed\.' - } - - It 'keeps feedback review and routing with maintainers' { - $introduction.attributes.value | - Should -Match 'Maintainers will review your feedback and decide how to route it\.' - } - - It 'links the canonical MSX issue guidance' { - $introduction.attributes.value | Should -Match '\[MSX issue guidance\]\[issues\]' - $introduction.attributes.value | - Should -Match '(?m)^\[issues\]: https://msx\.no/docs/Ways-of-Working/Issues/\r?$' - } - - It 'links the canonical MSX planning guidance' { - $introduction.attributes.value | Should -Match '\[planning guidance\]\[planning\]' - $introduction.attributes.value | - Should -Match '(?m)^\[planning\]: https://msx\.no/docs/Ways-of-Working/Issues/Process/Planning/\r?$' - } -} From 7eedb8a44c00bfa0f38d541ea88a7d7d791eaa19 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 4 Nov 2026 13:26:11 +0100 Subject: [PATCH 6/6] Use direct instructions in the feature request form --- .github/ISSUE_TEMPLATE/10-feature.yml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/10-feature.yml b/.github/ISSUE_TEMPLATE/10-feature.yml index 8fb4a88..29b9a60 100644 --- a/.github/ISSUE_TEMPLATE/10-feature.yml +++ b/.github/ISSUE_TEMPLATE/10-feature.yml @@ -9,14 +9,14 @@ body: - type: markdown attributes: value: | - Thank you for suggesting a feature. Start with how things work today. - Then explain why a change would help the user and what should change. - Describe the result you expect in your own words. - No technical plan is needed. - Maintainers will review your feedback and decide how to route it. + Start with how things work today. + Tell us who the change helps and why. + Then tell us what should change and what result you expect. + Use your own words. A technical plan is not necessary. + Maintainers review and refine feedback, then select the issue type. See the [MSX issue guidance][issues] and - [planning guidance][planning] for how feedback becomes planned work. + [planning guidance][planning] for the work process. [issues]: https://msx.no/docs/Ways-of-Working/Issues/ [planning]: https://msx.no/docs/Ways-of-Working/Issues/Process/Planning/ @@ -25,14 +25,15 @@ body: attributes: label: Current situation and desired change description: | - How do things work today, and what is difficult or missing? - Who would benefit from a change, and why would it be valuable? - What additional need or change would you like to see? - In a real situation, what would you do and expect to happen? + Tell us how things work today. Include what is not easy or is missing. + Tell us who the change helps and why. + Tell us what you want to add or change. + Give a real example. Include the situation, your action, + and the result you expect. placeholder: | Today, ... - This would help ... because ... - I would like to ... + The change helps ... because ... + I want to ... When I ..., I expect ... validations: required: true