refactor(#1294): T-final — delete the core.cjs re-export spine (epic #1267 complete) (#1295)

* refactor(#1294): T-final — delete the core.cjs re-export spine (epic #1267 complete)

After T0–T6 nothing imports core, so retire the spine and its scaffolding:
- delete src/core.cts (and the gitignored gsd-core/bin/lib/core.cjs artifact;
  remove its .gitignore + eslint-ignore entries)
- delete scripts/lint-core-spine-imports.cjs + its allowlist; drop it from the
  package.json lint:ci chain
- regenerate docs/INVENTORY-MANIFEST.json (drops the core.cjs surface)
- sweep stale references: CONTEXT.md glossary back-compat clauses (spine retired,
  callers import the leaf directly), planning-config.md CONFIG_DEFAULTS owner,
  and false present-tense core.cjs claims in leaf-module docstrings

The ADR-857 decomposition is complete: the former Core god-module is fully
dissolved into its leaf modules; no re-export spine remains. No behaviour change.

Closes #1294

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(#1294): migrate the computed-path core.cjs importers the literal grep missed

bin/install.js used require(path.join(_gsdLibDir, 'core.cjs')) (a computed
path, and bin/install.js was never in the convergence lint's scan roots), and
~8 test files referenced core.cjs via path.join/readFileSync/existsSync/FILE_ARG
forms the literal-string migration grep missed. Route install.js's symbols to
their leaves (RUNTIME_PROFILE_MAP->model-catalog, resolveTierEntry/EFFORT_SET->
model-resolver) and repoint/adjust the test references to the leaves. Recovers
the 161 'Cannot find module core.cjs' failures from the spine deletion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-06-15 18:50:46 -04:00
committed by GitHub
parent c76827afbc
commit 8c3d934a90
31 changed files with 62 additions and 501 deletions

View File

@@ -5,8 +5,8 @@
* - getAgentsDir(runtime?): string
* - checkAgentsInstalled(runtime?): AgentsInstalledResult
*
* Consumers that previously imported these via core.cjs continue to work:
* core.cjs re-exports both symbols BY REFERENCE from this module.
* The core.cjs re-export spine was retired in epic #1267; callers import
* these symbols from agent-install-check.cjs directly.
*/
import fs from 'node:fs';

View File

@@ -7,11 +7,10 @@
* normalizes legacy keys, applies the active-workstream overlay, validates
* against the config schema, and warns on unknown keys/profile overrides.
* Behaviour is preserved byte-for-behaviour from the prior location; only
* the module boundary moved. core.cjs re-exports `loadConfig` for back-compat.
* the module boundary moved. The core.cjs re-export spine was retired in
* epic #1267; callers import loadConfig from config-loader.cjs directly.
*
* New imports should pull loadConfig from config-loader.cjs directly.
*
* Dependencies (leaf modules only — no core.cjs):
* Dependencies (leaf modules only):
* - node:fs / node:os / node:path (stdlib)
* - ./configuration.cjs (normalizeLegacyKeys, CONFIG_DEFAULTS as CANONICAL_CONFIG_DEFAULTS)
* - ./config-schema.cjs (VALID_CONFIG_KEYS, DYNAMIC_KEY_PATTERNS)

View File

@@ -5,8 +5,8 @@
*
* Imported by:
* - config.cjs (isValidConfigKey validator)
* - core.cjs
* - many tests (config-schema.property.test.cjs, bug-*, feat-*, etc.)
* (core.cjs re-export spine retired in epic #1267)
*
* See Phase 2 Cycle 5 (#3536) — schema manifest migration.
*

View File

@@ -2,7 +2,8 @@
* TypeScript type definitions for GSD project config — model_policy block.
*
* These types reflect the model_policy config shape consumed by
* resolveModelPolicy in core.cjs and validated by config-schema.cjs.
* resolveModelPolicy in model-resolver.cjs and validated by config-schema.cjs.
* (core.cjs re-export spine retired in epic #1267)
*
* See feat #49 (model_policy presets) and config-schema.manifest.json.
* Added under ADR-457: TS sources in src/ compile to CJS artifacts in

View File

@@ -1,219 +0,0 @@
/**
* Core — Shared utilities, constants, and internal helpers
*
* ADR-457 build-at-publish: the hand-written bin/lib/core.cjs collapsed
* to a TypeScript source of truth. Behaviour is preserved byte-for-behaviour
* from the prior hand-written .cjs; only strict types are added.
*/
// (fs, path, execGit removed — last callers relocated to leaf modules during #1268 T0 rehome)
// eslint-disable-next-line @typescript-eslint/no-require-imports
import ioModule = require('./io.cjs');
const { output, error, ERROR_REASON, setJsonErrorMode, getJsonErrorMode, GSD_TEMP_DIR, reapStaleTempFiles } = ioModule;
// eslint-disable-next-line @typescript-eslint/no-require-imports
import phaseIdModule = require('./phase-id.cjs');
const { escapeRegex, normalizePhaseName, getMilestoneFromPhaseId, getPhaseDirFromPhaseId, phaseMarkdownRegexSource, phaseMarkdownRegexSourceExact, comparePhaseNum, extractPhaseToken, phaseTokenMatches } = phaseIdModule;
// eslint-disable-next-line @typescript-eslint/no-require-imports
import roadmapParserModule = require('./roadmap-parser.cjs');
const { stripShippedMilestones, extractCurrentMilestone, replaceInCurrentMilestone, getRoadmapPhaseInternal, getMilestoneInfo, getMilestonePhaseFilter } = roadmapParserModule;
import { RUNTIME_PROFILE_MAP, KNOWN_RUNTIMES, RUNTIMES_WITH_REASONING_EFFORT, RUNTIMES_WITH_FAST_MODE, KNOWN_PROVIDERS, MODEL_ALIAS_MAP } from './model-catalog.cjs';
// eslint-disable-next-line @typescript-eslint/no-require-imports
import worktreeSafety = require('./worktree-safety.cjs');
const {
inspectWorktreeHealth,
} = worktreeSafety;
// eslint-disable-next-line @typescript-eslint/no-require-imports
import planningWorkspace = require('./planning-workspace.cjs');
// Compatibility shim: new imports should use planning-workspace.cjs directly.
const {
planningDir,
planningRoot,
planningPaths,
withPlanningLock,
getActiveWorkstream,
setActiveWorkstream,
} = planningWorkspace;
// eslint-disable-next-line @typescript-eslint/no-require-imports
import coreUtilsModule = require('./core-utils.cjs');
const {
toPosixPath,
detectSubRepos,
extractOneLinerFromBody,
pathExistsInternal,
generateSlugInternal,
filterPlanFiles,
filterSummaryFiles,
getPhaseFileStats,
readSubdirectories,
timeAgo,
} = coreUtilsModule;
// eslint-disable-next-line @typescript-eslint/no-require-imports
import phaseLocatorModule = require('./phase-locator.cjs');
const { searchPhaseInDir, findPhaseInternal, getArchivedPhaseDirs } = phaseLocatorModule;
import { findProjectRoot } from './project-root.cjs';
// ─── Config Loader Module (extracted from core, ADR-857 phase 2e / #885) ─────
// eslint-disable-next-line @typescript-eslint/no-require-imports
import configLoaderModule = require('./config-loader.cjs');
const {
loadConfig,
isGitIgnored,
CONFIG_DEFAULTS,
_warnUnknownProfileOverrides,
RUNTIME_OVERRIDE_TIERS,
} = configLoaderModule;
// ─── Model Resolver Module (extracted from core, ADR-857 phase 2f / #888) ────
// eslint-disable-next-line @typescript-eslint/no-require-imports
import modelResolverModule = require('./model-resolver.cjs');
const {
resolveTierEntry,
resolveModelPolicy,
resolveModelInternal,
VALID_GRANULARITIES,
resolveGranularityInternal,
assertValidGranularityOverride,
resolveModelForTier,
VALID_EFFORTS,
EFFORT_SET,
nextEffort,
resolveEffortInternal,
resolveFastModeInternal,
resolveEffortForTier,
} = modelResolverModule;
// ─── Path helpers ────────────────────────────────────────────────────────────
// toPosixPath and detectSubRepos moved to core-utils.cjs (ADR-857 phase 2c / #877).
// The destructured bindings above (from coreUtilsModule) make them available to
// core-internal callers; core.cjs re-exports toPosixPath and detectSubRepos for back-compat.
// findProjectRoot is now re-exported from the generated CJS module above.
// loadConfig, isGitIgnored, CONFIG_DEFAULTS, and related helpers moved to
// config-loader.cjs (ADR-857 phase 2e / #885). The destructured bindings above
// (from configLoaderModule) make them available to core-internal callers;
// core.cjs re-exports loadConfig and isGitIgnored for back-compat.
// ─── Planning workspace (pathing + active workstream + lock) moved to planning-workspace.cjs ───
// ─── Phase utilities (pure helpers re-exported from phase-id.cjs) ─────────────
// escapeRegex, normalizePhaseName, getMilestoneFromPhaseId, getPhaseDirFromPhaseId,
// phaseMarkdownRegexSource, phaseMarkdownRegexSourceExact, comparePhaseNum,
// extractPhaseToken, phaseTokenMatches
// — all imported via `phaseIdModule` above; internal callers use the destructured bindings.
// extractCanonicalPlanId moved to core-utils.cjs (ADR-857 phase 2c / #877).
// It is consumed exclusively by phase-locator.cjs, which imports it from
// core-utils.cjs directly. It is NOT destructured in core.cts and is NOT
// in core.cjs's public export = block (it was never public).
// searchPhaseInDir, findPhaseInternal, getArchivedPhaseDirs moved to phase-locator.cjs
// (ADR-857 phase 2d / #881). The destructured bindings above (from phaseLocatorModule)
// make them available to core-internal callers; core.cjs re-exports findPhaseInternal,
// getArchivedPhaseDirs, and searchPhaseInDir for back-compat.
// ─── Roadmap milestone scoping (re-exported from roadmap-parser.cjs) ──────────
// stripShippedMilestones, extractCurrentMilestone, replaceInCurrentMilestone,
// getRoadmapPhaseInternal, getMilestoneInfo, getMilestonePhaseFilter
// — all imported via `roadmapParserModule` above; internal callers use the destructured bindings.
// ─── Agent installation validation (#1371) ───────────────────────────────────
// getAgentsDir and checkAgentsInstalled moved to agent-install-check.cjs (T0 #1268).
// Re-exports removed in T1 (#1277); callers import directly from agent-install-check.cjs.
// ─── Model alias resolution ───────────────────────────────────────────────────
// RUNTIME_OVERRIDE_TIERS, _warnedConfigKeys, _warnUnknownProfileOverrides, and
// _resetRuntimeWarningCacheForTests moved to config-loader.cjs (ADR-857 phase 2e / #885)
// and model-resolver.cjs (ADR-857 phase 2f / #888) respectively.
// _resetRuntimeWarningCacheForTests is NO LONGER re-exported from core.cjs; callers
// must import it directly from config-loader.cjs / model-resolver.cjs (or use
// the shared resetRuntimeWarningCaches() helper in tests/helpers.cjs).
// resolveTierEntry, resolveModelPolicy, resolveModelInternal, VALID_GRANULARITIES,
// resolveGranularityInternal, assertValidGranularityOverride, resolveModelForTier,
// VALID_EFFORTS, EFFORT_SET, nextEffort, resolveEffortInternal, resolveFastModeInternal,
// resolveEffortForTier — all moved to model-resolver.cjs (ADR-857 phase 2f / #888).
// The destructured bindings above (from modelResolverModule) make them available to
// core-internal callers; core.cjs re-exports all 13 symbols for back-compat.
// ─── Summary body helpers / Misc utilities / Phase file helpers ───────────────
// extractOneLinerFromBody, pathExistsInternal, generateSlugInternal,
// filterPlanFiles, filterSummaryFiles, getPhaseFileStats, readSubdirectories,
// timeAgo — all moved to core-utils.cjs (ADR-857 phase 2c / #877).
// The destructured bindings above (from coreUtilsModule) make them available
// to core-internal callers; core.cjs re-exports the public ones for back-compat.
// MilestoneInfo, MilestonePhaseFilter, getMilestoneInfo, getMilestonePhaseFilter
// — all re-exported from roadmap-parser.cjs via roadmapParserModule above.
export = {
output,
error,
ERROR_REASON,
setJsonErrorMode,
getJsonErrorMode,
loadConfig,
isGitIgnored,
escapeRegex,
normalizePhaseName,
getMilestoneFromPhaseId,
getPhaseDirFromPhaseId,
phaseMarkdownRegexSource,
phaseMarkdownRegexSourceExact,
comparePhaseNum,
searchPhaseInDir,
extractPhaseToken,
phaseTokenMatches,
findPhaseInternal,
getArchivedPhaseDirs,
getRoadmapPhaseInternal,
resolveModelInternal,
resolveModelForTier,
resolveGranularityInternal,
VALID_GRANULARITIES,
assertValidGranularityOverride,
resolveEffortInternal,
resolveFastModeInternal,
resolveEffortForTier,
VALID_EFFORTS,
EFFORT_SET,
nextEffort,
RUNTIME_PROFILE_MAP,
RUNTIMES_WITH_REASONING_EFFORT,
RUNTIMES_WITH_FAST_MODE,
KNOWN_RUNTIMES,
RUNTIME_OVERRIDE_TIERS,
resolveTierEntry,
resolveModelPolicy,
KNOWN_PROVIDERS,
pathExistsInternal,
generateSlugInternal,
getMilestoneInfo,
getMilestonePhaseFilter,
stripShippedMilestones,
extractCurrentMilestone,
replaceInCurrentMilestone,
toPosixPath,
extractOneLinerFromBody,
resolveWorktreeRoot: worktreeSafety.resolveWorktreeRoot,
// Deprecated re-exports — prefer direct import from planning-workspace.cjs
withPlanningLock,
findProjectRoot,
detectSubRepos,
reapStaleTempFiles,
GSD_TEMP_DIR,
MODEL_ALIAS_MAP,
CONFIG_DEFAULTS,
planningDir,
planningRoot,
planningPaths,
getActiveWorkstream,
setActiveWorkstream,
filterPlanFiles,
filterSummaryFiles,
getPhaseFileStats,
readSubdirectories,
timeAgo,
pruneOrphanedWorktrees: worktreeSafety.pruneOrphanedWorktrees,
inspectWorktreeHealth,
};

View File

@@ -176,7 +176,7 @@ export function resolveBaseBranch(
): string {
const execGit: ExecGitFn = deps?.execGit ?? execGitSeam;
// Derive .planning dir relative to cwd (mirrors planningDir() in core.cjs)
// Derive .planning dir relative to cwd (mirrors planningDir() in planning-workspace.cjs)
const planningDir = path.join(cwd, '.planning');
// 1. Config override

View File

@@ -4,10 +4,8 @@
*
* Extracted from core.cts (ADR-857 rollout phase 1 / issue #859).
* The hand-written bodies are preserved byte-for-behaviour; only the module
* boundary moved. core.cts re-exports every symbol here under its own
* `export =` object so existing consumers are unaffected.
*
* New imports should pull I/O primitives from io.cjs directly.
* boundary moved. The core.cjs re-export spine was retired in epic #1267;
* callers import I/O primitives from io.cjs directly.
*/
import fs from 'node:fs';

View File

@@ -138,7 +138,7 @@ function cmdMilestoneComplete(cwd: string, version: string, options: MilestoneCo
platformEnsureDir(archiveDir);
// Scope stats and accomplishments to only the phases belonging to the
// current milestone's ROADMAP. Uses the shared filter from core.cjs
// current milestone's ROADMAP. Uses the shared filter from roadmap-parser.cjs
// (same logic used by cmdPhasesList and other callers).
const isDirInMilestone = getMilestonePhaseFilter(cwd, version);
if (isDirInMilestone.missingExplicitVersion) {

View File

@@ -6,11 +6,10 @@
* planning granularity, reasoning effort, and fast-mode for a given agent by
* reading project config and resolving against the model profiles and catalog.
* Behaviour is preserved byte-for-behaviour from the prior location; only
* the module boundary moved. core.cjs re-exports the resolvers for back-compat.
* the module boundary moved. The core.cjs re-export spine was retired in
* epic #1267; callers import resolvers from model-resolver.cjs directly.
*
* New imports should pull resolvers from model-resolver.cjs directly.
*
* Dependencies (leaf modules only — no core.cjs):
* Dependencies (leaf modules only):
* - node:fs / node:path (stdlib, not currently needed — included for future use)
* - ./config-loader.cjs (loadConfig)
* - ./configuration.cjs (CONFIG_DEFAULTS as CANONICAL_CONFIG_DEFAULTS)

View File

@@ -4,10 +4,8 @@
*
* Extracted from core.cts (ADR-857 rollout phase 2a / issue #865).
* The hand-written bodies are preserved byte-for-behaviour; only the module
* boundary moved. core.cts re-exports every symbol here under its own
* `export =` object so existing consumers are unaffected.
*
* New imports should pull phase-id helpers from phase-id.cjs directly.
* boundary moved. The core.cjs re-export spine was retired in epic #1267;
* callers import phase-id helpers from phase-id.cjs directly.
*
* Dependencies: none (pure string/regex, no Node built-ins required).
*/

View File

@@ -6,13 +6,10 @@
* (`searchPhaseInDir`, `findPhaseInternal`) and archived-phase-dir
* enumeration (`getArchivedPhaseDirs`), matching phase ids/tokens against
* the filesystem. Behaviour is preserved byte-for-behaviour from the prior
* location; only the module boundary moved. core.cjs re-exports
* `searchPhaseInDir`, `findPhaseInternal`, and `getArchivedPhaseDirs` for back-compat.
* location; only the module boundary moved. The core.cjs re-export spine
* was retired in epic #1267; callers import phase-locator helpers directly.
*
* New imports should pull phase-locator helpers from phase-locator.cjs
* directly.
*
* Dependencies (leaf modules only — no core.cjs, no loadConfig):
* Dependencies (leaf modules only — no loadConfig):
* - node:fs / node:path (stdlib)
* - ./phase-id.cjs (normalizePhaseName, phaseTokenMatches, extractPhaseToken)
* - ./core-utils.cjs (readSubdirectories, getPhaseFileStats, extractCanonicalPlanId, toPosixPath)

View File

@@ -41,7 +41,7 @@
import fs from 'node:fs';
import path from 'node:path';
import { execFileSync } from 'node:child_process';
// Import the leaf I/O module directly, not the core.cjs re-export spine (being retired, #1268).
// Import the leaf I/O module directly (core.cjs re-export spine retired in epic #1267).
// eslint-disable-next-line @typescript-eslint/no-require-imports
import io = require('./io.cjs');
const { output, error, ERROR_REASON } = io;

View File

@@ -5,12 +5,10 @@
* Owns shipped-milestone slicing, current-milestone extraction,
* milestone/phase lookups, and milestone-phase filtering.
* Behaviour is preserved byte-for-behaviour from the prior location;
* only the module boundary moved. core.cjs re-exports every symbol here
* under its own `export =` object so existing consumers are unaffected.
* only the module boundary moved. The core.cjs re-export spine was retired
* in epic #1267; callers import roadmap-parser helpers directly.
*
* New imports should pull roadmap-parser helpers from roadmap-parser.cjs directly.
*
* Dependencies (leaf modules only — no core.cjs, no loadConfig):
* Dependencies (leaf modules only — no loadConfig):
* - node:fs / node:path (stdlib)
* - ./phase-id.cjs (escapeRegex, phaseMarkdownRegexSource)
* - ./planning-workspace.cjs (planningDir)

View File

@@ -251,8 +251,7 @@ function executeWorktreePrunePlan(plan: WorktreePrunePlan | null, deps: Worktree
const result = execGit(['worktree', 'prune'], { cwd: plan.repoRoot });
if (result.timedOut) {
// AC4: surface timedOut as a first-class field so callers (e.g.
// pruneOrphanedWorktrees in core.cjs) can log a structured WARNING rather
// AC4: surface timedOut as a first-class field so callers can log a structured WARNING rather
// than silently ignoring it (PRED.k302 — error-swallowing-empty-sentinel).
return {
ok: false,