mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-28 08:49:38 +02:00
feat(context): add warehouse verification tools (#46)
* feat(context): add warehouse dialect dispatch * feat(context): read warehouse scan catalog * feat(context): add entity details verification tool * feat(context): add ingest SQL verification tool * feat(context): add raw warehouse discovery tool * feat(context): expose warehouse verification tools to ingest * docs(context): add ingest identifier verification protocol * test(context): guard ingest identifier verification prompts * chore(context): verify warehouse verification tools * docs: add warehouse verification tools plan and spec * fix(context): expose target warehouses to Notion ingest * fix(context): update ingest prompts for warehouse verification tools * fix(context): scope raw schema discovery to allowed connections * fix(context): verify warehouse column display targets * docs: add notion warehouse verification gap closure plan * fix(context): include raw discovery connection names * fix(context): expose warehouse targets for LookML and MetricFlow * fix(context): pass connection config to ingest query executors * fix(cli): enable read-only SQL probes for local ingest * docs: add warehouse verification final v1 closure plan * fix(context): align warehouse sql probe prompt shape * docs: add warehouse verification prompt shape closure plan * test(context): catch connectionless sql execution prompt examples * fix(context): include connection name in sl capture sql example * docs: add warehouse verification sql example closure plan * fix(context): report structured entity detail misses * docs: add warehouse verification structured target miss closure plan * fix: report untracked squash merge conflicts * feat: require ingest verification ledger * fix: stabilize ingest wiki references
This commit is contained in:
parent
bcb0d2f8f7
commit
c22248dabf
89 changed files with 7818 additions and 191 deletions
|
|
@ -409,6 +409,38 @@ describe('IngestBundleRunner — Stages 1 → 7', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('threads target warehouse connection names into WorkUnit and reconcile tool sessions', async () => {
|
||||
const deps = makeDeps();
|
||||
const sessions: any[] = [];
|
||||
deps.adapter.listTargetConnectionIds = vi.fn().mockResolvedValue(['warehouse']);
|
||||
deps.toolsetFactory.createIngestWuToolset.mockImplementation((toolSession: any) => {
|
||||
sessions.push(toolSession);
|
||||
return {
|
||||
toAiSdkTools: vi.fn().mockReturnValue({}),
|
||||
getAllTools: vi.fn().mockReturnValue([]),
|
||||
getToolNames: vi.fn().mockReturnValue([]),
|
||||
};
|
||||
});
|
||||
deps.agentRunner.runLoop.mockResolvedValue({ stopReason: 'natural' });
|
||||
|
||||
const runner = buildRunner(deps);
|
||||
(runner as any).stageRawFilesStage1 = vi.fn().mockResolvedValue({
|
||||
currentHashes: new Map([['a.yml', 'h1']]),
|
||||
rawDirInWorktree: 'raw-sources/notion/fake/s',
|
||||
});
|
||||
(runner as any).resolveStagedDir = vi.fn().mockResolvedValue('/tmp/stage/upload-x');
|
||||
|
||||
await runner.run({
|
||||
jobId: 'j1',
|
||||
connectionId: 'notion',
|
||||
sourceKey: 'fake',
|
||||
trigger: 'upload',
|
||||
bundleRef: { kind: 'upload', uploadId: 'upload-x' },
|
||||
});
|
||||
|
||||
expect([...sessions[0].allowedConnectionNames].sort()).toEqual(['notion', 'warehouse']);
|
||||
});
|
||||
|
||||
it('reuses document evidence indexing and page triage for document WorkUnits', async () => {
|
||||
const deps = makeDeps();
|
||||
deps.adapter.source = 'notion';
|
||||
|
|
@ -643,6 +675,14 @@ describe('IngestBundleRunner — Stages 1 → 7', () => {
|
|||
});
|
||||
}
|
||||
if (params.telemetryTags.operationName === 'ingest-bundle-reconcile') {
|
||||
await params.toolSet.record_verification_ledger.execute(
|
||||
{
|
||||
summary: 'Reconciliation emits no warehouse identifiers before fallback recording.',
|
||||
verifiedIdentifiers: [],
|
||||
unverifiedIdentifiers: [],
|
||||
},
|
||||
{ toolCallId: 'ledger-1', messages: [] },
|
||||
);
|
||||
await params.toolSet.emit_conflict_resolution.execute(
|
||||
{
|
||||
kind: 'near_duplicate',
|
||||
|
|
@ -811,6 +851,14 @@ describe('IngestBundleRunner — Stages 1 → 7', () => {
|
|||
{ path: 'a.yml', startLine: 1, endLine: 2 },
|
||||
{ toolCallId: 'read-1', messages: [] },
|
||||
);
|
||||
await params.toolSet.record_verification_ledger.execute(
|
||||
{
|
||||
summary: 'Wiki write contains no warehouse identifiers.',
|
||||
verifiedIdentifiers: [],
|
||||
unverifiedIdentifiers: [],
|
||||
},
|
||||
{ toolCallId: 'ledger-1', messages: [] },
|
||||
);
|
||||
await params.toolSet.wiki_write.execute(
|
||||
{ key: 'knowledge/a.md', content: 'safe summary' },
|
||||
{ toolCallId: 'wiki-1', messages: [] },
|
||||
|
|
@ -850,9 +898,9 @@ describe('IngestBundleRunner — Stages 1 → 7', () => {
|
|||
{
|
||||
unitKey: 'u1',
|
||||
path: '/tmp/ktx-test/run/wu-transcripts/j1/u1.jsonl',
|
||||
toolCallCount: 2,
|
||||
toolCallCount: 3,
|
||||
errorCount: 0,
|
||||
toolNames: ['read_raw_span', 'wiki_write'],
|
||||
toolNames: ['read_raw_span', 'record_verification_ledger', 'wiki_write'],
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
|
@ -864,6 +912,14 @@ describe('IngestBundleRunner — Stages 1 → 7', () => {
|
|||
const deps = makeDeps();
|
||||
deps.agentRunner.runLoop.mockImplementation(async (params: any) => {
|
||||
if (params.telemetryTags.operationName === 'ingest-bundle-wu') {
|
||||
await params.toolSet.record_verification_ledger.execute(
|
||||
{
|
||||
summary: 'Unmapped fallback records an unsupported conversion metric without verified warehouse identifiers.',
|
||||
verifiedIdentifiers: [],
|
||||
unverifiedIdentifiers: [],
|
||||
},
|
||||
{ toolCallId: 'ledger-1', messages: [] },
|
||||
);
|
||||
await params.toolSet.emit_unmapped_fallback.execute(
|
||||
{
|
||||
rawPath: 'a.yml',
|
||||
|
|
@ -920,6 +976,14 @@ describe('IngestBundleRunner — Stages 1 → 7', () => {
|
|||
});
|
||||
deps.agentRunner.runLoop.mockImplementation(async (params: any) => {
|
||||
if (params.telemetryTags.operationName === 'ingest-bundle-reconcile') {
|
||||
await params.toolSet.record_verification_ledger.execute(
|
||||
{
|
||||
summary: 'Reconciliation records conflict, eviction, and fallback decisions without warehouse identifiers.',
|
||||
verifiedIdentifiers: [],
|
||||
unverifiedIdentifiers: [],
|
||||
},
|
||||
{ toolCallId: 'ledger-1', messages: [] },
|
||||
);
|
||||
await params.toolSet.emit_conflict_resolution.execute(
|
||||
{
|
||||
kind: 'near_duplicate',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue