fix(config): regression test and changeset for #3197 gsd-tools config-whitelist (#3208)

* fix(config): add regression test and changeset for #3197 CJS whitelist fix

The underlying fix (RUNTIME_STATE_KEYS in config-schema.cjs) was already
applied to main via #3162. This PR adds the regression test that would have
caught the drift had it been present — verifying the CJS path end-to-end —
and the changeset fragment to formally close #3197.

Closes #3197

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(config): isolate tmpDir per test for cleanup

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-05-06 21:51:42 -04:00
committed by GitHub
parent 2d32ad82be
commit f4d0208abb
2 changed files with 65 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
---
type: Fixed
pr: 3197
---
**`gsd-tools config-set workflow._auto_chain_active` no longer rejected** — `workflow._auto_chain_active` is an internal runtime-state key written by plan-phase, execute-phase, discuss-phase, and transition workflows. PR #3162 added it to `RUNTIME_STATE_KEYS` in the SDK's `config-schema.ts` but did not mirror the change to the CJS `config-schema.cjs` used by `gsd-tools.cjs`. Users routed through `gsd-tools.cjs` continued to see "Unknown config key" (#3033). The fix adds `RUNTIME_STATE_KEYS` to `config-schema.cjs`, exports it alongside `VALID_CONFIG_KEYS`, and updates `isValidConfigKey()` to accept runtime-state keys. The SDK `config-mutation.ts` is updated to import and check the same set. A new CI parity assertion ensures the two `RUNTIME_STATE_KEYS` sets stay in sync. (#3197)

View File

@@ -0,0 +1,60 @@
'use strict';
/**
* Regression test for #3197 — gsd-tools config-set rejects workflow._auto_chain_active.
*
* Root cause: RUNTIME_STATE_KEYS was added to sdk/src/query/config-schema.ts in #3162
* but not to get-shit-done/bin/lib/config-schema.cjs, so gsd-tools.cjs users still hit
* "Unknown config key" when setting workflow._auto_chain_active.
*/
const { describe, test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const { createTempProject, cleanup, runGsdTools } = require('./helpers.cjs');
describe('#3197 — gsd-tools.cjs config-set workflow._auto_chain_active', () => {
test('config-set workflow._auto_chain_active true succeeds via gsd-tools.cjs (CJS path)', (t) => {
const tmpDir = createTempProject();
t.after(() => cleanup(tmpDir));
const result = runGsdTools(['config-set', 'workflow._auto_chain_active', 'true'], tmpDir);
assert.ok(
result.success,
`config-set workflow._auto_chain_active true should succeed, got:\nstdout: ${result.output}\nstderr: ${result.error}`
);
});
test('config-set workflow._auto_chain_active true writes value to config.json', (t) => {
const tmpDir = createTempProject();
t.after(() => cleanup(tmpDir));
runGsdTools(['config-set', 'workflow._auto_chain_active', 'true'], tmpDir);
const configPath = path.join(tmpDir, '.planning', 'config.json');
assert.ok(fs.existsSync(configPath), '.planning/config.json must exist after config-set');
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
assert.ok(
config.workflow !== undefined && config.workflow._auto_chain_active === true,
`Expected workflow._auto_chain_active: true in config.json, got: ${JSON.stringify(config)}`
);
});
test('config-set workflow._auto_chain_active false writes false to config.json', (t) => {
const tmpDir = createTempProject();
t.after(() => cleanup(tmpDir));
runGsdTools(['config-set', 'workflow._auto_chain_active', 'false'], tmpDir);
const configPath = path.join(tmpDir, '.planning', 'config.json');
assert.ok(fs.existsSync(configPath), '.planning/config.json must exist after config-set');
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
assert.ok(
config.workflow !== undefined && config.workflow._auto_chain_active === false,
`Expected workflow._auto_chain_active: false in config.json, got: ${JSON.stringify(config)}`
);
});
});