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.
Approach
Section titled “Approach”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.tsgainspluginSkillsDir(root?)(the one place the skills location is named — Phase 3’s vault treeplugin/plugins/sdlc/skills/, replacing the inlinejoin(…, 'plugin', 'plugins', 'sdlc', 'skills')copies Phase 3 left in site, reference, skill-prose and corpus-invocation) andhostedPluginRootDir(projectRoot)(the plugin root when it lies inside the project, elseundefined).- Docs readers resolve skills via
pluginSkillsDir()and entity packages viapluginLibDir()/model/entities, as the rest of the codebase already did.enabledTypes()/enabledProjections()/collectEntityTypes()drop their now-unusedprojectRootparameter (the per-project package-dir probe was a fixture seam; the registry is the running plugin’s).regenSkillstakes an explicitskillsDir. Generated pages credit sources project-relative when hosted, else assdlc/<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 exportedscanCorpus(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 followspluginSkillsDir(), fixing the stalesolutions/ontological/skills/prefix Phase 3 left behind. - This also fixes a latent bug: the old binary branch returned an absolute
path that callers
joined ontoprojectRoot, 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.
| Area | Note |
|---|---|
solutions/ontological/lib/config/load.ts | drop plugin_source key and pluginSourceDir() |
solutions/ontological/lib/util/plugin-root.ts | pluginSkillsDir(), 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.ts | source exclusions derived from pluginRootDir() |
| tests | load, plugin-root (new), scan, corpus_invocation, docs site/data-model suites |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
SdlcConfigSchemano longer declaresplugin_source; aplugin_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 --checkreports no drift,gate skill-prosechecks all 40 skills, the generated site creditssolutions/ontological/...sources, and the check verb’sbun testline 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.
Out of scope
Section titled “Out of scope”- corpus-invocation walks
node_modulesunder the plugin root (~50k files, ~50s) — pre-existing, unchanged here.
Dependencies
Section titled “Dependencies”- none