docs: document ingest trace inspection

This commit is contained in:
Andrey Avtomonov 2026-05-17 21:32:03 +02:00
parent cae5c4b948
commit 8d78f872af
2 changed files with 37 additions and 2 deletions

View file

@ -111,6 +111,35 @@ notion skipped skipped done done
Use `--json` when a script or agent needs the selected plan and per-target
results.
## Inspect source ingest traces
Source ingest writes persistent JSONL traces for postmortem debugging. Stored
ingest status prints the trace path near the run identifiers:
```bash
ktx ingest status <runId>
```
The trace file lives under the project directory at
`.ktx/ingest-traces/<jobId>/trace.jsonl`. Each line is a JSON event with the
job id, run id, sync id, connection id, source key, phase, event name, timing,
context fields, and error details when a step fails.
Use `jq` or line-oriented tools to inspect a trace:
```bash
jq -c '. | {at, level, phase, event, durationMs, data, error}' \
.ktx/ingest-traces/<jobId>/trace.jsonl
```
KTX writes `debug` trace events by default. Set `KTX_INGEST_TRACE_LEVEL` to
`error`, `info`, `debug`, or `trace` before running ingest to change the trace
verbosity:
```bash
KTX_INGEST_TRACE_LEVEL=trace ktx ingest metabase
```
## Common errors
| Error | Cause | Recovery |

View file

@ -76,7 +76,7 @@ import { createEmitHistoricSqlEvidenceTool } from './adapters/historic-sql/evide
import { HistoricSqlProjectionPostProcessor } from './adapters/historic-sql/post-processor.js';
import { ContextEvidenceIndexService, SqliteContextEvidenceStore } from './context-evidence/index.js';
import { DiffSetService } from './diff-set.service.js';
import { ingestTracePathForJob } from './ingest-trace.js';
import { ingestTracePathForJob, type IngestTraceLevel } from './ingest-trace.js';
import { IngestBundleRunner } from './ingest-bundle.runner.js';
import { PageTriageService } from './page-triage/index.js';
import { createWarehouseVerificationTools } from './tools/warehouse-verification/index.js';
@ -97,6 +97,12 @@ const promptsDir = fileURLToPath(new URL('../../prompts', import.meta.url));
const skillsDir = fileURLToPath(new URL('../../skills', import.meta.url));
const LOCAL_AUTHOR = { name: 'KTX Local', email: 'local@ktx.local' };
const LOCAL_SHAPE_WARNING = 'Local ingest validates semantic-layer YAML shape only.';
const INGEST_TRACE_LEVELS = new Set<IngestTraceLevel>(['error', 'info', 'debug', 'trace']);
function ingestTraceLevelFromEnv(env: NodeJS.ProcessEnv = process.env): IngestTraceLevel {
const raw = env.KTX_INGEST_TRACE_LEVEL;
return raw && INGEST_TRACE_LEVELS.has(raw as IngestTraceLevel) ? (raw as IngestTraceLevel) : 'debug';
}
export interface CreateLocalBundleIngestRuntimeOptions {
project: KtxLocalProject;
@ -677,7 +683,7 @@ export function createLocalBundleIngestRuntime(
workUnitStepBudget: options.project.config.ingest.workUnits.stepBudget,
workUnitFailureMode: options.project.config.ingest.workUnits.failureMode,
isolatedDiffSourceKeys: ['metabase'],
ingestTraceLevel: 'debug',
ingestTraceLevel: ingestTraceLevelFromEnv(),
},
skillsRegistry: new SkillsRegistryService({ skillsDir, logger }),
promptService,