fix(26): retire validate.ts/verify.cjs cooperating-sibling for W005/W006-archived/I001 via generator (stacks on #156) (#158)
* test(26): reproduce W005/W006-archived/I001 false positives in CJS validate path Issue #26 (open-gsd/get-shit-done-redux): three validation drift items from PR #3479 were hand-ported to verify.cjs via PR #3806 but never routed through the generator pattern. This means they can drift again whenever validate.ts changes. RED tests assert that validate.generated.cjs exports four new items: - phaseDirNameRe (W005 regex — /^\d{2,}(?:\.\d+)*-[\w-]+$/) - MILESTONE_ARCHIVE_DIR_RE (W006-archived — /^v\d+.*-phases$/i) - PHASE_TOKEN_FROM_DIR_RE (W006-archived — phase dir token extractor) - canonicalPlanStem (I001 — plan/summary stem canonicalization) Three of four new export tests are RED (exports missing from generated artifact). Behavioral tests (W005 no-false-positive, W006-archived no-false-positive, I001 no-false-positive) are GREEN because #3806's hand-ported fixes are present. References: issue #26, ADR-3524, PR #154 (issue #4), PR #156 (issue #6), PR #3479 (original fix), PR #3806 (hand-port). * chore(26): extend gen-validate.mjs to export W005/W006-archived/I001 helpers Issue #26 (open-gsd/get-shit-done-redux): extend gen-validate.mjs (introduced in PR #156 / issue #6) to also extract the three drift items that PR #3806 hand-ported to verify.cjs but were never routed through the generator. New helpers added to gen-validate.mjs: phaseDirNameRe (PHASE_DIR_NAME_RE) — W005 phase directory naming regex. /^\d{2,}(?:\.\d+)*-[\w-]+$/ accepts multi-digit prefixes (999.1-foo valid). Requires adding PHASE_DIR_NAME_RE as a named constant to validate.ts so it appears as an extractable identifier in the compiled output. PHASE_TOKEN_FROM_DIR_RE — W006-archived regex; extracts phase token from directory names like "64-auth-service" → "64". Used by forEachArchivedPhaseToken() and collectDiskPhases() in verify.cjs. MILESTONE_ARCHIVE_DIR_RE — W006-archived regex; matches milestone archive directory names like "v1.0-phases". Used by listMilestoneArchiveDirs(). canonicalPlanStem() — I001 PLAN/SUMMARY stem canonicalization. '68-01-scaffolding' → '68-01'. Top-level named function in compiled output. Extraction approach: PHASE_TOKEN_FROM_DIR_RE and MILESTONE_ARCHIVE_DIR_RE are module-level const assignments, extracted via extractConstRegExp() (handles both `const` and `export const` prefixes). PHASE_DIR_NAME_RE is the new named export added to validate.ts in this commit. canonicalPlanStem is a top-level function, extracted via extractTopLevelFunction() (brace-balanced). validate.ts change: inline regex in Check 6 extracted to named constant PHASE_DIR_NAME_RE (exported) and Check 6 updated to reference it. References: issue #26, ADR-3524, PR #154 (issue #4), PR #156 (issue #6). * chore(26): regenerate validate.generated.cjs with W005/W006-archived/I001 helpers Re-run of sdk/scripts/gen-validate.mjs after extending it in the preceding commit. The artifact now exports seven items (was three): New (issue #26): phaseDirNameRe — /^\d{2,}(?:\.\d+)*-[\w-]+$/ (W005 check) PHASE_TOKEN_FROM_DIR_RE — phase token extractor regex (W006-archived) MILESTONE_ARCHIVE_DIR_RE — archive dir name matcher (W006-archived) canonicalPlanStem() — PLAN/SUMMARY stem canonicalization (I001) Existing (issue #6): phaseVariants() buildRoadmapPhaseVariants() buildNotStartedPhaseVariants() Freshness check: node sdk/scripts/check-validate-fresh.mjs → "fresh". References: issue #26, ADR-3524, PR #154 (issue #4), PR #156 (issue #6). * fix(26): migrate verify.cjs W005/W006-archived/I001 call sites to generated helpers Issue #26 (open-gsd/get-shit-done-redux): three hand-maintained items in verify.cjs now consumed from validate.generated.cjs (ADR-3524 §4 adapter pattern). Changes: - Top-of-file require(): extend to also destructure phaseDirNameRe, PHASE_TOKEN_FROM_DIR_RE, MILESTONE_ARCHIVE_DIR_RE, canonicalPlanStem from validate.generated.cjs (issue #26 exports). - Remove inline PHASE_TOKEN_FROM_DIR_RE and MILESTONE_ARCHIVE_DIR_RE constants (lines ~403-404). Now sourced from generated artifact. listMilestoneArchiveDirs and forEachArchivedPhaseToken pick them up via the require() at top of file. - Check 6 (W005): replace inline regex /^\d{2,}(?:\.\d+)*-[\w-]+$/ with phaseDirNameRe from validate.generated.cjs. No behavior change. - Remove inline canonicalPlanStem() function (~8 lines). Now sourced from validate.generated.cjs. Check 7 (I001) continues to call it as before. Public API of verify.cjs unchanged. Same migration shape as PR #156's Check 8. References: issue #26, ADR-3524, PR #154 (issue #4), PR #156 (issue #6), PR #3479 (original fix), PR #3806 (hand-port that #26 supersedes). * docs(26): extend ADR-3524 2026-05-23 amendment with #26 scope Extends the existing 2026-05-23 amendment (not a new dated section) to document the W005/W006-archived/I001 generator migration introduced by issue #26. Key points documented: - Four new exports added to validate.generated.cjs (phaseDirNameRe, PHASE_TOKEN_FROM_DIR_RE, MILESTONE_ARCHIVE_DIR_RE, canonicalPlanStem) - W006-archived coverage note: both fixes were already in verify.cjs from #3806; the gap was generator coverage of the regex constants - Extraction methods: extractConstRegExp() and extractTopLevelFunction() - Parity tests: tests/26-w005-w006-i001-cjs-drift-regression.test.cjs (7 tests) - Cross-reference: issue #26 completes the validate.ts ↔ verify.cjs migration scope started by issue #6 References: issue #26, ADR-3524, PR #154 (issue #4), PR #156 (issue #6), PR #3479 (original fix), PR #3806 (hand-port). * chore(26): add changeset fragment for W005/W006-archived/I001 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. References: issue #26, ADR-3524, PR #154 (issue #4), PR #156 (issue #6).
This commit is contained in:
@@ -146,3 +146,60 @@ all RED on pre-fix `origin/main`). Covers each drift item with concrete fixtures
|
||||
**Allowlist:** `scripts/shared-module-handsync-allowlist.json` — `verify.cjs` entry updated to
|
||||
reference the generator and freshness check. Classification remains `cooperating-sibling` (verify.cjs
|
||||
is still a full implementation; only Check 8 helpers are generated).
|
||||
|
||||
#### Extension — issue #26: W005/W006-archived/I001 generator migration
|
||||
|
||||
PR #3479 fixed three false-positive classes in `sdk/src/query/validate.ts`. PR #3806 hand-ported
|
||||
the three fixes to `get-shit-done/bin/lib/verify.cjs` but did not route them through the generator
|
||||
— meaning they could drift again. Issue #26 closes this gap by extending `gen-validate.mjs`
|
||||
(introduced in this amendment above) to also extract and export the W005/W006-archived/I001 items.
|
||||
|
||||
**Four additional exports added to `validate.generated.cjs` (issue #26):**
|
||||
|
||||
1. **`phaseDirNameRe` (W005)** — The `PHASE_DIR_NAME_RE` constant `/^\d{2,}(?:\.\d+)*-[\w-]+$/`
|
||||
is now a named export from `validate.ts` and extracted by `gen-validate.mjs`. `verify.cjs`
|
||||
Check 6 consumes `phaseDirNameRe` from the generated artifact instead of an inline copy.
|
||||
Reproducer: `mkdir -p .planning/phases/999.1-foo` → zero W005 (previously fired with
|
||||
the `\d{2}` two-digits-only regex before PR #3806 / PR #3479).
|
||||
|
||||
2. **`PHASE_TOKEN_FROM_DIR_RE` (W006-archived)** — The regex constant previously inline in
|
||||
`verify.cjs`'s `forEachArchivedPhaseToken()` and `collectDiskPhases()`. Extracted from the
|
||||
module-level `const` in the compiled output. `verify.cjs` inline copy removed.
|
||||
|
||||
3. **`MILESTONE_ARCHIVE_DIR_RE` (W006-archived)** — The regex constant previously inline in
|
||||
`verify.cjs`'s `listMilestoneArchiveDirs()`. Extracted the same way. `verify.cjs` inline copy
|
||||
removed. Together `PHASE_TOKEN_FROM_DIR_RE` and `MILESTONE_ARCHIVE_DIR_RE` ensure the
|
||||
archive-walking logic uses the same patterns as `validate.ts`.
|
||||
|
||||
4. **`canonicalPlanStem` (I001)** — The top-level helper function previously inline in
|
||||
`verify.cjs` Check 7. Extracted via `extractTopLevelFunction()` (brace-balanced parser).
|
||||
`verify.cjs` inline copy removed. Fix: `68-01-scaffolding-PLAN.md` correctly matches
|
||||
`68-01-SUMMARY.md` — both reduce to `68-01` via `canonicalPlanStem()`.
|
||||
|
||||
**W006-archived coverage note:** Issue #26 describes W006-archived as "RELATED TO but DISTINCT
|
||||
FROM" PR #156's W006 fix. Investigation confirmed both fixes are ALREADY in `verify.cjs` (from
|
||||
PR #3806). The gap was generator coverage: the regex constants used by `forEachArchivedPhaseToken`
|
||||
were inline copies with no generator protection. This amendment closes that gap by extracting them.
|
||||
No new behavioral fix is required — the generator pattern extension is the deliverable.
|
||||
|
||||
**`validate.ts` change:** `PHASE_DIR_NAME_RE` promoted from inline anonymous regex to a named
|
||||
`export const` so it appears as an extractable identifier in the compiled ESM output.
|
||||
|
||||
**Extraction methods used:**
|
||||
- `extractConstRegExp()` (new in `gen-validate.mjs`) — handles `const` and `export const`
|
||||
single-line RegExp assignments. Used for `phaseDirNameRe`, `PHASE_TOKEN_FROM_DIR_RE`,
|
||||
`MILESTONE_ARCHIVE_DIR_RE`.
|
||||
- `extractTopLevelFunction()` (new in `gen-validate.mjs`) — brace-balanced parser for top-level
|
||||
named function declarations. Used for `canonicalPlanStem`.
|
||||
|
||||
**Parity tests:** `tests/26-w005-w006-i001-cjs-drift-regression.test.cjs` — 7 tests.
|
||||
- W005: no false positive for `999.1-foo`; W005 still fires for single-digit prefix.
|
||||
- W006-archived: no false W006 for phase archived under `milestones/v1.0-phases/`; unit tests
|
||||
for `MILESTONE_ARCHIVE_DIR_RE` and `PHASE_TOKEN_FROM_DIR_RE` export and behavior.
|
||||
- I001: no false I001 when long-stem PLAN matches short-stem SUMMARY via `canonicalPlanStem`;
|
||||
I001 still fires when there is genuinely no SUMMARY; unit test for `canonicalPlanStem` export.
|
||||
|
||||
**Cross-references:** issue #26 cures the same false-positive scenarios as issue #6 but for
|
||||
the W005/W006-archived/I001 check paths. The artifact `validate.generated.cjs` now covers all
|
||||
six drift surfaces originally identified across both issues. This completes the validate.ts ↔
|
||||
verify.cjs migration scope for generator-pattern coverage.
|
||||
|
||||
Reference in New Issue
Block a user