* test(#3964): waiting_signal, codebase_dir, and skill-manifest must be project-scoped * fix(#3964): route waiting_signal, codebase_dir, and skill-manifest through the project-aware resolver * chore(#3964): changeset fragment (pr number backfilled after PR creation) * chore(#3964): backfill changeset PR number (3971) * test(#3964): assert on the POSIX-normalized codebase_dir across platforms --------- Co-authored-by: sim <sim@local>
54 lines
2.2 KiB
TypeScript
54 lines
2.2 KiB
TypeScript
/**
|
|
* Canonical GSD artifact registry (ADR-457 build-at-publish: the hand-written
|
|
* bin/lib/artifacts.cjs collapsed to a TypeScript source of truth). Behaviour
|
|
* is preserved byte-for-behaviour from the prior hand-written .cjs; only types
|
|
* are added.
|
|
*
|
|
* Enumerates the file names that gsd workflows officially produce at the
|
|
* .planning/ root level. Used by gsd-health (W019) to flag unrecognized files
|
|
* so stale or misnamed artifacts don't silently mislead agents or reviewers.
|
|
*
|
|
* Add entries here whenever a new workflow produces a .planning/ root file.
|
|
*/
|
|
|
|
// Exact-match canonical file names at .planning/ root
|
|
export const CANONICAL_EXACT: ReadonlySet<string> = new Set([
|
|
'PROJECT.md',
|
|
'ROADMAP.md',
|
|
'STATE.md',
|
|
'REQUIREMENTS.md',
|
|
'MILESTONES.md',
|
|
'BACKLOG.md',
|
|
'LEARNINGS.md',
|
|
'THREADS.md',
|
|
'config.json',
|
|
'CLAUDE.md',
|
|
'RETROSPECTIVE.md',
|
|
'WINDOWS.md', // #3224: broken-windows ledger (src/broken-windows.cts, LEDGER_FILE_NAME)
|
|
'STATE-ARCHIVE.md', // state.cts's cmdStatePrune writes this at the .planning/ root
|
|
'milestone.lock', // #3311: milestone (phase + session) claim (src/milestone-lock.cts); persistent, unlike the transient STATE.md.lock/WAITING.json
|
|
'state.json', // #3227: machine-readable state contract published at step boundaries (src/state-contract.cts)
|
|
'skill-manifest.json', // init.cts routeSkillManifest --write (project-scoped planning root, #3964)
|
|
]);
|
|
|
|
// Pattern-match canonical file names (regex tests on the basename)
|
|
// Each pattern includes the name of the workflow that produces it as a comment.
|
|
export const CANONICAL_PATTERNS: ReadonlyArray<RegExp> = [
|
|
/^v\d+\.\d+(?:\.\d+)?-MILESTONE-AUDIT\.md$/i, // gsd-complete-milestone (pre-archive)
|
|
/^v\d+\.\d+(?:\.\d+)?-.*\.md$/i, // other version-stamped planning docs
|
|
];
|
|
|
|
/**
|
|
* Return true if `filename` (basename only, no path) matches a canonical
|
|
* .planning/ root artifact — either an exact name or a known pattern.
|
|
*
|
|
* @param filename - Basename of the file (e.g. "STATE.md")
|
|
*/
|
|
export function isCanonicalPlanningFile(filename: string): boolean {
|
|
if (CANONICAL_EXACT.has(filename)) return true;
|
|
for (const pattern of CANONICAL_PATTERNS) {
|
|
if (pattern.test(filename)) return true;
|
|
}
|
|
return false;
|
|
}
|