* test(6): reproduce W007 + phaseVariants + W006 drift between CJS verify and SDK validate Adds tests/6-validate-cjs-drift-regression.test.cjs with 5 RED tests covering the three drift items from issue #6 between verify.cjs (Check 8) and validate.ts (Check 8): 1. W007 activeDiskPhases — verify.cjs uses diskPhases (includes archived) for W007; archived phase "1" absent from current ROADMAP fires false W007. validate.ts: activeDiskPhases (active phasesDir only) correctly excludes archives. 2. phaseVariants() normalization — ROADMAP says "01A", disk has "1A-foo". verify.cjs parseInt("01A")=1 → padded "01" (drops letter suffix) → miss. validate.ts phaseVariants("01A") = {"01A","1A","01A"} → "1A" matched. Both W006 and W007 fire as false positives in verify.cjs. 3. W006 letter-suffix padding mismatch — ROADMAP says "3B", disk has "03B-foo". verify.cjs parseInt("3B")=3 → padded "03" (drops "B") → diskPhases.has("03B") missed. W006 and W007 fire as false positives. All 5 tests RED on origin/main. Will turn GREEN after generator + verify.cjs migration. References: - Issue #6 (open-gsd/get-shit-done-redux) — maintainer acceptance criteria: "Port all three items to verify.cjs; add parity tests confirming identical output for all three cases on both paths" - ADR-3524 (docs/adr/3524-cjs-sdk-hard-seam.md) - PR #154 (issue #4) — precedent for the generator pattern Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(6): add sdk/scripts/gen-validate.mjs generator Extracts phaseVariants() from sdk/dist/query/validate.js via brace-balanced source-text parsing (phaseVariants is a closure inside validateHealth, not a module export, so Function.prototype.toString() is unavailable). Emits get-shit-done/bin/lib/validate.generated.cjs with three pure helpers: - phaseVariants(phase): normalized Set of padded/unpadded/letter-suffix variants - buildRoadmapPhaseVariants(content): {roadmapPhases, roadmapPhaseVariants} - buildNotStartedPhaseVariants(content): Set of unchecked-phase variants These three helpers directly address the three drift items in issue #6. Follows the gen-phase-lifecycle-policy.mjs extraction pattern from PR #154. References: - Issue #6 (open-gsd/get-shit-done-redux) - ADR-3524 (docs/adr/3524-cjs-sdk-hard-seam.md) - PR #154 (issue #4) — generator pattern precedent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(6): add sdk/scripts/check-validate-fresh.mjs freshness check Mirrors check-phase-lifecycle-policy-fresh.mjs from PR #154: imports buildValidateCjs() directly, regenerates in-memory, and diffs against the committed validate.generated.cjs. Exits 1 if stale (CI gate). References: - Issue #6 (open-gsd/get-shit-done-redux) - ADR-3524 (docs/adr/3524-cjs-sdk-hard-seam.md) - PR #154 (issue #4) — precedent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(6): emit validate.generated.cjs from validate.ts Generated by: node sdk/scripts/gen-validate.mjs Exports three pure helpers extracted from sdk/src/query/validate.ts Check 8: - phaseVariants(phase): Set of normalized variants {"01A","1A"} etc. - buildRoadmapPhaseVariants(content): {roadmapPhases, roadmapPhaseVariants} - buildNotStartedPhaseVariants(content): Set of unchecked-phase variants Freshness check: node sdk/scripts/check-validate-fresh.mjs → FRESH References: - Issue #6 (open-gsd/get-shit-done-redux) - ADR-3524 (docs/adr/3524-cjs-sdk-hard-seam.md) - PR #154 (issue #4) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(6): migrate verify.cjs to consume validate.generated.cjs helpers (GREEN) Check 8 in verify.cjs now uses three generated helpers from validate.generated.cjs: 1. buildRoadmapPhaseVariants(roadmapContent) — replaces hand-rolled roadmapPhases Set. Produces both roadmapPhases (raw, for W006 message) and roadmapPhaseVariants (all variants, for W007 membership check). Fixes false W007 for letter-suffix phases with padding mismatch. 2. activeDiskPhases — now uses collectDiskPhases() WITHOUT forEachArchivedPhaseToken. W007 iterates activeDiskPhases, not diskPhases, so archived phases absent from current ROADMAP no longer trigger false W007. 3. buildNotStartedPhaseVariants(roadmapContent) — replaces raw+parseInt-padded notStartedPhases population. Uses phaseVariants() expansion so zero-padded letter-suffix unchecked entries (e.g. "03B") correctly suppress W006 for their un-padded counterpart ("3B") and vice versa. 4. phaseVariants() in W006 loop — replaces parseInt-padded disk-existence check. "3B" now matches disk dir "03B-foo" via variant expansion. Also updates test fixture for drift item 1 to use two milestone archives (v1.0 + v1.1), accurately reproducing the scenario where forEachArchivedPhaseToken walks ALL archives while getActiveMilestoneArchiveDir returns only the most recent one. All 5 tests GREEN. Confirmed RED on pre-fix code (git stash test). References: - Issue #6 (open-gsd/get-shit-done-redux) — maintainer acceptance criteria: "Port all three items to verify.cjs; add parity tests confirming identical output" - ADR-3524 (docs/adr/3524-cjs-sdk-hard-seam.md) - PR #154 (issue #4) — generator pattern precedent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci(6): wire validate freshness check into test workflow Adds 'SDK generated validate artifact drift check' step to .github/workflows/test.yml, mirroring the pattern used by all PR #154 generator freshness checks. Runs on ubuntu-latest/node-24 only (same as other artifact drift checks). Placement: after workstream-name-policy check, before Shared Module hand-sync drift check. References: - Issue #6 (open-gsd/get-shit-done-redux) - ADR-3524 (docs/adr/3524-cjs-sdk-hard-seam.md) - PR #154 (issue #4) — precedent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(6): wire gen:validate into sdk/package.json, root package.json, and allowlist sdk/package.json: adds gen:validate and check:validate-fresh npm scripts. package.json: adds check:validate-fresh script (mirrors other check:*-fresh entries). scripts/shared-module-handsync-allowlist.json: updates verify.cjs justification to note that Check 8 W006/W007 helpers are now generated from validate.ts via gen-validate.mjs (issue #6), with freshness check at check-validate-fresh.mjs. References: - Issue #6 (open-gsd/get-shit-done-redux) - ADR-3524 (docs/adr/3524-cjs-sdk-hard-seam.md) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(6): amend ADR-3524 — validate.ts now uses generator pattern Adds 2026-05-23 amendment section to docs/adr/3524-cjs-sdk-hard-seam.md documenting: - Generator/artifact/freshness-check/CI paths - Three drift items resolved (W007 activeDiskPhases, phaseVariants normalization, W006 unchecked-phase variant skip) - phaseVariants extraction technique (brace-balanced source-text parsing) - Parity test coverage (5 tests, RED→GREEN) - Allowlist classification preserved (cooperating-sibling) References: - Issue #6 (open-gsd/get-shit-done-redux) - ADR-3524 (docs/adr/3524-cjs-sdk-hard-seam.md) - PR #154 (issue #4) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(6): add changeset fragment for validate.ts/verify.cjs generator migration Touches get-shit-done/bin/lib/validate.generated.cjs and verify.cjs which match USER_FACING_PREFIXES. Required by the fix-template checklist + the changeset-lint CI workflow. Refs #6 #156 * docs(6): register validate.generated.cjs in INVENTORY + manifest INVENTORY parity test demanded a row for the new generated CJS surface and a matching entry in INVENTORY-MANIFEST.json. Headline count bumped from 74 → 75. Refs #6 --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
42 lines
1.4 KiB
JavaScript
42 lines
1.4 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Freshness check for validate.generated.cjs.
|
|
*
|
|
* Regenerates the expected CJS content in-memory (without writing to disk) and
|
|
* compares it to the committed file. Exits 0 if they match, 1 if stale.
|
|
*
|
|
* Uses the same pattern as check-phase-lifecycle-policy-fresh.mjs: imports
|
|
* buildValidateCjs() from the generator directly.
|
|
*
|
|
* Run: node sdk/scripts/check-validate-fresh.mjs
|
|
* (Requires sdk/dist to be built first — `npm run build` in sdk/.)
|
|
*
|
|
* References:
|
|
* - ADR-3524 (docs/adr/3524-cjs-sdk-hard-seam.md)
|
|
* - Issue #6 (open-gsd/get-shit-done-redux)
|
|
* - PR #154 (issue #4) — generator pattern precedent
|
|
*/
|
|
|
|
import { readFile } from 'node:fs/promises';
|
|
import { resolve, dirname } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
|
|
// Import the generator function directly (avoids duplicating logic).
|
|
const { buildValidateCjs } = await import('./gen-validate.mjs');
|
|
|
|
const expected = await buildValidateCjs();
|
|
|
|
const committedPath = resolve(here, '..', '..', 'get-shit-done', 'bin', 'lib', 'validate.generated.cjs');
|
|
const committed = await readFile(committedPath, 'utf-8');
|
|
|
|
if (expected === committed) {
|
|
console.log('validate.generated.cjs is fresh');
|
|
process.exit(0);
|
|
} else {
|
|
console.error('validate.generated.cjs is STALE.');
|
|
console.error('Regenerate: cd sdk && npm run gen:validate');
|
|
process.exit(1);
|
|
}
|