Files
get-shit-done/tests/config-schema-docs-parity.test.cjs
Tom Boucher 62eaa8dd7b docs: close doc drift vectors — bidirectional parity, manifest, schema-driven config (#2479)
Option A — ghost-entry guard (INVENTORY ⊆ actual):
  tests/inventory-source-parity.test.cjs parses every declared row in
  INVENTORY.md and asserts the source file exists. Catches deletions and
  renames that leave ghost entries behind.

Option B — auto-generated structural manifest:
  scripts/gen-inventory-manifest.cjs walks all six family dirs and emits
  docs/INVENTORY-MANIFEST.json. tests/inventory-manifest-sync.test.cjs
  fails CI when a new surface ships without a manifest update, surfacing
  exactly which entries are missing.

Option C — schema-driven config validation + docs parity:
  get-shit-done/bin/lib/config-schema.cjs extracted from config.cjs as
  the single source of truth for VALID_CONFIG_KEYS and dynamic patterns.
  config.cjs now imports from it. tests/config-schema-docs-parity.test.cjs
  asserts every exact-match key appears in docs/CONFIGURATION.md, surfacing
  14 previously undocumented keys (planning.sub_repos, workflow.ai_integration_phase,
  git.base_branch, learnings.max_inject, and 10 others) — all now documented
  in their appropriate sections.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:39:05 -04:00

41 lines
1.5 KiB
JavaScript

'use strict';
/**
* Asserts every exact-match key in config-schema.cjs appears at least once
* in docs/CONFIGURATION.md. A key present in the validator but absent from
* the docs means users can set it but have no guidance. A key in the docs but
* absent from the validator means config-set silently rejects it.
*
* Dynamic patterns (agent_skills.*, review.models.*, features.*) are excluded
* from this check — they are documented by namespace in CONFIGURATION.md.
*/
const { test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const ROOT = path.resolve(__dirname, '..');
const { VALID_CONFIG_KEYS } = require('../get-shit-done/bin/lib/config-schema.cjs');
const CONFIGURATION_MD = fs.readFileSync(path.join(ROOT, 'docs', 'CONFIGURATION.md'), 'utf8');
// Keys starting with _ are internal runtime state, not user-facing config.
const INTERNAL_KEYS = new Set(['workflow._auto_chain_active']);
test('every key in VALID_CONFIG_KEYS is documented in docs/CONFIGURATION.md', () => {
const undocumented = [];
for (const key of VALID_CONFIG_KEYS) {
if (INTERNAL_KEYS.has(key)) continue;
if (!CONFIGURATION_MD.includes('`' + key + '`')) {
undocumented.push(key);
}
}
assert.deepStrictEqual(
undocumented,
[],
'Keys in VALID_CONFIG_KEYS with no mention in docs/CONFIGURATION.md:\n' +
undocumented.map((k) => ' ' + k).join('\n') +
'\nAdd a row in the appropriate section of docs/CONFIGURATION.md.',
);
});