phasegate 0.340.0 → 0.341.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/docs/folder_management_rules.md +10 -1
  3. package/docs/guide/cli-reference.md +23 -3
  4. package/docs/guide/configuration.md +28 -2
  5. package/docs/guide/hooks-integration.md +7 -1
  6. package/docs/guide/skills-overview.md +3 -0
  7. package/package.json +2 -1
  8. package/scripts/harness/agent-integration/application/usecases/handle-post-tool-use-usecase.ts +4 -0
  9. package/scripts/harness/agent-integration/application/usecases/handle-pre-tool-use-usecase.ts +36 -1
  10. package/scripts/harness/agent-integration/application/usecases/handle-stop-usecase.ts +3 -9
  11. package/scripts/harness/agent-integration/domain/ports/story-reflection-query-port.ts +2 -0
  12. package/scripts/harness/agent-integration/domain/services/hook-to-cli-translator.ts +8 -5
  13. package/scripts/harness/agent-integration/domain/value-objects/hook-translation-result.ts +1 -1
  14. package/scripts/harness/agent-integration/domain/value-objects/story-reflection-query-result.ts +10 -2
  15. package/scripts/harness/agent-integration/domain/value-objects/write-target-scope.ts +12 -0
  16. package/scripts/harness/agent-integration/infrastructure/adapters/child-process-cli-executor-adapter.ts +64 -13
  17. package/scripts/harness/agent-integration/infrastructure/adapters/file-system-story-reflection-query-adapter.ts +108 -2
  18. package/scripts/harness/agent-integration/infrastructure/adapters/harness-config-config-query-adapter.ts +8 -6
  19. package/scripts/harness/agent-integration/presentation/hook-skip-event-recorder.ts +3 -0
  20. package/scripts/harness/agent-integration/presentation/post-tool-use-feedback.ts +39 -0
  21. package/scripts/harness/agent-integration/presentation/post-tool-use-hook.ts +20 -27
  22. package/scripts/harness/agent-integration/presentation/pre-tool-use-hook.ts +3 -0
  23. package/scripts/harness/agent-integration/presentation/stop-hook.ts +1 -3
  24. package/scripts/harness/biome-ast-engine/infrastructure/adapters/biome-cli-executor-adapter.ts +21 -1
  25. package/scripts/harness/biome-ast-engine/infrastructure/adapters/typescript-source-module-analyzer-adapter.ts +5 -0
  26. package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json +15 -0
  27. package/scripts/harness/config-foundation/infrastructure/validators/ajv-config-schema-validator.ts +6 -3
  28. package/scripts/harness/harness-api/domain/ports/biome-lint-port.ts +2 -1
  29. package/scripts/harness/harness-api/domain/services/command-dispatch-service.ts +12 -1
  30. package/scripts/harness/harness-api/infrastructure/adapters/biome-ast-engine-lint-adapter.ts +10 -2
  31. package/scripts/harness/installation/application/bundled-skill-selection.ts +28 -2
  32. package/scripts/harness/installation/application/checks/check-utils.ts +2 -2
  33. package/scripts/harness/installation/application/usecases/run-install.ts +5 -5
  34. package/scripts/harness/installation/application/usecases/run-reconcile.ts +62 -21
  35. package/scripts/harness/installation/presentation/cli/install-handler.ts +2 -1
  36. package/scripts/harness/main.ts +128 -90
  37. package/scripts/harness/phase-dependency-model/domain/services/story-reflection-checker.ts +48 -5
  38. package/scripts/harness/phase-dependency-model/domain/services/work-item-reflection-scope-resolver.ts +64 -0
  39. package/scripts/harness/phase-dependency-model/domain/values/story-reflection-mapping.ts +8 -2
  40. package/scripts/harness/phase-dependency-model/infrastructure/filesystem/file-system-story-reflection-adapter.ts +6 -1
  41. package/scripts/harness/phase-dependency-model/infrastructure/filesystem/file-system-work-item-dependency-catalog.ts +73 -0
  42. package/scripts/harness/quick-mode/application/dto/change-category-classification-contract.ts +4 -0
  43. package/scripts/harness/quick-mode/application/ports/change-risk-advisory-port.ts +16 -0
  44. package/scripts/harness/quick-mode/composition-root.ts +5 -1
  45. package/scripts/harness/quick-mode/infrastructure/adapters/snapshot-risk-advisory-adapter.ts +118 -0
  46. package/scripts/harness/quick-mode/presentation/formatters/change-category-formatter.ts +7 -0
  47. package/scripts/harness/quick-mode/presentation/handlers/check-change-category-handler.ts +12 -1
  48. package/scripts/harness/setup/skill-deployer.ts +3 -45
  49. package/scripts/harness/skill-quality/application/dto/run-plan-checker-loop-output.ts +1 -0
  50. package/scripts/harness/skill-quality/application/usecases/apply-cascade-update-usecase.ts +9 -4
  51. package/scripts/harness/skill-quality/application/usecases/execute-tdd-cycle-usecase.ts +2 -1
  52. package/scripts/harness/skill-quality/application/usecases/run-plan-checker-loop-usecase.ts +8 -0
  53. package/scripts/harness/skill-quality/composition-root.ts +14 -7
  54. package/scripts/harness/skill-quality/domain/ports/plan-check-executor-port.ts +2 -0
  55. package/scripts/harness/skill-quality/domain/value-objects/cascade-update-target.ts +15 -1
  56. package/scripts/harness/skill-quality/infrastructure/adapters/l1-biome-validator-adapter.ts +9 -1
  57. package/scripts/harness/skill-quality/infrastructure/adapters/l2-validator-system-adapter.ts +18 -2
  58. package/scripts/harness/skill-quality/presentation/handlers/apply-cascade-update-handler.ts +8 -2
  59. package/scripts/harness/skill-quality/presentation/handlers/execute-tdd-cycle-handler.ts +4 -3
  60. package/scripts/harness/skill-quality/presentation/handlers/run-plan-checker-loop-handler.ts +11 -4
  61. package/scripts/harness/traceability-model/infrastructure/parsers/work-item-frontmatter-parser.ts +41 -0
  62. package/skills/README.md +7 -0
  63. package/skills/cascade-updater/SKILL.md +37 -109
  64. package/skills/cascade-updater/references//345/261/244/345/210/245/345/210/244/345/256/232/343/202/254/343/202/244/343/203/211.md +5 -3
  65. package/skills/release-publisher/SKILL.md +3 -1
  66. package/skills/skill-creator/SKILL.md +8 -9
@@ -45,9 +45,8 @@ import {
45
45
  } from "node:fs/promises";
46
46
  import { basename, dirname, join, resolve } from "node:path";
47
47
  import { fileURLToPath } from "node:url";
48
- import { createAdrFoundationModule } from "./adr-foundation/composition-root.js";
49
48
  import { createBiomeAstEngineModule } from "./biome-ast-engine/composition-root.js";
50
- import { buildCiGovernance, type CiGovernanceDocPaths } from "./ci-governance/composition-root.js";
49
+ import type { CiGovernanceDocPaths } from "./ci-governance/composition-root.js";
51
50
  import { toPhaseConfigSection } from "./config-foundation/application/mappers/phase-config-section-mapper.js";
52
51
  import { toValidatorSystemConfig } from "./config-foundation/application/mappers/validator-system-config-mapper.js";
53
52
  import { toWorldModelConfig } from "./config-foundation/application/mappers/world-model-config-mapper.js";
@@ -59,16 +58,13 @@ import {
59
58
  ConfigPersistenceError,
60
59
  } from "./config-foundation/infrastructure/repositories/file-system-config-repository.js";
61
60
  import { createHarnessApiModule } from "./harness-api/composition-root.js";
62
- import { createHarnessErrorModule } from "./harness-error/composition-root.js";
63
61
  import {
64
62
  type DeployManifestRecord,
65
63
  SkillDeployerManifestBuilder,
66
64
  } from "./installation/application/wrappers/skill-deployer-manifest-builder.js";
67
- import { createInstallationModule } from "./installation/composition-root.js";
68
65
  import { type AgentTarget, isAgentTarget } from "./installation/domain/agent-target.js";
69
66
  import { NodeCryptoHashAdapter } from "./installation/infrastructure/adapters/node-crypto-hash-adapter.js";
70
67
  import { CheckStoryReflectionUseCase } from "./phase-dependency-model/application/usecases/check-story-reflection-usecase.js";
71
- import { createPhaseDependencyModelModule } from "./phase-dependency-model/composition-root.js";
72
68
  import { StoryReflectionChecker } from "./phase-dependency-model/domain/services/story-reflection-checker.js";
73
69
  import { StoryReflectionResult } from "./phase-dependency-model/domain/values/story-reflection-result.js";
74
70
  import {
@@ -77,10 +73,9 @@ import {
77
73
  } from "./phase-dependency-model/infrastructure/config/harness-config-phase-config-provider.js";
78
74
  import { FileSystemStoryReflectionAdapter } from "./phase-dependency-model/infrastructure/filesystem/file-system-story-reflection-adapter.js";
79
75
  import { StoryReflectionStatusPresenter } from "./phase-dependency-model/presentation/cli/story-reflection-status-presenter.js";
80
- import { buildPhase2Extensions } from "./phase2-extensions/composition-root.js";
81
- import { createQuickModeCompositionRoot, type QuickModeCompositionRootOptions } from "./quick-mode/composition-root.js";
82
- import { buildRegressionSuite } from "./regression-suite/composition-root.js";
76
+ import type { QuickModeCompositionRootOptions } from "./quick-mode/composition-root.js";
83
77
  import type { SkillSet } from "./setup/skill-deployer.js";
78
+ import { isSkillSet } from "./installation/application/bundled-skill-selection.js";
84
79
  import {
85
80
  deployAgentSkillLinks,
86
81
  deployCiWorkflows,
@@ -97,11 +92,7 @@ import {
97
92
  initHarnessConfig,
98
93
  listAvailableSkillNames,
99
94
  } from "./setup/skill-deployer.js";
100
- import { createSkillQualityHandlers } from "./skill-quality/composition-root.js";
101
- import { createTraceabilityModelModule } from "./traceability-model/composition-root.js";
102
- import { createValidatorSystemModule } from "./validator-system/composition-root.js";
103
- import {
104
- createWorldModelModule,
95
+ import type {
105
96
  WorldDeriveCommandHandler,
106
97
  WorldInspectCommandHandler,
107
98
  WorldPinCommandHandler,
@@ -210,7 +201,7 @@ Usage: phasegate <command> [options]
210
201
  Setup:
211
202
  init Initialize project: deploy skills + design docs + phasegate.config.json
212
203
  (--name <project-name>, --preset <full|standard|minimal|custom>,
213
- --skills <core|all>, --agent <claude|codex|both|grok|antigravity|all>, --workflow <standard|strict>,
204
+ --skills <core|consumer|all>, --agent <claude|codex|both|grok|antigravity|all>, --workflow <standard|strict>,
214
205
  --language <language>, --with-husky, --with-ci, --yes)
215
206
  update-skills Alias for reconcile (kept for compatibility)
216
207
  doctor Diagnose silent installation failures (--json, --strict, --personal, --agent <claude|codex|both|grok|antigravity|all>, --report-out <path>)
@@ -283,7 +274,7 @@ Gate semantics:
283
274
  session begin Start a Full Mode session (--mode full, --unit, --work-item, --reason, --duration)
284
275
  session end End a Full Mode session (--work-item)
285
276
 
286
- skill:execute-tdd-cycle Execute TDD cycle (--unit, --story, --desc, --phase RED|GREEN|REFACTOR, --passed)
277
+ skill:execute-tdd-cycle Execute TDD cycle (--unit, --story, --desc, --phase RED|GREEN|REFACTOR, --passed, optional --configured-validation)
287
278
  skill:check-coverage Check coverage (--story <storyId>, --json)
288
279
  skill:collect-lessons Collect lessons (--story <storyId>, --sources <paths>, --write-artifact)
289
280
  skill:apply-cascade-update Apply cascade update (--story <storyId>, --dry-run)
@@ -495,7 +486,7 @@ async function saveInstallationManifest(
495
486
  ): Promise<void> {
496
487
  const filteredRecords = (await Promise.all(records)).filter((record) => record !== null);
497
488
  if (filteredRecords.length === 0) return;
498
- const mod = createInstallationModule();
489
+ const mod = (await import("./installation/composition-root.js")).createInstallationModule();
499
490
  const builder = new SkillDeployerManifestBuilder(new NodeCryptoHashAdapter());
500
491
  await mod.manifestRepository.save(rootDir, builder.build(version, filteredRecords));
501
492
  }
@@ -707,7 +698,7 @@ Initialize phasegate in the current project: deploy skills + design docs + phase
707
698
  Options:
708
699
  --name <project-name> Project name (default: "my-project")
709
700
  --preset <full|standard|minimal|custom> Phase dependency preset (default: "standard")
710
- --skills <core|all> Skill set to deploy (default: "all")
701
+ --skills <core|consumer|all> Skill set to deploy (default: "all"; consumer excludes maintainer skills)
711
702
  --agent <claude|codex|both|grok|antigravity|all> Agent integration target (default: "claude")
712
703
  --workflow <standard|strict> Workflow enforcement defaults (default: "standard")
713
704
  --language <language> Project language declaration (default: "typescript")
@@ -735,7 +726,7 @@ Options:
735
726
  --apply Write merge results and manifest
736
727
  --force Force ai-assisted/manual targets after backing up existing files
737
728
  --agent <claude|codex|both|grok|antigravity|all> Agent context and hook targets (default: both)
738
- --skills <core|all> Rendered agent context skill mode (default: all)
729
+ --skills <core|consumer|all> Skill set to deploy (default: all; consumer excludes maintainer skills)
739
730
  --workflow <standard|strict> Rendered agent context workflow mode (default: standard)
740
731
  --with-husky Include Husky hook targets (opt-in; omitted by default)
741
732
  --with-ci Include GitHub Actions target (opt-in; omitted by default)
@@ -902,6 +893,7 @@ Options:
902
893
  --paths <csv> Comma-separated file paths to classify.
903
894
  --format <human|json> Output format. Default: human.
904
895
  --fail-on-full-required Exit with code 1 when Full Mode is required.
896
+ --risk-snapshots <json> Optional before/after snapshots for advisory review; does not change gates.
905
897
  --help, -h Show this help.
906
898
 
907
899
  Examples:
@@ -1567,11 +1559,7 @@ function isPlainRecord(value: unknown): value is Record<string, unknown> {
1567
1559
  }
1568
1560
 
1569
1561
  async function readProjectJson(rootDir: string, relativePath: string): Promise<unknown | null> {
1570
- try {
1571
- return JSON.parse(await fsReadFile(join(rootDir, relativePath), "utf8")) as unknown;
1572
- } catch {
1573
- return null;
1574
- }
1562
+ return JSON.parse(await fsReadFile(join(rootDir, relativePath), "utf8")) as unknown;
1575
1563
  }
1576
1564
 
1577
1565
  function withNestedValue(source: unknown, path: readonly string[], value: unknown): Record<string, unknown> {
@@ -1595,7 +1583,7 @@ function getNestedValue(source: unknown, path: readonly string[]): unknown {
1595
1583
  return cursor;
1596
1584
  }
1597
1585
 
1598
- function buildConfigPatchPreview(intent: ConfigChangeIntent, before: unknown | null): ConfigPatchPreview {
1586
+ function buildConfigPatchPreview(intent: ConfigChangeIntent, before: unknown | null, missing = false): ConfigPatchPreview {
1599
1587
  const configIntents: Record<
1600
1588
  ConfigChangeIntent,
1601
1589
  readonly { readonly pointer: string; readonly path: readonly string[]; readonly value: unknown }[]
@@ -1639,6 +1627,16 @@ function buildConfigPatchPreview(intent: ConfigChangeIntent, before: unknown | n
1639
1627
  operations: [],
1640
1628
  };
1641
1629
  }
1630
+ if (!isPlainRecord(before) && !missing) {
1631
+ return {
1632
+ path: "phasegate.config.json",
1633
+ applicability: "blocked",
1634
+ blockedReason: "An existing JSON object configuration is required. Review phasegate install --dry-run before initialization, or restore a valid configuration before retrying.",
1635
+ before,
1636
+ after: before,
1637
+ operations: [],
1638
+ };
1639
+ }
1642
1640
  let after: unknown = before;
1643
1641
  const operations: ConfigPatchOperation[] = [];
1644
1642
  for (const change of changes) {
@@ -1674,6 +1672,9 @@ async function applyConfigPlan(
1674
1672
  if (patch.applicability !== "applicable") {
1675
1673
  throw new Error(`config plan is not applicable: ${patch.blockedReason ?? patch.applicability}`);
1676
1674
  }
1675
+ if (!isPlainRecord(patch.before)) {
1676
+ throw new Error("phasegate.config.json is missing. Review phasegate install --dry-run before initialization; config:plan does not create a partial configuration.");
1677
+ }
1677
1678
  if (patch.operations.length === 0) {
1678
1679
  throw new Error("config plan has no operations to apply.");
1679
1680
  }
@@ -1682,13 +1683,16 @@ async function applyConfigPlan(
1682
1683
  }
1683
1684
 
1684
1685
  const configPath = join(rootDir, patch.path);
1686
+ const beforeText = await fsReadFile(configPath, "utf8");
1687
+ if (JSON.stringify(JSON.parse(beforeText)) !== JSON.stringify(patch.before)) {
1688
+ throw new Error("phasegate.config.json changed after planning. Review config:plan --dry-run again before applying; no configuration was changed.");
1689
+ }
1685
1690
  const backupPath = configPlanBackupPath(rootDir, new Date());
1686
1691
  await fsMkdir(dirname(backupPath), { recursive: true });
1687
- const beforeText = patch.before === null ? "" : `${JSON.stringify(patch.before, null, 2)}\n`;
1688
- await fsWriteFile(backupPath, beforeText, "utf8");
1692
+ await fsWriteFile(backupPath, beforeText, { encoding: "utf8", flag: "wx" });
1689
1693
 
1690
1694
  const tempPath = `${configPath}.tmp-${process.pid}-${Date.now()}`;
1691
- await fsWriteFile(tempPath, `${JSON.stringify(patch.after, null, 2)}\n`, "utf8");
1695
+ await fsWriteFile(tempPath, `${JSON.stringify(patch.after, null, 2)}\n`, { encoding: "utf8", flag: "wx" });
1692
1696
  await fsRename(tempPath, configPath);
1693
1697
 
1694
1698
  return {
@@ -1829,11 +1833,31 @@ async function buildConfigChangePlan(rootDir: string, intent: ConfigChangeIntent
1829
1833
  ],
1830
1834
  },
1831
1835
  };
1832
- const before = await readProjectJson(rootDir, "phasegate.config.json");
1836
+ let before: unknown = null;
1837
+ let readFailure: string | undefined;
1838
+ let missing = false;
1839
+ try {
1840
+ before = await readProjectJson(rootDir, "phasegate.config.json");
1841
+ } catch (error) {
1842
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") {
1843
+ missing = true;
1844
+ } else if (error instanceof SyntaxError) {
1845
+ readFailure = "Cannot parse phasegate.config.json. Restore valid JSON from version control or a known-good backup through an authorized recovery path, then preview again. The original file has not been changed.";
1846
+ } else {
1847
+ readFailure = `Cannot read phasegate.config.json. Check file access permissions before retrying. The original file has not been changed. ${error instanceof Error ? error.message : String(error)}`;
1848
+ }
1849
+ }
1850
+ let configPatch = buildConfigPatchPreview(intent, before, missing);
1851
+ if (readFailure && configPatch.applicability !== "not-applicable") {
1852
+ configPatch = { ...configPatch, applicability: "blocked", blockedReason: readFailure, after: before, operations: [] };
1853
+ }
1833
1854
  return {
1834
1855
  intent,
1835
1856
  ...catalog[intent],
1836
- configPatch: buildConfigPatchPreview(intent, before),
1857
+ commands: missing && configPatch.applicability === "applicable"
1858
+ ? ["phasegate install --dry-run", ...catalog[intent].commands]
1859
+ : catalog[intent].commands,
1860
+ configPatch,
1837
1861
  diffExplanation:
1838
1862
  "Review the listed targets first, apply through PhaseGate managed commands where possible, then run the validations in order.",
1839
1863
  rollback: "Use git diff for config changes; use phasegate uninstall/reconcile dry-runs for managed setup targets.",
@@ -2143,8 +2167,8 @@ async function main(): Promise<void> {
2143
2167
  }
2144
2168
  const phasePreset = parseInitPhasePreset(rawPhasePreset);
2145
2169
  const skillSetRaw = parseFlag(args, "--skills") ?? "all";
2146
- if (skillSetRaw !== "core" && skillSetRaw !== "all") {
2147
- console.error(`Invalid --skills value: "${skillSetRaw}". Use "core" or "all".`);
2170
+ if (!isSkillSet(skillSetRaw)) {
2171
+ console.error(`Invalid --skills value: "${skillSetRaw}". Use "core", "consumer", or "all".`);
2148
2172
  process.exit(2);
2149
2173
  }
2150
2174
  const skillSet: SkillSet = skillSetRaw;
@@ -2226,7 +2250,7 @@ async function main(): Promise<void> {
2226
2250
  huskyPrePushResult?.created ? await createFileManifestRecord(rootDir, join(".husky", "pre-push")) : null,
2227
2251
  ...(ciWorkflowResult?.copiedFiles.map((path) => createFileManifestRecord(rootDir, path)) ?? []),
2228
2252
  ]);
2229
- const installModule = createInstallationModule();
2253
+ const installModule = (await import("./installation/composition-root.js")).createInstallationModule();
2230
2254
  const installResult = await installModule.runInstallUseCase.execute({
2231
2255
  projectRoot: rootDir,
2232
2256
  harnessRoot,
@@ -2390,7 +2414,7 @@ async function main(): Promise<void> {
2390
2414
  }
2391
2415
  const apply = hasFlag(args, "--apply");
2392
2416
  const dryRun = hasFlag(args, "--dry-run") || !apply;
2393
- const mod = createInstallationModule();
2417
+ const mod = (await import("./installation/composition-root.js")).createInstallationModule();
2394
2418
  const phasegateVersion = await getHarnessVersion(harnessRoot);
2395
2419
  const result = await mod.reconcileHandler.execute({
2396
2420
  projectRoot: rootDir,
@@ -2419,7 +2443,7 @@ async function main(): Promise<void> {
2419
2443
  console.error(`Invalid --agent value: "${parseFlag(args, "--agent")}". Use <${AGENT_TARGET_USAGE}>.`);
2420
2444
  process.exit(2);
2421
2445
  }
2422
- const mod = createInstallationModule();
2446
+ const mod = (await import("./installation/composition-root.js")).createInstallationModule();
2423
2447
  const phasegateVersion = await getHarnessVersion(harnessRoot);
2424
2448
  const result = await mod.doctorHandler.execute({
2425
2449
  projectRoot: rootDir,
@@ -2493,8 +2517,8 @@ async function main(): Promise<void> {
2493
2517
  process.exit(2);
2494
2518
  }
2495
2519
  const skillSetRaw = parseFlag(args, "--skills") ?? "all";
2496
- if (skillSetRaw !== "core" && skillSetRaw !== "all") {
2497
- console.error(`Invalid --skills value: "${skillSetRaw}". Use "core" or "all".`);
2520
+ if (!isSkillSet(skillSetRaw)) {
2521
+ console.error(`Invalid --skills value: "${skillSetRaw}". Use "core", "consumer", or "all".`);
2498
2522
  process.exit(2);
2499
2523
  }
2500
2524
  const workflowRaw = parseFlag(args, "--workflow");
@@ -2505,7 +2529,7 @@ async function main(): Promise<void> {
2505
2529
  const includeClaude = agent === "claude" || agent === "both" || agent === "grok" || agent === "all";
2506
2530
  const includeCodex = agent === "codex" || agent === "both" || agent === "all";
2507
2531
  const personal = hasFlag(args, "--personal");
2508
- const mod = createInstallationModule();
2532
+ const mod = (await import("./installation/composition-root.js")).createInstallationModule();
2509
2533
  const phasegateVersion = await getHarnessVersion(harnessRoot);
2510
2534
  const result = await mod.installHandler.execute({
2511
2535
  projectRoot: rootDir,
@@ -2578,7 +2602,7 @@ async function main(): Promise<void> {
2578
2602
  packageDependency: packageResult,
2579
2603
  configCreated: configResult.created,
2580
2604
  };
2581
- const mod = createInstallationModule();
2605
+ const mod = (await import("./installation/composition-root.js")).createInstallationModule();
2582
2606
  const phasegateVersion = await getHarnessVersion(harnessRoot);
2583
2607
  installResult = await mod.runInstallUseCase.execute({
2584
2608
  projectRoot: rootDir,
@@ -2745,7 +2769,7 @@ async function main(): Promise<void> {
2745
2769
  }
2746
2770
  const apply = hasFlag(args, "--apply");
2747
2771
  const dryRun = hasFlag(args, "--dry-run") || !apply;
2748
- const mod = createInstallationModule();
2772
+ const mod = (await import("./installation/composition-root.js")).createInstallationModule();
2749
2773
  const result = await mod.uninstallHandler.execute({
2750
2774
  projectRoot: rootDir,
2751
2775
  harnessRoot,
@@ -2768,7 +2792,7 @@ async function main(): Promise<void> {
2768
2792
  }
2769
2793
  const apply = hasFlag(args, "--apply");
2770
2794
  const dryRun = hasFlag(args, "--dry-run") || !apply;
2771
- const mod = createInstallationModule();
2795
+ const mod = (await import("./installation/composition-root.js")).createInstallationModule();
2772
2796
  const phasegateVersion = await getHarnessVersion(harnessRoot);
2773
2797
  const result = await mod.reconcileHandler.execute({
2774
2798
  projectRoot: rootDir,
@@ -2827,7 +2851,7 @@ async function main(): Promise<void> {
2827
2851
 
2828
2852
  case "migrate": {
2829
2853
  if (args[1] === "work-items") {
2830
- const mod = createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
2854
+ const mod = (await import("./traceability-model/composition-root.js")).createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
2831
2855
  const result = await mod.migrateWorkItemsCommandHandler.execute({
2832
2856
  dryRun: hasFlag(args, "--dry-run"),
2833
2857
  apply: hasFlag(args, "--apply"),
@@ -2851,7 +2875,7 @@ async function main(): Promise<void> {
2851
2875
 
2852
2876
  // ── harness-error ──
2853
2877
  case "render-errors": {
2854
- const mod = createHarnessErrorModule(rootDir);
2878
+ const mod = (await import("./harness-error/composition-root.js")).createHarnessErrorModule(rootDir);
2855
2879
  const format = toRenderFormat(parseFlag(args, "--format") ?? "human");
2856
2880
  const failOnError = hasFlag(args, "--fail-on-error");
2857
2881
  const result = mod.renderHarnessErrorsHandler.execute({
@@ -2865,7 +2889,7 @@ async function main(): Promise<void> {
2865
2889
  }
2866
2890
 
2867
2891
  case "validate-fix": {
2868
- const mod = createHarnessErrorModule(rootDir);
2892
+ const mod = (await import("./harness-error/composition-root.js")).createHarnessErrorModule(rootDir);
2869
2893
  const code = parseFlag(args, "--code");
2870
2894
  const failFast = hasFlag(args, "--fail-fast");
2871
2895
  const format = toListFormat(parseFlag(args, "--format") ?? "human");
@@ -2880,7 +2904,7 @@ async function main(): Promise<void> {
2880
2904
  }
2881
2905
 
2882
2906
  case "list-errors": {
2883
- const mod = createHarnessErrorModule(rootDir);
2907
+ const mod = (await import("./harness-error/composition-root.js")).createHarnessErrorModule(rootDir);
2884
2908
  const format = toListFormat(parseFlag(args, "--format") ?? "human");
2885
2909
  const layer = toLayerFilter(parseFlag(args, "--layer"));
2886
2910
  const result = await mod.listErrorDefinitionsHandler.execute({
@@ -2894,7 +2918,7 @@ async function main(): Promise<void> {
2894
2918
 
2895
2919
  // ── traceability-model ──
2896
2920
  case "validate-metadata": {
2897
- const mod = createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
2921
+ const mod = (await import("./traceability-model/composition-root.js")).createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
2898
2922
  const filePaths = parsePositionalArgs(args.slice(1));
2899
2923
  const result = await mod.validateMetadataCommandHandler.execute({
2900
2924
  filePaths,
@@ -2906,7 +2930,7 @@ async function main(): Promise<void> {
2906
2930
  }
2907
2931
 
2908
2932
  case "work-items:status": {
2909
- const mod = createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
2933
+ const mod = (await import("./traceability-model/composition-root.js")).createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
2910
2934
  const result = await mod.workItemStatusCommandHandler.execute({
2911
2935
  dryRun: hasFlag(args, "--dry-run"),
2912
2936
  apply: hasFlag(args, "--apply"),
@@ -2925,12 +2949,12 @@ async function main(): Promise<void> {
2925
2949
  case "world:inspect": {
2926
2950
  let handler: WorldInspectCommandHandler;
2927
2951
  try {
2928
- handler = createWorldModelModule({
2952
+ handler = (await import("./world-model/index.js")).createWorldModelModule({
2929
2953
  rootDir,
2930
2954
  resolvedConfig: await loadWorldResolvedConfig(),
2931
2955
  }).worldInspectCommandHandler;
2932
2956
  } catch (error) {
2933
- handler = WorldInspectCommandHandler.fromFailure(error);
2957
+ handler = (await import("./world-model/index.js")).WorldInspectCommandHandler.fromFailure(error);
2934
2958
  }
2935
2959
  const result = await handler.execute(args.slice(1));
2936
2960
  if (result.stdout.length > 0) process.stdout.write(result.stdout);
@@ -2942,12 +2966,12 @@ async function main(): Promise<void> {
2942
2966
  case "world:pin": {
2943
2967
  let handler: WorldPinCommandHandler;
2944
2968
  try {
2945
- handler = createWorldModelModule({
2969
+ handler = (await import("./world-model/index.js")).createWorldModelModule({
2946
2970
  rootDir,
2947
2971
  resolvedConfig: await loadWorldResolvedConfig(),
2948
2972
  }).worldPinCommandHandler;
2949
2973
  } catch (error) {
2950
- handler = WorldPinCommandHandler.fromFailure(error);
2974
+ handler = (await import("./world-model/index.js")).WorldPinCommandHandler.fromFailure(error);
2951
2975
  }
2952
2976
  const result = await handler.execute(args.slice(1));
2953
2977
  if (result.stdout.length > 0) process.stdout.write(result.stdout);
@@ -2959,12 +2983,12 @@ async function main(): Promise<void> {
2959
2983
  case "world:derive": {
2960
2984
  let handler: WorldDeriveCommandHandler;
2961
2985
  try {
2962
- handler = createWorldModelModule({
2986
+ handler = (await import("./world-model/index.js")).createWorldModelModule({
2963
2987
  rootDir,
2964
2988
  resolvedConfig: await loadWorldResolvedConfig(),
2965
2989
  }).worldDeriveCommandHandler;
2966
2990
  } catch (error) {
2967
- handler = WorldDeriveCommandHandler.fromFailure(error);
2991
+ handler = (await import("./world-model/index.js")).WorldDeriveCommandHandler.fromFailure(error);
2968
2992
  }
2969
2993
  const result = await handler.execute(args.slice(1));
2970
2994
  if (result.stdout.length > 0) process.stdout.write(result.stdout);
@@ -2977,7 +3001,7 @@ async function main(): Promise<void> {
2977
3001
  case "check-phase-gate": {
2978
3002
  const phaseConfig = resolvedConfig ? toPhaseConfigSection(resolvedConfig) : undefined;
2979
3003
  const reportOutputDir = resolvedConfig?.reporting.outputDir;
2980
- const mod = createPhaseDependencyModelModule({
3004
+ const mod = (await import("./phase-dependency-model/composition-root.js")).createPhaseDependencyModelModule({
2981
3005
  rootDir,
2982
3006
  phaseConfig,
2983
3007
  reportOutputDir,
@@ -3003,7 +3027,7 @@ async function main(): Promise<void> {
3003
3027
  // ADR ディレクトリを rootDir として渡す(project root を渡すと readdir が ADR を
3004
3028
  // 一切発見できず vacuous な valid を返す phantom gate になる)。
3005
3029
  case "list-adrs": {
3006
- const mod = createAdrFoundationModule(join(rootDir, "docs", "ADR"));
3030
+ const mod = (await import("./adr-foundation/composition-root.js")).createAdrFoundationModule(join(rootDir, "docs", "ADR"));
3007
3031
  const statuses = toAdrStatuses(parseFlag(args, "--status"));
3008
3032
  const result = await mod.listAdrsCommandHandler.execute({
3009
3033
  statuses,
@@ -3015,7 +3039,7 @@ async function main(): Promise<void> {
3015
3039
  }
3016
3040
 
3017
3041
  case "validate-adr": {
3018
- const mod = createAdrFoundationModule(join(rootDir, "docs", "ADR"));
3042
+ const mod = (await import("./adr-foundation/composition-root.js")).createAdrFoundationModule(join(rootDir, "docs", "ADR"));
3019
3043
  const all = hasFlag(args, "--all");
3020
3044
  const adrRef = args.find((a) => !a.startsWith("--") && a !== command);
3021
3045
  const result = await mod.validateAdrCommandHandler.execute({
@@ -3041,7 +3065,7 @@ async function main(): Promise<void> {
3041
3065
 
3042
3066
  // ── validator-system ──
3043
3067
  case "validate": {
3044
- const mod = createValidatorSystemModule(toValidatorSystemConfig(resolvedConfig));
3068
+ const mod = (await import("./validator-system/composition-root.js")).createValidatorSystemModule(toValidatorSystemConfig(resolvedConfig));
3045
3069
  const layer = parseValidateLayer(args);
3046
3070
  const unit = parseFlag(args, "--unit");
3047
3071
  const phase = parseFlag(args, "--phase");
@@ -3074,7 +3098,7 @@ async function main(): Promise<void> {
3074
3098
  // WI-364: check-change-category (WI-351) と同様に解決済み configPath / rootDir を注入する。
3075
3099
  // 無指定だと quickMode 設定を cwd 基準でしか探せず、サブディレクトリ実行で
3076
3100
  // HarnessConfigNotFoundError → exit 2 になっていた。
3077
- const mod = createQuickModeCompositionRoot(await resolveQuickModeCompositionOptions());
3101
+ const mod = (await import("./quick-mode/composition-root.js")).createQuickModeCompositionRoot(await resolveQuickModeCompositionOptions());
3078
3102
  const failOnReject = hasFlag(args, "--fail-on-reject");
3079
3103
  const dryRun = hasFlag(args, "--dry-run");
3080
3104
  const files = parseFlag(args, "--files");
@@ -3103,6 +3127,7 @@ async function main(): Promise<void> {
3103
3127
  " --paths <csv> Comma-separated file paths to classify.",
3104
3128
  " --format <human|json> Output format. Default: human.",
3105
3129
  " --fail-on-full-required Exit with code 1 when Full Mode is required.",
3130
+ " --risk-snapshots <json> Optional before/after snapshots for advisory review; does not change gates.",
3106
3131
  " --help Show this help.",
3107
3132
  "",
3108
3133
  "Examples:",
@@ -3113,14 +3138,19 @@ async function main(): Promise<void> {
3113
3138
  );
3114
3139
  return;
3115
3140
  }
3116
- const mod = createQuickModeCompositionRoot(await resolveQuickModeCompositionOptions());
3141
+ const mod = (await import("./quick-mode/composition-root.js")).createQuickModeCompositionRoot(await resolveQuickModeCompositionOptions());
3117
3142
  const paths = parseFlag(args, "--paths");
3118
3143
  const format = parseFlag(args, "--format") as "human" | "json" | undefined;
3119
3144
  const failOnFullRequired = hasFlag(args, "--fail-on-full-required");
3145
+ const riskSnapshots = parseFlag(args, "--risk-snapshots");
3146
+ if (hasFlag(args, "--risk-snapshots") && !riskSnapshots) {
3147
+ throw new Error("--risk-snapshots requires a JSON file path.");
3148
+ }
3120
3149
  const result = await mod.checkChangeCategoryHandler.handle({
3121
3150
  paths,
3122
3151
  format,
3123
3152
  failOnFullRequired,
3153
+ riskSnapshots,
3124
3154
  });
3125
3155
  await finishCliExit(result.exitCode);
3126
3156
  return;
@@ -3206,9 +3236,8 @@ async function main(): Promise<void> {
3206
3236
  const mod = createHarnessApiModule();
3207
3237
  const flags: Record<string, boolean | string> = {};
3208
3238
  if (json) flags.json = true;
3209
- const target = parseFlag(args, "--target");
3210
- if (target) flags.target = target;
3211
- await mod.handlers.lint.handle({}, flags);
3239
+ const targets = args.flatMap((arg, index) => arg === '--target' && args[index + 1] !== undefined ? [args[index + 1]] : []);
3240
+ await mod.handlers.lint.handle(targets.length > 0 ? { reportTargets: JSON.stringify(targets) } : {}, flags);
3212
3241
  break;
3213
3242
  }
3214
3243
 
@@ -3283,7 +3312,7 @@ async function main(): Promise<void> {
3283
3312
  }
3284
3313
  const { createAttestationModule } = await import("./attestation/index.js");
3285
3314
  const pkgVersion = await getHarnessVersion(harnessRoot);
3286
- const worldModule = createWorldModelModule({
3315
+ const worldModule = (await import("./world-model/index.js")).createWorldModelModule({
3287
3316
  rootDir,
3288
3317
  resolvedConfig: await loadWorldResolvedConfig(),
3289
3318
  });
@@ -3350,7 +3379,7 @@ Examples:
3350
3379
  console.error(flagError);
3351
3380
  process.exit(2);
3352
3381
  }
3353
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3382
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3354
3383
  const presetId = parseFlag(args, "--preset") ?? "standard";
3355
3384
  const templateType = parseFlag(args, "--type") ?? "aidlc-gate";
3356
3385
  const render = hasFlag(args, "--render");
@@ -3362,7 +3391,7 @@ Examples:
3362
3391
  }
3363
3392
 
3364
3393
  case "ci:migrate-agents-md": {
3365
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3394
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3366
3395
  const dryRun = hasFlag(args, "--dry-run");
3367
3396
  const validateOnly = hasFlag(args, "--validate-only");
3368
3397
  const format = json ? "json" : "human";
@@ -3373,7 +3402,7 @@ Examples:
3373
3402
  }
3374
3403
 
3375
3404
  case "ci:auto-refresh-agent-context": {
3376
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3405
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3377
3406
  const dryRun = hasFlag(args, "--dry-run");
3378
3407
  const apply = hasFlag(args, "--apply");
3379
3408
  const format = json ? "json" : "human";
@@ -3384,7 +3413,7 @@ Examples:
3384
3413
  }
3385
3414
 
3386
3415
  case "refresh-claude-md": {
3387
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3416
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3388
3417
  const dryRun = hasFlag(args, "--dry-run");
3389
3418
  const apply = hasFlag(args, "--apply");
3390
3419
  const format = json ? "json" : "human";
@@ -3395,7 +3424,7 @@ Examples:
3395
3424
  }
3396
3425
 
3397
3426
  case "p2:check-agent-context": {
3398
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3427
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3399
3428
  const thresholdRaw = parseFlag(args, "--threshold-days");
3400
3429
  const thresholdDays = thresholdRaw === undefined ? undefined : Number(thresholdRaw);
3401
3430
  const format = json ? "json" : "human";
@@ -3406,7 +3435,7 @@ Examples:
3406
3435
  }
3407
3436
 
3408
3437
  case "ci:check-repetition": {
3409
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3438
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3410
3439
  const errorCode = parseFlag(args, "--code") ?? "";
3411
3440
  const reset = hasFlag(args, "--reset");
3412
3441
  const format = json ? "json" : "human";
@@ -3417,7 +3446,7 @@ Examples:
3417
3446
  }
3418
3447
 
3419
3448
  case "baseline": {
3420
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3449
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3421
3450
  const dryRun = hasFlag(args, "--dry-run");
3422
3451
  const force = hasFlag(args, "--force");
3423
3452
  const pathsFlag = parseFlag(args, "--paths");
@@ -3440,7 +3469,7 @@ Examples:
3440
3469
  }
3441
3470
 
3442
3471
  case "scaffold-design": {
3443
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3472
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3444
3473
  const unit = parseFlag(args, "--unit") ?? "";
3445
3474
  const phase = parseFlag(args, "--phase") ?? "";
3446
3475
  const dryRun = hasFlag(args, "--dry-run");
@@ -3461,7 +3490,7 @@ Examples:
3461
3490
  }
3462
3491
 
3463
3492
  case "scaffold-inception": {
3464
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3493
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3465
3494
  const kind = parseFlag(args, "--kind") ?? "";
3466
3495
  const dryRun = hasFlag(args, "--dry-run");
3467
3496
  const apply = hasFlag(args, "--apply");
@@ -3480,7 +3509,7 @@ Examples:
3480
3509
  }
3481
3510
 
3482
3511
  case "templates": {
3483
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3512
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3484
3513
  const subCommand = args[1];
3485
3514
  const emit = async (result: { exitCode: number; output: string; errorOutput: string }): Promise<void> => {
3486
3515
  if (result.output.length > 0) console.log(result.output);
@@ -3503,7 +3532,7 @@ Examples:
3503
3532
  }
3504
3533
 
3505
3534
  case "integrity:pin": {
3506
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3535
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3507
3536
  const dryRun = hasFlag(args, "--dry-run");
3508
3537
  const format = json ? "json" : "human";
3509
3538
  const result = await mod.integrityHandler.pin({ dryRun, format });
@@ -3513,7 +3542,7 @@ Examples:
3513
3542
  }
3514
3543
 
3515
3544
  case "integrity:verify": {
3516
- const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3545
+ const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
3517
3546
  const format = json ? "json" : "human";
3518
3547
  const result = await mod.integrityHandler.verify({ format });
3519
3548
  console.log(result.output);
@@ -3523,7 +3552,15 @@ Examples:
3523
3552
 
3524
3553
  // ── skill-quality ──
3525
3554
  case "skill:execute-tdd-cycle": {
3526
- const mod = createSkillQualityHandlers();
3555
+ const configuredValidation = hasFlag(args, "--configured-validation");
3556
+ const mod = (await import("./skill-quality/composition-root.js")).createSkillQualityHandlers(configuredValidation ? {
3557
+ rootDir,
3558
+ l1Config: resolvedConfig
3559
+ ? { l1Config: toL1Config(resolvedConfig), architecture: toArchitectureInput(resolvedConfig) }
3560
+ : undefined,
3561
+ validatorSystemConfig: toValidatorSystemConfig(resolvedConfig),
3562
+ failOnWarning: resolvedConfig?.validate.failOnWarning,
3563
+ } : {});
3527
3564
  const unit = parseFlag(args, "--unit") ?? "";
3528
3565
  const storyId = parseFlag(args, "--story") ?? "";
3529
3566
  const description = parseFlag(args, "--desc") ?? "";
@@ -3533,12 +3570,13 @@ Examples:
3533
3570
  const passed = hasFlag(args, "--passed");
3534
3571
  const result = await mod.executeTddCycleHandler.handle({ unit, storyId, description, phase, passed });
3535
3572
  console.log(result.message);
3573
+ console.log(`Validation profile: ${configuredValidation ? "configured" : "legacy (use --configured-validation to explicitly adopt resolved project validation settings)"}`);
3536
3574
  await finishCliExit(result.exitCode);
3537
3575
  return;
3538
3576
  }
3539
3577
 
3540
3578
  case "skill:check-coverage": {
3541
- const mod = createSkillQualityHandlers();
3579
+ const mod = (await import("./skill-quality/composition-root.js")).createSkillQualityHandlers();
3542
3580
  const storyId = parseFlag(args, "--story") ?? "";
3543
3581
  const format = json ? "json" : "human";
3544
3582
  const result = await mod.checkCoverageHandler.handle({ storyId, format });
@@ -3548,7 +3586,7 @@ Examples:
3548
3586
  }
3549
3587
 
3550
3588
  case "skill:collect-lessons": {
3551
- const mod = createSkillQualityHandlers();
3589
+ const mod = (await import("./skill-quality/composition-root.js")).createSkillQualityHandlers();
3552
3590
  const storyId = parseFlag(args, "--story") ?? "";
3553
3591
  const sourcesRaw = parseFlag(args, "--sources") ?? "";
3554
3592
  const sources = sourcesRaw ? sourcesRaw.split(",") : [];
@@ -3560,7 +3598,7 @@ Examples:
3560
3598
  }
3561
3599
 
3562
3600
  case "skill:apply-cascade-update": {
3563
- const mod = createSkillQualityHandlers();
3601
+ const mod = (await import("./skill-quality/composition-root.js")).createSkillQualityHandlers();
3564
3602
  const storyId = parseFlag(args, "--story") ?? "";
3565
3603
  const dryRun = hasFlag(args, "--dry-run");
3566
3604
  const result = await mod.applyCascadeUpdateHandler.handle({ storyId, dryRun, format: json ? "json" : "human" });
@@ -3570,7 +3608,7 @@ Examples:
3570
3608
  }
3571
3609
 
3572
3610
  case "skill:validate-structure": {
3573
- const mod = createSkillQualityHandlers();
3611
+ const mod = (await import("./skill-quality/composition-root.js")).createSkillQualityHandlers();
3574
3612
  const skillFile = parseFlag(args, "--file") ?? "";
3575
3613
  const format = json ? "json" : "human";
3576
3614
  const result = await mod.validateSkillStructureHandler.handle({ skillFile, format });
@@ -3581,7 +3619,7 @@ Examples:
3581
3619
 
3582
3620
  // ── regression-suite ──
3583
3621
  case "regression:run-k-requirements": {
3584
- const mod = buildRegressionSuite(rootDir);
3622
+ const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
3585
3623
  const result = await mod.runKRequirementsRegressionUseCase.execute();
3586
3624
  const output = json
3587
3625
  ? JSON.stringify(result, null, 2)
@@ -3592,7 +3630,7 @@ Examples:
3592
3630
  }
3593
3631
 
3594
3632
  case "regression:run-gng-gate": {
3595
- const mod = buildRegressionSuite(rootDir);
3633
+ const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
3596
3634
  const result = await mod.runGngGateRegressionUseCase.execute();
3597
3635
  const output = json
3598
3636
  ? JSON.stringify(result, null, 2)
@@ -3603,7 +3641,7 @@ Examples:
3603
3641
  }
3604
3642
 
3605
3643
  case "regression:run-agent-guard": {
3606
- const mod = buildRegressionSuite(rootDir);
3644
+ const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
3607
3645
  const result = await mod.runAgentIndependenceGuardUseCase.execute();
3608
3646
  const output = json
3609
3647
  ? JSON.stringify(result, null, 2)
@@ -3614,7 +3652,7 @@ Examples:
3614
3652
  }
3615
3653
 
3616
3654
  case "regression:run-k14-k15": {
3617
- const mod = buildRegressionSuite(rootDir);
3655
+ const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
3618
3656
  const result = await mod.runK14K15RegressionUseCase.execute();
3619
3657
  const output = json
3620
3658
  ? JSON.stringify(result, null, 2)
@@ -3625,7 +3663,7 @@ Examples:
3625
3663
  }
3626
3664
 
3627
3665
  case "regression:configure-ci-gate": {
3628
- const mod = buildRegressionSuite(rootDir);
3666
+ const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
3629
3667
  const requiredSuiteIds = parseSuiteIds(parseFlag(args, "--suites") ?? DEFAULT_REGRESSION_SUITES);
3630
3668
  const threshold = parseCoverageThreshold(parseFlag(args, "--threshold"));
3631
3669
  const result = await mod.configureCiGateUseCase.execute({
@@ -3642,7 +3680,7 @@ Examples:
3642
3680
  }
3643
3681
 
3644
3682
  case "regression:analyze-migration": {
3645
- const mod = buildRegressionSuite(rootDir);
3683
+ const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
3646
3684
  const dryRun = !hasFlag(args, "--no-dry-run");
3647
3685
  const result = await mod.analyzeV0MigrationUseCase.execute({ dryRun });
3648
3686
  const output = json
@@ -3654,7 +3692,7 @@ Examples:
3654
3692
  }
3655
3693
 
3656
3694
  case "regression:migrate-v0-tests": {
3657
- const mod = buildRegressionSuite(rootDir);
3695
+ const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
3658
3696
  const confirm = hasFlag(args, "--confirm");
3659
3697
  const result = await mod.migrateV0TestsUseCase.execute({ confirmExecute: confirm });
3660
3698
  const output = json
@@ -3667,7 +3705,7 @@ Examples:
3667
3705
 
3668
3706
  // ── phase2-extensions ──
3669
3707
  case "p2:check-freshness": {
3670
- const mod = buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
3708
+ const mod = (await import("./phase2-extensions/composition-root.js")).buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
3671
3709
  const p2args = args.slice(1);
3672
3710
  const result = await mod.checkFreshnessHandler.handle(p2args);
3673
3711
  console.log(result.stdout);
@@ -3676,7 +3714,7 @@ Examples:
3676
3714
  }
3677
3715
 
3678
3716
  case "p2:validate-pointers": {
3679
- const mod = buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
3717
+ const mod = (await import("./phase2-extensions/composition-root.js")).buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
3680
3718
  const p2args = args.slice(1);
3681
3719
  const result = await mod.validatePointersHandler.handle(p2args);
3682
3720
  console.log(result.stdout);
@@ -3685,7 +3723,7 @@ Examples:
3685
3723
  }
3686
3724
 
3687
3725
  case "p2:generate-e2e-template": {
3688
- const mod = buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
3726
+ const mod = (await import("./phase2-extensions/composition-root.js")).buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
3689
3727
  const p2args = args.slice(1);
3690
3728
  const result = await mod.generateE2ETemplateHandler.handle(p2args);
3691
3729
  console.log(result.stdout);
@@ -3694,7 +3732,7 @@ Examples:
3694
3732
  }
3695
3733
 
3696
3734
  case "p2:check-initial-creation": {
3697
- const mod = buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
3735
+ const mod = (await import("./phase2-extensions/composition-root.js")).buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
3698
3736
  const p2args = args.slice(1);
3699
3737
  const result = await mod.checkInitialCreationExpirationHandler.handle(p2args);
3700
3738
  console.log(result.stdout);