mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-07 07:55:13 +02:00
feat(cli)!: remove fast mode; ktx ingest always builds enriched context (KLO-721) (#237)
Fast mode (the ktx ingest --fast/--deep database-ingest depth toggle) is removed.
ktx ingest now always builds the full enriched ("deep") context. There is no
structural fallback: a database connection without a configured model and
embeddings fails the enrichment-readiness preflight before any work runs, with
a 'Run ktx setup to configure a model and embeddings' hint.
- Remove --fast/--deep flags, the per-connection context.depth field, and the
ktx setup depth prompt (delete setup-database-context-depth.ts).
- Rename ingest-depth.ts -> connection-drivers.ts; ingest always requests scan
mode 'enriched'; readiness gate (enrichmentReadinessGaps) runs for every
database target.
- Drop the database-context-depth telemetry step (Node + Python schema mirrors
regenerated).
- Update CLI, setup, context-build view, docs, the public ktx skill, and the
release-smoke / artifacts scripts (now assert the no-LLM guard failure).
ktx status --fast (a separate network-probe flag) is unchanged.
Follow-ups: KLO-726 (live progress for ktx ingest --all), KLO-727 (restore
credentialed successful-ingest release smoke coverage).
This commit is contained in:
parent
637891f030
commit
3f0d11e07d
34 changed files with 222 additions and 884 deletions
|
|
@ -257,7 +257,7 @@ describe('standalone example docs', () => {
|
|||
assert.match(primarySources, /context:\n queryHistory:/);
|
||||
assert.match(rootReadme, /`ktx ingest` \| Build context for every configured connection/);
|
||||
assert.doesNotMatch(rootReadme, /`ktx ingest <id>`/);
|
||||
assert.match(quickstart, /Databases:\n warehouse: deep context complete/);
|
||||
assert.match(quickstart, /Databases:\n warehouse: database context complete/);
|
||||
assert.match(quickstart, /Databases configured: yes \(warehouse\)/);
|
||||
assert.match(setupReference, /Databases configured: yes \(postgres-warehouse\)/);
|
||||
assert.doesNotMatch(rootReadme, new RegExp(['Primary sources', 'configured'].join(' ')));
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@ export function buildLiveDatabaseIngestArgs(projectDir, _databaseIntrospectionUr
|
|||
connectionId,
|
||||
'--project-dir',
|
||||
projectDir,
|
||||
'--fast',
|
||||
'--no-input',
|
||||
];
|
||||
}
|
||||
|
|
@ -152,20 +151,20 @@ function requireSuccess(label, result) {
|
|||
}
|
||||
}
|
||||
|
||||
function requireFailure(label, result) {
|
||||
if (result.code === 0) {
|
||||
throw new Error(
|
||||
`${label} unexpectedly succeeded\nstdout:\n${result.stdout}\nstderr:\n${result.stderr}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function requireOutput(label, result, pattern) {
|
||||
if (!pattern.test(result.stdout)) {
|
||||
throw new Error(`${label} output did not match ${pattern}\nstdout:\n${result.stdout}`);
|
||||
}
|
||||
}
|
||||
|
||||
function getRunId(stdout) {
|
||||
const match = stdout.match(/^Run: (.+)$/m);
|
||||
if (!match) {
|
||||
throw new Error(`ingest output did not include a run id\nstdout:\n${stdout}`);
|
||||
}
|
||||
return match[1];
|
||||
}
|
||||
|
||||
async function requireDocker() {
|
||||
const result = await run('docker', ['info'], { timeout: 20_000 });
|
||||
if (result.code !== 0) {
|
||||
|
|
@ -310,13 +309,17 @@ async function main() {
|
|||
env: managedRuntimeEnv(cleanInstallDir),
|
||||
timeout: 120_000,
|
||||
});
|
||||
requireSuccess('ktx ingest warehouse --fast', ingestRun);
|
||||
requireOutput('ktx ingest warehouse --fast', ingestRun, /Ingest finished/);
|
||||
requireOutput('ktx ingest warehouse --fast', ingestRun, /Database schema/);
|
||||
// ktx ingest now always builds enriched context and requires a configured
|
||||
// model and embeddings. This smoke project has neither, so the database
|
||||
// target fails the enrichment-readiness preflight before any work runs.
|
||||
// This still exercises the packaged binary, daemon startup, and the live
|
||||
// database connection end to end.
|
||||
requireFailure('ktx ingest warehouse', ingestRun);
|
||||
requireOutput('ktx ingest warehouse', ingestRun, /Ingest finished with partial failures/);
|
||||
requireOutput('ktx ingest warehouse', ingestRun, /enrichment is not configured/);
|
||||
|
||||
const runId = getRunId(ingestRun.stdout);
|
||||
await assertPathExists(join(projectDir, '.ktx', 'db.sqlite'), 'SQLite local ingest state');
|
||||
process.stdout.write(`Installed live-database artifact smoke passed: ${runId}\n`);
|
||||
process.stdout.write('Installed live-database artifact smoke passed: enrichment-readiness guard verified\n');
|
||||
} finally {
|
||||
if (daemonStarted && cleanInstallDir) {
|
||||
await stopDaemon(cleanInstallDir);
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ describe('installed live-database artifact smoke helpers', () => {
|
|||
'warehouse',
|
||||
'--project-dir',
|
||||
'/tmp/project',
|
||||
'--fast',
|
||||
'--no-input',
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -512,15 +512,6 @@ function requireSuccess(label, result) {
|
|||
assert.equal(result.stderr, '', label + ' wrote unexpected stderr');
|
||||
}
|
||||
|
||||
function requireSuccessWithProjectStderr(label, result, projectDir) {
|
||||
assert.equal(
|
||||
result.code,
|
||||
0,
|
||||
label + ' failed with code ' + result.code + '\\nstdout:\\n' + result.stdout + '\\nstderr:\\n' + result.stderr,
|
||||
);
|
||||
assert.equal(result.stderr, 'Project: ' + projectDir + '\\n', label + ' wrote unexpected stderr');
|
||||
}
|
||||
|
||||
function requireExitCodeWithProjectStderr(label, result, projectDir, expectedCode) {
|
||||
assert.equal(
|
||||
result.code,
|
||||
|
|
@ -860,27 +851,15 @@ try {
|
|||
requireOutput('ktx admin runtime stop', runtimeStop, /Stopped KTX daemon/);
|
||||
process.stdout.write('ktx admin runtime daemon lifecycle verified\\n');
|
||||
|
||||
const structuralScan = await run(
|
||||
const databaseIngest = await run(
|
||||
...Object.values(
|
||||
pnpmCommand(['exec', 'ktx', 'ingest', 'warehouse', '--project-dir', projectDir, '--fast', '--no-input']),
|
||||
pnpmCommand(['exec', 'ktx', 'ingest', 'warehouse', '--project-dir', projectDir, '--no-input']),
|
||||
),
|
||||
);
|
||||
requireSuccessWithProjectStderr('ktx ingest fast', structuralScan, projectDir);
|
||||
requireOutput('ktx ingest fast', structuralScan, /Ingest finished/);
|
||||
requireOutput('ktx ingest fast', structuralScan, /Database schema/);
|
||||
requireOutput('ktx ingest fast', structuralScan, /warehouse\\s+done/);
|
||||
await access(join(projectDir, 'semantic-layer', 'warehouse', '_schema', 'public.yaml'));
|
||||
process.stdout.write('ktx ingest fast verified\\n');
|
||||
|
||||
const enrichedScan = await run(
|
||||
...Object.values(
|
||||
pnpmCommand(['exec', 'ktx', 'ingest', 'warehouse', '--project-dir', projectDir, '--deep', '--no-input']),
|
||||
),
|
||||
);
|
||||
requireExitCodeWithProjectStderr('ktx ingest deep readiness guard', enrichedScan, projectDir, 1);
|
||||
requireOutput('ktx ingest deep readiness guard', enrichedScan, /Ingest finished with partial failures/);
|
||||
requireOutput('ktx ingest deep readiness guard', enrichedScan, /requires deep ingest readiness/);
|
||||
process.stdout.write('ktx ingest deep readiness guard verified\\n');
|
||||
requireExitCodeWithProjectStderr('ktx ingest enrichment guard', databaseIngest, projectDir, 1);
|
||||
requireOutput('ktx ingest enrichment guard', databaseIngest, /Ingest finished with partial failures/);
|
||||
requireOutput('ktx ingest enrichment guard', databaseIngest, /enrichment is not configured/);
|
||||
process.stdout.write('ktx ingest enrichment guard verified\\n');
|
||||
|
||||
await access(join(projectDir, '.ktx', 'db.sqlite'));
|
||||
process.stdout.write('ktx ingest state verified\\n');
|
||||
|
|
|
|||
|
|
@ -530,10 +530,11 @@ describe('verification snippets', () => {
|
|||
assert.doesNotMatch(source, /ktx admin runtime prune/);
|
||||
assert.doesNotMatch(source, /staleRuntimeDir/);
|
||||
assert.match(source, /pnpmCommand\(\['exec', 'ktx', 'ingest', 'warehouse'/);
|
||||
assert.match(source, /'--deep'/);
|
||||
assert.doesNotMatch(source, /'--fast'/);
|
||||
assert.doesNotMatch(source, /'--deep'/);
|
||||
assert.doesNotMatch(source, /'--enrich'/);
|
||||
assert.match(source, /ktx ingest fast verified/);
|
||||
assert.match(source, /ktx ingest deep readiness guard verified/);
|
||||
assert.match(source, /ktx ingest enrichment guard verified/);
|
||||
assert.match(source, /enrichment is not configured/);
|
||||
assert.match(source, /enrichment:/);
|
||||
assert.match(source, /mode: deterministic/);
|
||||
assert.doesNotMatch(source, /run\('pnpm', \['exec', 'ktx', 'ingest', 'run'/);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue