fix(ingest): enforce SL target connection scope

This commit is contained in:
Andrey Avtomonov 2026-05-17 22:11:44 +02:00
parent 5ec639602b
commit 9d756b2c6c
10 changed files with 200 additions and 2 deletions

View file

@ -50,6 +50,22 @@ describe('isolated diff patch contract', () => {
).toThrow(/slDisallowed WorkUnit lookml-mismatch touched semantic-layer\/c1\/orders.yaml/);
});
it('rejects semantic-layer paths outside allowed target connections', () => {
const patch =
'diff --git a/semantic-layer/finance/orders.yaml b/semantic-layer/finance/orders.yaml\nindex 1..2 100644\n';
expect(() =>
assertPatchAllowedForWorkUnit({
unitKey: 'wu-finance',
patch,
slDisallowed: false,
allowedTargetConnectionIds: new Set(['warehouse']),
}),
).toThrow(
/semantic-layer target connection not allowed: semantic-layer\/finance\/orders.yaml \(finance\); allowed: warehouse/,
);
});
it('rejects executable and binary changes under known text artifact roots', () => {
expect(textArtifactRoots).toEqual(['wiki/', 'semantic-layer/']);

View file

@ -1,3 +1,5 @@
import { assertSemanticLayerTargetPathsAllowed } from '../semantic-layer-target-policy.js';
export const textArtifactRoots = ['wiki/', 'semantic-layer/'] as const;
export interface PatchTouchedPath {
@ -12,6 +14,7 @@ export interface PatchPolicyInput {
unitKey: string;
patch: string;
slDisallowed: boolean;
allowedTargetConnectionIds?: ReadonlySet<string>;
}
function stripPrefix(path: string): string {
@ -74,6 +77,12 @@ export function parsePatchTouchedPaths(patch: string): PatchTouchedPath[] {
export function assertPatchAllowedForWorkUnit(input: PatchPolicyInput): PatchTouchedPath[] {
const touched = parsePatchTouchedPaths(input.patch);
if (input.allowedTargetConnectionIds) {
assertSemanticLayerTargetPathsAllowed({
paths: touched.map((entry) => entry.path),
allowedConnectionIds: input.allowedTargetConnectionIds,
});
}
for (const entry of touched) {
if (input.slDisallowed && entry.path.startsWith('semantic-layer/')) {
throw new Error(`slDisallowed WorkUnit ${input.unitKey} touched ${entry.path}`);