* fix(#1864): balance <step> tags in settings-advanced.md §8 Model Policy §8 Model Policy ended with </step> but had no matching opening tag (5 opens / 6 closes), leaving it as loose inter-step content. Add the missing <step name="model_policy"> opener so the section is a proper step. - gsd-core/workflows/settings-advanced.md: add <step name="model_policy"> - tests/workflow-step-tag-balance.test.cjs: regression guard — every top-level workflow must have balanced <step>/</step> (fenced code stripped), plus a focused assertion that §8 is wrapped in model_policy. - goldens + workflow-size baseline recaptured. Closes #1864 * docs(#1864): backfill changeset pr 2014
This commit is contained in:
5
.changeset/1864-settings-step-balance.md
Normal file
5
.changeset/1864-settings-step-balance.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
type: Fixed
|
||||
pr: 2014
|
||||
---
|
||||
**`settings-advanced.md` no longer has an orphan `</step>` around §8 Model Policy** — the §8 Model Policy block ended with a closing `</step>` but had no matching opening tag (5 opens / 6 closes), leaving its content as loose inter-step prose that could fail to execute reliably. Added the missing `<step name="model_policy">` opener so the section is a proper step. A new workflow `<step>`-tag-balance regression guard (fenced-code-stripped) now blocks any future orphan tag across all top-level workflows. (#1864)
|
||||
@@ -568,6 +568,8 @@ route each write through `gsd-tools.cjs query config-set` so sibling preservatio
|
||||
the central setter.
|
||||
</step>
|
||||
|
||||
<step name="model_policy">
|
||||
|
||||
### Section 8 — Model Policy
|
||||
|
||||
This section configures the `model_policy` key in `.planning/config.json`. Model policy
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
"gsd-core/workflows/scan.md": "a7fecd67e5cd655f",
|
||||
"gsd-core/workflows/secure-phase.md": "96b199dfac00e60f",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "43a3875aec529e5c",
|
||||
"gsd-core/workflows/settings-advanced.md": "f2f8c750101cb9ee",
|
||||
"gsd-core/workflows/settings-integrations.md": "4d3001ad2b5dad8f",
|
||||
"gsd-core/workflows/settings.md": "4017f3f235051902",
|
||||
"gsd-core/workflows/ship.md": "984bd7660e7791fd",
|
||||
|
||||
@@ -352,7 +352,7 @@
|
||||
"gsd-core/workflows/scan.md": "003883d71c37da7d",
|
||||
"gsd-core/workflows/secure-phase.md": "29fc6b62c5c5dc62",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "3d86a02a58171cff",
|
||||
"gsd-core/workflows/settings-advanced.md": "b57c947edee905bc",
|
||||
"gsd-core/workflows/settings-integrations.md": "70515c5838fb9826",
|
||||
"gsd-core/workflows/settings.md": "b2d39d972650f5f3",
|
||||
"gsd-core/workflows/ship.md": "7b8fe9f89143e648",
|
||||
|
||||
@@ -281,7 +281,7 @@
|
||||
"gsd-core/workflows/scan.md": "47371c2073d6c0be",
|
||||
"gsd-core/workflows/secure-phase.md": "59d3c50aba8c9a6c",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "c12cfa7a9e83bba4",
|
||||
"gsd-core/workflows/settings-advanced.md": "02f7ef84f976bda4",
|
||||
"gsd-core/workflows/settings-integrations.md": "53649313d20694ae",
|
||||
"gsd-core/workflows/settings.md": "3d994d669d3fb321",
|
||||
"gsd-core/workflows/ship.md": "12e8e58c077a891a",
|
||||
|
||||
@@ -285,7 +285,7 @@
|
||||
"gsd-core/workflows/scan.md": "dfd92717caea0ce7",
|
||||
"gsd-core/workflows/secure-phase.md": "cf78183f06a02582",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "bb070111ecdaf386",
|
||||
"gsd-core/workflows/settings-advanced.md": "e08245a5a65dcec2",
|
||||
"gsd-core/workflows/settings-integrations.md": "76eee76d6eb57657",
|
||||
"gsd-core/workflows/settings.md": "f6c7aa7ceb99078b",
|
||||
"gsd-core/workflows/ship.md": "5f931a25ea9102a4",
|
||||
|
||||
@@ -352,7 +352,7 @@
|
||||
"gsd-core/workflows/scan.md": "003883d71c37da7d",
|
||||
"gsd-core/workflows/secure-phase.md": "29fc6b62c5c5dc62",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "3d86a02a58171cff",
|
||||
"gsd-core/workflows/settings-advanced.md": "b57c947edee905bc",
|
||||
"gsd-core/workflows/settings-integrations.md": "70515c5838fb9826",
|
||||
"gsd-core/workflows/settings.md": "b2d39d972650f5f3",
|
||||
"gsd-core/workflows/ship.md": "7b8fe9f89143e648",
|
||||
|
||||
@@ -317,7 +317,7 @@
|
||||
"gsd-core/workflows/scan.md": "1a3caa5d724d39e9",
|
||||
"gsd-core/workflows/secure-phase.md": "db91810d16964b1e",
|
||||
"gsd-core/workflows/session-report.md": "dd8fa011c9394075",
|
||||
"gsd-core/workflows/settings-advanced.md": "19ce35f8fae6b667",
|
||||
"gsd-core/workflows/settings-advanced.md": "2cbb05c302f1df5e",
|
||||
"gsd-core/workflows/settings-integrations.md": "77730321d3d6d317",
|
||||
"gsd-core/workflows/settings.md": "1e19b0245851afc0",
|
||||
"gsd-core/workflows/ship.md": "d86233c9a365effd",
|
||||
|
||||
@@ -283,7 +283,7 @@
|
||||
"gsd-core/workflows/scan.md": "dcc2f76d0850e2fb",
|
||||
"gsd-core/workflows/secure-phase.md": "d87bd706f85bcad6",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "ae415134000ee1e2",
|
||||
"gsd-core/workflows/settings-advanced.md": "85f19b66b7d5040f",
|
||||
"gsd-core/workflows/settings-integrations.md": "a1d146d6bfd14db5",
|
||||
"gsd-core/workflows/settings.md": "95aa4a9bc0b51e92",
|
||||
"gsd-core/workflows/ship.md": "b9dc0aaee0ff68e7",
|
||||
|
||||
@@ -352,7 +352,7 @@
|
||||
"gsd-core/workflows/scan.md": "47371c2073d6c0be",
|
||||
"gsd-core/workflows/secure-phase.md": "c55975672c4e1895",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "4887fb7e45ddb3b6",
|
||||
"gsd-core/workflows/settings-advanced.md": "3817a94612e4b588",
|
||||
"gsd-core/workflows/settings-integrations.md": "166ca51b1f33c2a3",
|
||||
"gsd-core/workflows/settings.md": "1e285d00022e00ce",
|
||||
"gsd-core/workflows/ship.md": "38830806d244fe9c",
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
"gsd-core/workflows/scan.md": "b28f65d88c522767",
|
||||
"gsd-core/workflows/secure-phase.md": "f2957d4b88fb3746",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "a0629316a41e5d30",
|
||||
"gsd-core/workflows/settings-advanced.md": "9a45f0e5b8acf83d",
|
||||
"gsd-core/workflows/settings-integrations.md": "1dce76db0aca08a5",
|
||||
"gsd-core/workflows/settings.md": "cb2b6be87c519df9",
|
||||
"gsd-core/workflows/ship.md": "dbf8bf636cb196c0",
|
||||
|
||||
@@ -352,7 +352,7 @@
|
||||
"gsd-core/workflows/scan.md": "47371c2073d6c0be",
|
||||
"gsd-core/workflows/secure-phase.md": "e8855104c1e0417c",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "df9c4835bcb4373f",
|
||||
"gsd-core/workflows/settings-advanced.md": "03c647793401655b",
|
||||
"gsd-core/workflows/settings-integrations.md": "3ea8095d5fad891b",
|
||||
"gsd-core/workflows/settings.md": "05e35aeb442b7e20",
|
||||
"gsd-core/workflows/ship.md": "afd77be2093535f8",
|
||||
|
||||
@@ -318,7 +318,7 @@
|
||||
"gsd-core/workflows/scan.md": "003883d71c37da7d",
|
||||
"gsd-core/workflows/secure-phase.md": "29fc6b62c5c5dc62",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "3d86a02a58171cff",
|
||||
"gsd-core/workflows/settings-advanced.md": "b57c947edee905bc",
|
||||
"gsd-core/workflows/settings-integrations.md": "70515c5838fb9826",
|
||||
"gsd-core/workflows/settings.md": "b2d39d972650f5f3",
|
||||
"gsd-core/workflows/ship.md": "7b8fe9f89143e648",
|
||||
|
||||
@@ -352,7 +352,7 @@
|
||||
"gsd-core/workflows/scan.md": "ad8ebcad4626d4a8",
|
||||
"gsd-core/workflows/secure-phase.md": "e9a488cec3b4efdc",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "72438bf453f7340b",
|
||||
"gsd-core/workflows/settings-advanced.md": "f62c8e4fa6d3a3d9",
|
||||
"gsd-core/workflows/settings-integrations.md": "d1711a95f44fdbde",
|
||||
"gsd-core/workflows/settings.md": "bbbcad8d95d5e813",
|
||||
"gsd-core/workflows/ship.md": "924c79e3cfd1e42b",
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
"gsd-core/workflows/scan.md": "949692db4834dd27",
|
||||
"gsd-core/workflows/secure-phase.md": "6758f1acf4113e9e",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "008b5b3f4942e8a1",
|
||||
"gsd-core/workflows/settings-advanced.md": "8d850d15f1d06dd6",
|
||||
"gsd-core/workflows/settings-integrations.md": "29c5de27fbbb18e9",
|
||||
"gsd-core/workflows/settings.md": "da0b7567d648b80a",
|
||||
"gsd-core/workflows/ship.md": "9f94d0b155eb041e",
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
"gsd-core/workflows/scan.md": "63631467651d9ca8",
|
||||
"gsd-core/workflows/secure-phase.md": "6cc236e53c2e7d56",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "ed6ebaf5fb33a790",
|
||||
"gsd-core/workflows/settings-advanced.md": "252d3f848c95220e",
|
||||
"gsd-core/workflows/settings-integrations.md": "f8f756709ec02363",
|
||||
"gsd-core/workflows/settings.md": "01cf9ffd340cff64",
|
||||
"gsd-core/workflows/ship.md": "c08f0fe3025d2c86",
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
"gsd-core/workflows/scan.md": "12c11b2edc165df9",
|
||||
"gsd-core/workflows/secure-phase.md": "7bf923689bf58288",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
"gsd-core/workflows/settings-advanced.md": "c00c99b938e45272",
|
||||
"gsd-core/workflows/settings-advanced.md": "4c030adc097d1746",
|
||||
"gsd-core/workflows/settings-integrations.md": "b082fc518b484c07",
|
||||
"gsd-core/workflows/settings.md": "13ca50dba129c17b",
|
||||
"gsd-core/workflows/ship.md": "c035bb8b3bb7efbb",
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"scan.md": 7732,
|
||||
"secure-phase.md": 13520,
|
||||
"session-report.md": 4044,
|
||||
"settings-advanced.md": 39690,
|
||||
"settings-advanced.md": 39718,
|
||||
"settings-integrations.md": 15892,
|
||||
"settings.md": 33457,
|
||||
"ship.md": 24691,
|
||||
|
||||
50
tests/workflow-step-tag-balance.test.cjs
Normal file
50
tests/workflow-step-tag-balance.test.cjs
Normal file
@@ -0,0 +1,50 @@
|
||||
'use strict';
|
||||
|
||||
// Regression guard for #1864 — settings-advanced.md had an orphan </step>
|
||||
// (6 closes / 5 opens) because §8 Model Policy lacked an opening <step>.
|
||||
// Asserts EVERY top-level workflow .md has balanced <step>/</step> tags so an
|
||||
// unbalanced workflow can never land again. Fenced code blocks are stripped
|
||||
// first so legitimate <step> examples inside ``` fences don't false-positive.
|
||||
|
||||
const { describe, test } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const { stripFencedCode } = require('../gsd-core/bin/lib/markdown-sectionizer.cjs');
|
||||
|
||||
const WORKFLOWS_DIR = path.join(__dirname, '..', 'gsd-core', 'workflows');
|
||||
|
||||
function topLevelWorkflowFiles() {
|
||||
return fs.readdirSync(WORKFLOWS_DIR)
|
||||
.filter((f) => f.endsWith('.md'))
|
||||
.map((f) => path.join(WORKFLOWS_DIR, f));
|
||||
}
|
||||
|
||||
function countTags(text, re) {
|
||||
// matchAll requires the global flag; force it so the iterator terminates.
|
||||
const flags = re.flags.includes('g') ? re.flags : re.flags + 'g';
|
||||
return [...text.matchAll(new RegExp(re.source, flags))].length;
|
||||
}
|
||||
|
||||
describe('workflow <step> tag balance (#1864)', () => {
|
||||
test('every top-level workflow has equal <step> opens and </step> closes (code fences stripped)', () => {
|
||||
const offenders = [];
|
||||
for (const file of topLevelWorkflowFiles()) {
|
||||
const raw = fs.readFileSync(file, 'utf8');
|
||||
const stripped = stripFencedCode(raw).text;
|
||||
const opens = countTags(stripped, /<step(\s|>)/);
|
||||
const closes = countTags(stripped, /<\/step>/);
|
||||
if (opens !== closes) offenders.push(`${path.basename(file)}: ${opens} opens / ${closes} closes`);
|
||||
}
|
||||
assert.deepEqual(offenders, [], `unbalanced <step> tags:\n${offenders.join('\n')}`);
|
||||
});
|
||||
|
||||
test('settings-advanced.md §8 Model Policy is wrapped in a model_policy step (#1864)', () => {
|
||||
const file = path.join(WORKFLOWS_DIR, 'settings-advanced.md');
|
||||
const raw = fs.readFileSync(file, 'utf8');
|
||||
const stripped = stripFencedCode(raw).text;
|
||||
assert.match(stripped, /<step name="model_policy">[\s\S]*?### Section 8 — Model Policy[\s\S]*?<\/step>/,
|
||||
'§8 must be wrapped in <step name="model_policy">…</step>');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user