Per the T1 design rubber-duck, batch by FILE so each tranche drops convergence-lint allowlist entries. Migrate 12 files' core imports to the leaf modules directly (behaviour-identical — leaves are the objects core re-exports by reference): - io (output/error/ERROR_REASON): agent-command-router, capability-state, capability-writer, frontmatter, gsd2-import, learnings, loop-resolver, task-command-router - roadmap-command-router -> config-loader; workstream-inventory -> core-utils - milestone, verify -> their full leaf sets (both were multi-leaf, not single-leaf as first scoped; migrated completely) All 12 files now import zero core symbols and are removed from the allowlist (30 -> 18). core.cts re-exports untouched (still serve the remaining 18 files); teardown is T-final. Stale core.cjs docstrings in the migrated files corrected to reference io.cjs. No behaviour change. Closes #1281 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,34 +2,22 @@
|
||||
"_comment": "Files allowed to import the core re-export spine during the staged retirement (issue #1268). Entries are REMOVED as each tranche migrates a leaf; the file + this lint are deleted in T-final.",
|
||||
"allow": [
|
||||
"gsd-core/bin/gsd-tools.cjs",
|
||||
"src/agent-command-router.cts",
|
||||
"src/audit-command-router.cts",
|
||||
"src/capability-state.cts",
|
||||
"src/capability-writer.cts",
|
||||
"src/check-command-router.cts",
|
||||
"src/commands.cts",
|
||||
"src/config.cts",
|
||||
"src/docs.cts",
|
||||
"src/frontmatter.cts",
|
||||
"src/gap-checker.cts",
|
||||
"src/graphify-command-router.cts",
|
||||
"src/gsd2-import.cts",
|
||||
"src/init.cts",
|
||||
"src/intel-command-router.cts",
|
||||
"src/learnings.cts",
|
||||
"src/loop-resolver.cts",
|
||||
"src/milestone.cts",
|
||||
"src/phase.cts",
|
||||
"src/profile-output.cts",
|
||||
"src/roadmap-command-router.cts",
|
||||
"src/roadmap.cts",
|
||||
"src/state.cts",
|
||||
"src/task-command-router.cts",
|
||||
"src/template.cts",
|
||||
"src/uat.cts",
|
||||
"src/verification.cts",
|
||||
"src/verify.cts",
|
||||
"src/workstream-inventory.cts",
|
||||
"src/workstream.cts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import core = require('./core.cjs');
|
||||
const { output, error, ERROR_REASON } = core;
|
||||
import io = require('./io.cjs');
|
||||
const { output, error, ERROR_REASON } = io;
|
||||
|
||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
* pure, config-only resolution with no filesystem I/O.
|
||||
* cmdCapabilityState is the I/O handler.
|
||||
*
|
||||
* Dependencies (leaf modules only — no core.cjs circular risk):
|
||||
* Dependencies (leaf modules only — no circular risk):
|
||||
* - node:path
|
||||
* - ./core.cjs (output, error)
|
||||
* - ./io.cjs (output, error)
|
||||
* - ./capability-activation.cjs (_resolveActivationValue)
|
||||
* - ./install-profiles.cjs (readActiveProfile, loadSkillsManifest, resolveProfile)
|
||||
* - ./surface.cjs (resolveSurface)
|
||||
@@ -32,8 +32,8 @@ import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import core = require('./core.cjs');
|
||||
const { output: coreOutput, error: coreError } = core;
|
||||
import ioMod = require('./io.cjs');
|
||||
const { output: coreOutput, error: coreError } = ioMod;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import activationMod = require('./capability-activation.cjs');
|
||||
@@ -363,7 +363,7 @@ function _resolveManifest(commandsGsdDir: string, configDir: string): Map<string
|
||||
|
||||
/**
|
||||
* Command entry point: resolve install profile, surface, and config; compute
|
||||
* capability state; emit the envelope via core.output.
|
||||
* capability state; emit the envelope via io.output.
|
||||
*
|
||||
* Envelope: { runtimeConfigDir, warnings?: string[], capabilities: CapabilityStateEntry[] }
|
||||
*
|
||||
@@ -388,7 +388,7 @@ function _resolveManifest(commandsGsdDir: string, configDir: string): Map<string
|
||||
* Providing a value without a next token (e.g. the flag
|
||||
* is last in argv with no following value) should be
|
||||
* caught by the caller before invoking this function.
|
||||
* @param raw Whether to emit raw JSON (core.output raw mode)
|
||||
* @param raw Whether to emit raw JSON (io.output raw mode)
|
||||
* @param _options Reserved for future use
|
||||
*/
|
||||
function resolveCapabilityRuntimeState(
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* - re-resolve: always calls resolveCapabilityRuntimeState for the return value
|
||||
*
|
||||
* Dependencies (leaf modules only — no circular risk):
|
||||
* - ./core.cjs (output, error)
|
||||
* - ./io.cjs (output, error)
|
||||
* - ./capability-state.cjs (resolveCapabilityRuntimeState, _resolveManifest, _resolveCommandsGsdDir)
|
||||
* - ./surface.cjs (readSurface, writeSurface, applySurface)
|
||||
* - ./install-profiles.cjs (readActiveProfile)
|
||||
@@ -23,8 +23,8 @@
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import core = require('./core.cjs');
|
||||
const { output: coreOutput, error: coreError } = core;
|
||||
import ioMod = require('./io.cjs');
|
||||
const { output: coreOutput, error: coreError } = ioMod;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import capabilityStateMod = require('./capability-state.cjs');
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import core = require('./core.cjs');
|
||||
const { output, error } = core;
|
||||
import ioMod = require('./io.cjs');
|
||||
const { output, error } = ioMod;
|
||||
import { platformReadSync as safeReadFile, platformWriteSync } from './shell-command-projection.cjs';
|
||||
|
||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -24,8 +24,8 @@ import path from 'node:path';
|
||||
import { platformWriteSync } from './shell-command-projection.cjs';
|
||||
import { formatGsdSlash, resolveRuntime } from './runtime-slash.cjs';
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import core = require('./core.cjs');
|
||||
const { output } = core;
|
||||
import ioMod = require('./io.cjs');
|
||||
const { output } = ioMod;
|
||||
|
||||
// ─── Types ───────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ import path from 'node:path';
|
||||
import crypto from 'node:crypto';
|
||||
import os from 'node:os';
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import core = require('./core.cjs');
|
||||
const { output, error: coreError } = core;
|
||||
import ioMod = require('./io.cjs');
|
||||
const { output, error: coreError } = ioMod;
|
||||
import { platformWriteSync } from './shell-command-projection.cjs';
|
||||
|
||||
// ─── Types ───────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
* Both pure functions (resolveLoopHooks, renderLoopHooks) take explicit
|
||||
* registry/config arguments so they are trivially testable without I/O.
|
||||
*
|
||||
* Dependencies (leaf modules only — no core.cjs circular risk):
|
||||
* Dependencies (leaf modules only — no circular risk):
|
||||
* - node:fs / node:path (raw config.json read for capability-key activation)
|
||||
* - ./config-loader.cjs (loadConfig)
|
||||
* - ./planning-workspace.cjs (planningDir — to locate config.json)
|
||||
* - ./core.cjs (output, error)
|
||||
* - ./io.cjs (output, error)
|
||||
* - loop-host-contract.cjs (CANONICAL_POINTS via LOOP_HOST_CONTRACT)
|
||||
* - capability-registry.cjs (byLoopPoint, consumed at call time)
|
||||
*/
|
||||
@@ -32,8 +32,8 @@ import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import core = require('./core.cjs');
|
||||
const { output: coreOutput, error: coreError } = core;
|
||||
import ioMod = require('./io.cjs');
|
||||
const { output: coreOutput, error: coreError } = ioMod;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import configLoaderModule = require('./config-loader.cjs');
|
||||
@@ -284,7 +284,7 @@ interface ResolveLoopHooksResult {
|
||||
* Pure resolver: given a point, registry, and config, returns the active hooks.
|
||||
*
|
||||
* Throws if `point` is not one of the 12 canonical points (caller converts to
|
||||
* core.error). Never throws for malformed registry/hook entries — skips and
|
||||
* io.error). Never throws for malformed registry/hook entries — skips and
|
||||
* continues.
|
||||
*
|
||||
* Ordering: steps first, then contributions, then gates. Within each array,
|
||||
@@ -571,7 +571,7 @@ function renderLoopHooks(resolved: ResolveLoopHooksResult): string {
|
||||
* Command entry point: load registry + config, resolve + render, emit envelope.
|
||||
*
|
||||
* Envelope: { point, activeHooks, rendered }
|
||||
* On invalid point, emits core.error instead of throwing.
|
||||
* On invalid point, emits io.error instead of throwing.
|
||||
*
|
||||
* Config note: FIX 1 replaced _loadMergedConfig (whole-config deep-merge) with a
|
||||
* per-hook single-key activation resolver (_resolveActivationValue). The resolver
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports -- core.cjs is an export= CommonJS module
|
||||
import core = require('./core.cjs');
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports -- planning-workspace.cjs is an export= CommonJS module
|
||||
import planningWorkspace = require('./planning-workspace.cjs');
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports -- frontmatter.cjs is an export= CommonJS module
|
||||
@@ -18,16 +16,18 @@ import frontmatterMod = require('./frontmatter.cjs');
|
||||
import stateMod = require('./state.cjs');
|
||||
import { platformWriteSync, platformEnsureDir } from './shell-command-projection.cjs';
|
||||
import { formatGsdSlash, resolveRuntime } from './runtime-slash.cjs';
|
||||
|
||||
const {
|
||||
escapeRegex,
|
||||
getMilestonePhaseFilter,
|
||||
extractOneLinerFromBody,
|
||||
normalizePhaseName,
|
||||
phaseTokenMatches,
|
||||
output,
|
||||
error,
|
||||
} = core;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import ioMod = require('./io.cjs');
|
||||
const { output, error } = ioMod;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import phaseIdMod = require('./phase-id.cjs');
|
||||
const { escapeRegex, normalizePhaseName, phaseTokenMatches } = phaseIdMod;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import roadmapParserMod = require('./roadmap-parser.cjs');
|
||||
const { getMilestonePhaseFilter, extractCurrentMilestone } = roadmapParserMod;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import coreUtilsMod = require('./core-utils.cjs');
|
||||
const { extractOneLinerFromBody } = coreUtilsMod;
|
||||
const { planningPaths } = planningWorkspace;
|
||||
const { extractFrontmatter } = frontmatterMod;
|
||||
const { writeStateMd, stateReplaceFieldWithFallback } = stateMod;
|
||||
@@ -167,7 +167,6 @@ function cmdMilestoneComplete(cwd: string, version: string, options: MilestoneCo
|
||||
}
|
||||
|
||||
if (stateVersion && stateVersion === version) {
|
||||
const { extractCurrentMilestone } = core;
|
||||
const roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
|
||||
const scopedContent = extractCurrentMilestone(roadmapContent, cwd);
|
||||
const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi;
|
||||
|
||||
@@ -19,8 +19,8 @@ import roadmapUpgrade = require('./roadmap-upgrade.cjs');
|
||||
import planningWorkspace = require('./planning-workspace.cjs');
|
||||
const { planningDir } = planningWorkspace;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import core = require('./core.cjs');
|
||||
const { loadConfig } = core;
|
||||
import configLoaderMod = require('./config-loader.cjs');
|
||||
const { loadConfig } = configLoaderMod;
|
||||
|
||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import core = require('./core.cjs');
|
||||
const { output, error, ERROR_REASON } = core;
|
||||
import ioMod = require('./io.cjs');
|
||||
const { output, error, ERROR_REASON } = ioMod;
|
||||
|
||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@ import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import { phaseVariants, buildRoadmapPhaseVariants, buildNotStartedPhaseVariants } from './validate.cjs';
|
||||
import { phaseDirNameRe, PHASE_TOKEN_FROM_DIR_RE, MILESTONE_ARCHIVE_DIR_RE, canonicalPlanStem } from './validate.cjs';
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports -- core.cjs is an export= CommonJS module
|
||||
import core = require('./core.cjs');
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports -- planning-workspace.cjs is an export= CommonJS module
|
||||
import planningWorkspace = require('./planning-workspace.cjs');
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports -- frontmatter.cjs is an export= CommonJS module
|
||||
@@ -31,21 +29,24 @@ import { isCanonicalPlanningFile } from './artifacts.cjs';
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports -- agent-install-check.cjs is an export= CommonJS module
|
||||
import agentInstallCheck = require('./agent-install-check.cjs');
|
||||
const { checkAgentsInstalled } = agentInstallCheck;
|
||||
|
||||
const {
|
||||
loadConfig,
|
||||
normalizePhaseName,
|
||||
phaseTokenMatches,
|
||||
escapeRegex,
|
||||
findPhaseInternal,
|
||||
getMilestoneInfo,
|
||||
stripShippedMilestones,
|
||||
extractCurrentMilestone,
|
||||
output,
|
||||
error,
|
||||
CONFIG_DEFAULTS,
|
||||
inspectWorktreeHealth,
|
||||
} = core;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import ioMod = require('./io.cjs');
|
||||
const { output, error } = ioMod;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import configLoaderMod = require('./config-loader.cjs');
|
||||
const { loadConfig, CONFIG_DEFAULTS } = configLoaderMod;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import phaseIdMod = require('./phase-id.cjs');
|
||||
const { normalizePhaseName, phaseTokenMatches, escapeRegex, getMilestoneFromPhaseId } = phaseIdMod;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import phaseLocatorMod = require('./phase-locator.cjs');
|
||||
const { findPhaseInternal } = phaseLocatorMod;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import roadmapParserMod = require('./roadmap-parser.cjs');
|
||||
const { getMilestoneInfo, stripShippedMilestones, extractCurrentMilestone } = roadmapParserMod;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import worktreeSafetyMod = require('./worktree-safety.cjs');
|
||||
const { inspectWorktreeHealth } = worktreeSafetyMod;
|
||||
|
||||
const { planningDir } = planningWorkspace;
|
||||
const { extractFrontmatter, parseMustHavesBlock } = frontmatterMod;
|
||||
@@ -1402,7 +1403,6 @@ function cmdValidateHealth(
|
||||
if (phaseConvention === 'milestone-prefixed') {
|
||||
if (fs.existsSync(roadmapPath)) {
|
||||
const roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
|
||||
const { getMilestoneFromPhaseId } = core;
|
||||
const mismatches = checkMilestonePrefixMismatches(roadmapContent, {
|
||||
getMilestoneFromPhaseId: getMilestoneFromPhaseId,
|
||||
});
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import core = require('./core.cjs');
|
||||
const { readSubdirectories } = core;
|
||||
import coreUtilsMod = require('./core-utils.cjs');
|
||||
const { readSubdirectories } = coreUtilsMod;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import planScan = require('./plan-scan.cjs');
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
|
||||
Reference in New Issue
Block a user