Skip to content

T-KS64-move-the-plugin-source-config-key-and-its-gates-out-of

State: closed/done · Impact: low · Complexity: medium

Retire the plugin_source config key from SdlcConfigSchema. It named the project-relative directory of sdlc’s own source tree (default solutions/ontological) and was only meaningful in a checkout hosting that source, yet it sat in the general schema every consumer loads. Its readers — the docs-site skill/entity reference and data-model pages, the skill-prose and corpus-invocation gates, and project scan todos’ exclusions — must keep working unchanged in this checkout.

Investigation: the readers were lib/services/docs/{data_model,site}.ts, lib/services/docs/site/{reference,projections}.ts, lib/services/project/ops/scan-todos.ts and — confirming the original task text — the skill-prose and corpus-invocation gates under lib/services/gate/ops/. The docs-site generator was the “docs-site” reader (there is no separate docs-site gate). Every repo invocation (lefthook.yml, sdlc.yaml check verb) runs bun solutions/ontological/cli/sdlc.ts from the same checkout.

Decision: no config key and no repo-level override are needed. The source tree is derived from the running code’s own location, via the existing pluginRootDir() resolver in lib/util/plugin-root.ts (module-relative in the dev tree, the extracted cache under a compiled binary). Running from source in this repo, that root IS solutions/ontological; running an installed plugin or binary, it is the installed surface. So:

  • plugin-root.ts gains pluginSkillsDir(root?) (the one place the skills location is named — Phase 3’s vault tree plugin/plugins/sdlc/skills/, replacing the inline join(…, 'plugin', 'plugins', 'sdlc', 'skills') copies Phase 3 left in site, reference, skill-prose and corpus-invocation) and hostedPluginRootDir(projectRoot) (the plugin root when it lies inside the project, else undefined).
  • Docs readers resolve skills via pluginSkillsDir() and entity packages via pluginLibDir()/model/entities, as the rest of the codebase already did. enabledTypes()/enabledProjections()/collectEntityTypes() drop their now-unused projectRoot parameter (the per-project package-dir probe was a fixture seam; the registry is the running plugin’s). regenSkills takes an explicit skillsDir. Generated pages credit sources project-relative when hosted, else as sdlc/<path> (never a machine-specific install path).
  • The gates stay dev-repo-only by keying on hostedPluginRootDir: skill-prose’s default walk and corpus-invocation’s scan are no-ops when the project does not host the running plugin. corpus-invocation’s scan is factored into an exported scanCorpus(pluginDir, displayRoot).
  • scan-todos derives the source tree’s repo-relative prefix from pluginRootDir() and drops the skills/template exclusions when the repo does not host it. Its skills exclusion now follows pluginSkillsDir(), fixing the stale solutions/ontological/skills/ prefix Phase 3 left behind.
  • This also fixes a latent bug: the old binary branch returned an absolute path that callers joined onto projectRoot, yielding a non-existent path.

Hard cutover: plugin_source: in an sdlc.yaml is now an unrecognized key under the schema’s existing strictness. This repo’s sdlc.yaml never set it.

AreaNote
solutions/ontological/lib/config/load.tsdrop plugin_source key and pluginSourceDir()
solutions/ontological/lib/util/plugin-root.tspluginSkillsDir(), hostedPluginRootDir(), resolver docs
solutions/ontological/lib/services/docs/data_model, site, site/reference, site/projections read the running plugin
solutions/ontological/lib/services/gate/ops/skill-prose, corpus-invocation key on hostedPluginRootDir
solutions/ontological/lib/services/project/ops/scan-todos.tssource exclusions derived from pluginRootDir()
testsload, plugin-root (new), scan, corpus_invocation, docs site/data-model suites
  • AC-1: SdlcConfigSchema no longer declares plugin_source; a plugin_source: key is rejected as unrecognized (load.test.ts).
  • AC-2: The skill-prose/corpus-invocation gates and the docs-site generator resolve the sdlc source tree without the key, from the running code (lib/util/plugin-root.ts), with no regression in this checkout: sdlc docs generate --check reports no drift, gate skill-prose checks all 40 skills, the generated site credits solutions/ontological/... sources, and the check verb’s bun test line passes.
  • AC-3: Outside a checkout hosting the running plugin the gates are no-ops (plugin-root.test.ts, corpus_invocation.test.ts).
  • AC-4: pluginSkillsDir() is the single place the skills location is named for source-as-data readers.
  • corpus-invocation walks node_modules under the plugin root (~50k files, ~50s) — pre-existing, unchanged here.
  • none

← Back to Tasks