@coderifts/agent-guard 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -2
- package/dist/cjs/artifact-resolver.d.ts +76 -0
- package/dist/cjs/artifact-resolver.d.ts.map +1 -0
- package/dist/cjs/artifact-resolver.js +413 -0
- package/dist/cjs/artifact-resolver.js.map +1 -0
- package/dist/cjs/guard.d.ts.map +1 -1
- package/dist/cjs/guard.js +31 -0
- package/dist/cjs/guard.js.map +1 -1
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +12 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/resolver-glob.d.ts +15 -0
- package/dist/cjs/resolver-glob.d.ts.map +1 -0
- package/dist/cjs/resolver-glob.js +65 -0
- package/dist/cjs/resolver-glob.js.map +1 -0
- package/dist/cjs/resolver-yaml.d.ts +20 -0
- package/dist/cjs/resolver-yaml.d.ts.map +1 -0
- package/dist/cjs/resolver-yaml.js +235 -0
- package/dist/cjs/resolver-yaml.js.map +1 -0
- package/dist/cjs/tool-registry.d.ts +88 -0
- package/dist/cjs/tool-registry.d.ts.map +1 -0
- package/dist/cjs/tool-registry.js +274 -0
- package/dist/cjs/tool-registry.js.map +1 -0
- package/dist/cjs/types.d.ts +2 -2
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/artifact-resolver.d.ts +76 -0
- package/dist/esm/artifact-resolver.d.ts.map +1 -0
- package/dist/esm/artifact-resolver.js +410 -0
- package/dist/esm/artifact-resolver.js.map +1 -0
- package/dist/esm/guard.d.ts.map +1 -1
- package/dist/esm/guard.js +31 -0
- package/dist/esm/guard.js.map +1 -1
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/resolver-glob.d.ts +15 -0
- package/dist/esm/resolver-glob.d.ts.map +1 -0
- package/dist/esm/resolver-glob.js +59 -0
- package/dist/esm/resolver-glob.js.map +1 -0
- package/dist/esm/resolver-yaml.d.ts +20 -0
- package/dist/esm/resolver-yaml.d.ts.map +1 -0
- package/dist/esm/resolver-yaml.js +229 -0
- package/dist/esm/resolver-yaml.js.map +1 -0
- package/dist/esm/tool-registry.d.ts +88 -0
- package/dist/esm/tool-registry.d.ts.map +1 -0
- package/dist/esm/tool-registry.js +269 -0
- package/dist/esm/tool-registry.js.map +1 -0
- package/dist/esm/types.d.ts +2 -2
- package/dist/esm/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,16 +15,41 @@ import { CodeRifts } from '@coderifts/sdk';
|
|
|
15
15
|
const client = new CodeRifts({ apiKey: 'cr_live_...' });
|
|
16
16
|
|
|
17
17
|
const outcome = await guardToolCall(
|
|
18
|
-
{
|
|
18
|
+
{
|
|
19
|
+
toolName: 'Edit',
|
|
20
|
+
arguments: { path: 'openapi.yaml' },
|
|
21
|
+
// Supply the contract change as artifacts[] with before/after content — this is what the
|
|
22
|
+
// server preflights. `id`/`type`/`before`/`after` are all required for each artifact.
|
|
23
|
+
artifacts: [{ id: 'public-api', type: 'openapi', before: baseSpec, after: proposedSpec }],
|
|
24
|
+
},
|
|
19
25
|
// The mutating work is created ONLY here, after the verdict — never eagerly (closes TOCTOU).
|
|
20
26
|
async (envelope, redactedCall) => applyEdit(redactedCall),
|
|
21
|
-
{ client },
|
|
27
|
+
{ client, operation: 'merge', environment: 'production' },
|
|
22
28
|
);
|
|
23
29
|
|
|
24
30
|
if (!outcome.executed) console.error('blocked:', outcome.verdict);
|
|
25
31
|
// Retry ONLY when outcome.executionAttempted === false (the safe-to-retry signal).
|
|
26
32
|
```
|
|
27
33
|
|
|
34
|
+
> **Supply `artifacts[]` with content.** If the guard detects a contract change (e.g. from
|
|
35
|
+
> `filesTouched`/`diff`) but you did **not** supply `artifacts[]` with `before`/`after`, it fails
|
|
36
|
+
> closed **locally** with `outcome.verdict.cause === 'MISSING_ARTIFACT_CONTENT'` — the tool does not
|
|
37
|
+
> execute and the error is *actionable* (pass the change as artifacts), not a package failure. The
|
|
38
|
+
> guard never sends an empty change set to the server.
|
|
39
|
+
|
|
40
|
+
### Guarding the whole tool surface (inescapability)
|
|
41
|
+
|
|
42
|
+
`guardToolCall` guards one call. To make CodeRifts the **only** path a mutating tool can take, wrap
|
|
43
|
+
your entire tool list with [`guardToolRegistry`](#) — it returns the sole tool table the agent may
|
|
44
|
+
see (every mutator wrapped, fail-closed at construction if any would remain raw):
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { guardToolRegistry } from '@coderifts/agent-guard';
|
|
48
|
+
|
|
49
|
+
const { tools, coverage } = guardToolRegistry(rawTools, { guard: { client } });
|
|
50
|
+
// register ONLY `tools` with your agent SDK; coverage === 'COMPLETE' ⇒ no mutator is reachable raw.
|
|
51
|
+
```
|
|
52
|
+
|
|
28
53
|
## Guarantees (tsc-verified)
|
|
29
54
|
|
|
30
55
|
- **Fail-closed by default** — any ambiguity, integrity failure, or unknown state resolves to `STOP`.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* artifactResolver — automatic base/head contract artifacts from a pure git snapshot (artifact-
|
|
3
|
+
* resolver-SPEC v1.0). The companion to MISSING_ARTIFACT_CONTENT: it answers "where do before/after
|
|
4
|
+
* come from?" by turning `git diff --name-only` + blob reads into `artifacts[] { id, type, before,
|
|
5
|
+
* after }` ready for preflight — OR honest `unresolved[]` entries. It NEVER decides, scores, or
|
|
6
|
+
* touches the fingerprint (§0.1); `report.claim.produces_verdict` is ALWAYS false.
|
|
7
|
+
*
|
|
8
|
+
* PURE + DETERMINISTIC (§0.3): git I/O is the host's job and enters as the `blobs` input; the same
|
|
9
|
+
* snapshot + changedFiles + config yields byte-identical artifacts/unresolved/coverage.
|
|
10
|
+
*
|
|
11
|
+
* Anti-fabrication (§4.2 / A1/A2): a missing $ref target, unreadable blob, or ambiguous SSOT becomes
|
|
12
|
+
* an `unresolved` entry with a code — NEVER an invented component, stub, or half-bundle.
|
|
13
|
+
*/
|
|
14
|
+
export type ArtifactType = 'openapi' | 'graphql' | 'grpc' | 'asyncapi' | 'mcp_manifest';
|
|
15
|
+
export type ResolvedArtifact = {
|
|
16
|
+
id: string;
|
|
17
|
+
type: ArtifactType;
|
|
18
|
+
before: string;
|
|
19
|
+
after: string;
|
|
20
|
+
};
|
|
21
|
+
export type UnresolvedReason = 'unreadable_blob' | 'missing_ref_target' | 'ref_cycle' | 'ref_depth_exceeded' | 'ambiguous_ssot' | 'unsupported_encoding' | 'type_ambiguous' | 'empty_changed_contract' | 'config_ssot_missing' | 'external_ref_forbidden' | 'parse_error';
|
|
22
|
+
export type UnresolvedEntry = {
|
|
23
|
+
path: string;
|
|
24
|
+
reason: UnresolvedReason;
|
|
25
|
+
detail?: string;
|
|
26
|
+
related_paths?: string[];
|
|
27
|
+
};
|
|
28
|
+
export type ResolveCoverage = 'COMPLETE' | 'PARTIAL' | 'UNRESOLVED' | 'EMPTY';
|
|
29
|
+
export type BlobValue = string | null | {
|
|
30
|
+
error: UnresolvedReason;
|
|
31
|
+
detail?: string;
|
|
32
|
+
};
|
|
33
|
+
export type ResolveInput = {
|
|
34
|
+
repository?: string;
|
|
35
|
+
baseRef: string;
|
|
36
|
+
headRef: string;
|
|
37
|
+
changedFiles: string[];
|
|
38
|
+
/** Pure snapshot keyed `${ref}:${path}` → text | null (absent) | { error }. */
|
|
39
|
+
blobs: Record<string, BlobValue>;
|
|
40
|
+
};
|
|
41
|
+
export type ResolveConfig = {
|
|
42
|
+
maxRefDepth?: number;
|
|
43
|
+
followExternalRefs?: boolean;
|
|
44
|
+
ssotPrefer?: string[];
|
|
45
|
+
generatedGlobs?: string[];
|
|
46
|
+
pathTypeHints?: Record<string, ArtifactType>;
|
|
47
|
+
allowBinary?: boolean;
|
|
48
|
+
openApiAssembly?: 'bundle_inline' | 'root_only';
|
|
49
|
+
/** Matrix flags (§5.1 pairing / §5 strict SSOT). */
|
|
50
|
+
forceSameSurfaceGroup?: string[];
|
|
51
|
+
requireSsotIfConfigured?: boolean;
|
|
52
|
+
};
|
|
53
|
+
export type SsotSelection = {
|
|
54
|
+
chosen: string;
|
|
55
|
+
deferred: string[];
|
|
56
|
+
reason: 'ssotPrefer' | 'generated_deprioritized' | 'single';
|
|
57
|
+
};
|
|
58
|
+
export type ResolveResult = {
|
|
59
|
+
artifacts: ResolvedArtifact[];
|
|
60
|
+
unresolved: UnresolvedEntry[];
|
|
61
|
+
coverage: ResolveCoverage;
|
|
62
|
+
report: {
|
|
63
|
+
version: 'artifact-resolver-report/1.0';
|
|
64
|
+
baseRef: string;
|
|
65
|
+
headRef: string;
|
|
66
|
+
contract_paths_discovered: string[];
|
|
67
|
+
ignored_non_contract: string[];
|
|
68
|
+
ssot_selections: SsotSelection[];
|
|
69
|
+
claim: {
|
|
70
|
+
artifacts_ready_for_preflight: boolean;
|
|
71
|
+
produces_verdict: false;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
export declare function resolve(input: ResolveInput, config?: ResolveConfig): ResolveResult;
|
|
76
|
+
//# sourceMappingURL=artifact-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-resolver.d.ts","sourceRoot":"","sources":["../../src/artifact-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,cAAc,CAAC;AAExF,MAAM,MAAM,gBAAgB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjG,MAAM,MAAM,gBAAgB,GACxB,iBAAiB,GAAG,oBAAoB,GAAG,WAAW,GAAG,oBAAoB,GAC7E,gBAAgB,GAAG,sBAAsB,GAAG,gBAAgB,GAAG,wBAAwB,GACvF,qBAAqB,GAAG,wBAAwB,GAAG,aAAa,CAAC;AAErE,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEpH,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,CAAC;AAE9E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG;IAAE,KAAK,EAAE,gBAAgB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC7C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,eAAe,GAAG,WAAW,CAAC;IAChD,oDAAoD;IACpD,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,YAAY,GAAG,yBAAyB,GAAG,QAAQ,CAAA;CAAE,CAAC;AAEhI,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,QAAQ,EAAE,eAAe,CAAC;IAC1B,MAAM,EAAE;QACN,OAAO,EAAE,8BAA8B,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,yBAAyB,EAAE,MAAM,EAAE,CAAC;QACpC,oBAAoB,EAAE,MAAM,EAAE,CAAC;QAC/B,eAAe,EAAE,aAAa,EAAE,CAAC;QACjC,KAAK,EAAE;YAAE,6BAA6B,EAAE,OAAO,CAAC;YAAC,gBAAgB,EAAE,KAAK,CAAA;SAAE,CAAC;KAC5E,CAAC;CACH,CAAC;AA0PF,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,GAAE,aAAkB,GAAG,aAAa,CAgGtF"}
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* artifactResolver — automatic base/head contract artifacts from a pure git snapshot (artifact-
|
|
4
|
+
* resolver-SPEC v1.0). The companion to MISSING_ARTIFACT_CONTENT: it answers "where do before/after
|
|
5
|
+
* come from?" by turning `git diff --name-only` + blob reads into `artifacts[] { id, type, before,
|
|
6
|
+
* after }` ready for preflight — OR honest `unresolved[]` entries. It NEVER decides, scores, or
|
|
7
|
+
* touches the fingerprint (§0.1); `report.claim.produces_verdict` is ALWAYS false.
|
|
8
|
+
*
|
|
9
|
+
* PURE + DETERMINISTIC (§0.3): git I/O is the host's job and enters as the `blobs` input; the same
|
|
10
|
+
* snapshot + changedFiles + config yields byte-identical artifacts/unresolved/coverage.
|
|
11
|
+
*
|
|
12
|
+
* Anti-fabrication (§4.2 / A1/A2): a missing $ref target, unreadable blob, or ambiguous SSOT becomes
|
|
13
|
+
* an `unresolved` entry with a code — NEVER an invented component, stub, or half-bundle.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.resolve = resolve;
|
|
17
|
+
const resolver_yaml_js_1 = require("./resolver-yaml.js");
|
|
18
|
+
const resolver_glob_js_1 = require("./resolver-glob.js");
|
|
19
|
+
const DEFAULT_GENERATED = ['**/generated/**', '**/gen/**'];
|
|
20
|
+
const VENDOR_GLOBS = ['**/node_modules/**', '**/vendor/**'];
|
|
21
|
+
// ── path helpers (POSIX) ─────────────────────────────────────────────────────────────────────────
|
|
22
|
+
function normalizePath(p) {
|
|
23
|
+
let s = p.replace(/\\/g, '/').trim();
|
|
24
|
+
while (s.startsWith('./'))
|
|
25
|
+
s = s.slice(2);
|
|
26
|
+
return s;
|
|
27
|
+
}
|
|
28
|
+
function dirname(p) {
|
|
29
|
+
const i = p.lastIndexOf('/');
|
|
30
|
+
return i === -1 ? '' : p.slice(0, i);
|
|
31
|
+
}
|
|
32
|
+
function basename(p) {
|
|
33
|
+
const i = p.lastIndexOf('/');
|
|
34
|
+
return i === -1 ? p : p.slice(i + 1);
|
|
35
|
+
}
|
|
36
|
+
function extname(p) {
|
|
37
|
+
const b = basename(p);
|
|
38
|
+
const i = b.lastIndexOf('.');
|
|
39
|
+
return i === -1 ? '' : b.slice(i + 1).toLowerCase();
|
|
40
|
+
}
|
|
41
|
+
function resolveRelative(dir, rel) {
|
|
42
|
+
const parts = (dir ? dir.split('/') : []).concat(normalizePath(rel).split('/'));
|
|
43
|
+
const out = [];
|
|
44
|
+
for (const seg of parts) {
|
|
45
|
+
if (seg === '' || seg === '.')
|
|
46
|
+
continue;
|
|
47
|
+
if (seg === '..')
|
|
48
|
+
out.pop();
|
|
49
|
+
else
|
|
50
|
+
out.push(seg);
|
|
51
|
+
}
|
|
52
|
+
return out.join('/');
|
|
53
|
+
}
|
|
54
|
+
// ── discovery (§2) ──────────────────────────────────────────────────────────────────────────────
|
|
55
|
+
function classifyByName(path) {
|
|
56
|
+
const b = basename(path).toLowerCase();
|
|
57
|
+
const ext = extname(path);
|
|
58
|
+
const yamlJson = ext === 'yaml' || ext === 'yml' || ext === 'json';
|
|
59
|
+
if (yamlJson && (b.includes('openapi') || b.includes('swagger')))
|
|
60
|
+
return 'openapi';
|
|
61
|
+
if (yamlJson && b.includes('asyncapi'))
|
|
62
|
+
return 'asyncapi';
|
|
63
|
+
if (ext === 'graphql' || ext === 'gql')
|
|
64
|
+
return 'graphql';
|
|
65
|
+
if (ext === 'proto')
|
|
66
|
+
return 'grpc';
|
|
67
|
+
if (b === 'mcp.json' || b === 'tools-catalog.json')
|
|
68
|
+
return 'mcp_manifest';
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
function classifyByContent(text) {
|
|
72
|
+
if (!text)
|
|
73
|
+
return null;
|
|
74
|
+
if (/(^|\n)\s*["']?openapi["']?\s*:\s*["']?[23]/.test(text) || (/swagger\s*:/.test(text) && /paths\s*:/.test(text)))
|
|
75
|
+
return 'openapi';
|
|
76
|
+
if (/(^|\n)\s*["']?asyncapi["']?\s*:/.test(text))
|
|
77
|
+
return 'asyncapi';
|
|
78
|
+
if (/\btype\s+Query\b|\btype\s+Mutation\b|\bschema\s*\{/.test(text))
|
|
79
|
+
return 'graphql';
|
|
80
|
+
if (/syntax\s*=\s*["']proto[23]["']/.test(text))
|
|
81
|
+
return 'grpc';
|
|
82
|
+
try {
|
|
83
|
+
const j = JSON.parse(text);
|
|
84
|
+
if (j && Array.isArray(j.tools) && j.tools.some((t) => t && typeof t === 'object' && 'inputSchema' in t))
|
|
85
|
+
return 'mcp_manifest';
|
|
86
|
+
}
|
|
87
|
+
catch { /* not json */ }
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/** *mcp*.json (not exactly mcp.json) needs a content check (tools + inputSchema) per the §2.3 table. */
|
|
91
|
+
function isMcpByNameNeedingContent(path) {
|
|
92
|
+
const b = basename(path).toLowerCase();
|
|
93
|
+
return extname(path) === 'json' && b.includes('mcp') && b !== 'mcp.json';
|
|
94
|
+
}
|
|
95
|
+
// ── $ref scanning + bounded inliner (§4) ──────────────────────────────────────────────────────────
|
|
96
|
+
const REF_RE = /\$ref["']?\s*:\s*["']?([^"'\s,}]+)["']?/g;
|
|
97
|
+
function scanRefs(text) {
|
|
98
|
+
const out = [];
|
|
99
|
+
let m;
|
|
100
|
+
REF_RE.lastIndex = 0;
|
|
101
|
+
while ((m = REF_RE.exec(text)) !== null)
|
|
102
|
+
out.push(m[1]);
|
|
103
|
+
return out;
|
|
104
|
+
}
|
|
105
|
+
function isExternalRef(ref) { return /^[a-z][a-z0-9+.-]*:\/\//i.test(ref) || ref.startsWith('//'); }
|
|
106
|
+
function isInternalRef(ref) { return ref.startsWith('#'); }
|
|
107
|
+
function splitRef(ref) {
|
|
108
|
+
const i = ref.indexOf('#');
|
|
109
|
+
return i === -1 ? { file: ref, pointer: '' } : { file: ref.slice(0, i), pointer: ref.slice(i + 1) };
|
|
110
|
+
}
|
|
111
|
+
function jsonPointer(doc, pointer) {
|
|
112
|
+
if (pointer === '' || pointer === '/')
|
|
113
|
+
return doc;
|
|
114
|
+
const parts = pointer.replace(/^\//, '').split('/').map((p) => p.replace(/~1/g, '/').replace(/~0/g, '~'));
|
|
115
|
+
let cur = doc;
|
|
116
|
+
for (const part of parts) {
|
|
117
|
+
if (cur && typeof cur === 'object' && part in cur)
|
|
118
|
+
cur = cur[part];
|
|
119
|
+
else
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
return cur;
|
|
123
|
+
}
|
|
124
|
+
function slugify(s) { return s.replace(/[^A-Za-z0-9]+/g, '_'); }
|
|
125
|
+
class RefError extends Error {
|
|
126
|
+
reason;
|
|
127
|
+
related;
|
|
128
|
+
constructor(reason, related) { super(reason); this.reason = reason; this.related = related; }
|
|
129
|
+
}
|
|
130
|
+
/** Assemble one side (base/head) into a deterministic JSON bundle. Throws RefError on any ref failure. */
|
|
131
|
+
function assembleSide(rootPath, rootText, refSide, input, config, deps) {
|
|
132
|
+
const maxDepth = config.maxRefDepth ?? 8;
|
|
133
|
+
let root;
|
|
134
|
+
try {
|
|
135
|
+
root = (0, resolver_yaml_js_1.parseDoc)(rootText);
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
if (e instanceof resolver_yaml_js_1.YamlLiteError)
|
|
139
|
+
throw new RefError('parse_error');
|
|
140
|
+
throw e;
|
|
141
|
+
}
|
|
142
|
+
const components = {};
|
|
143
|
+
const inline = (node, curDir, depth, stack) => {
|
|
144
|
+
if (Array.isArray(node))
|
|
145
|
+
return node.map((n) => inline(n, curDir, depth, stack));
|
|
146
|
+
if (node && typeof node === 'object') {
|
|
147
|
+
const rec = node;
|
|
148
|
+
if (typeof rec.$ref === 'string') {
|
|
149
|
+
const ref = rec.$ref;
|
|
150
|
+
if (isExternalRef(ref))
|
|
151
|
+
throw new RefError('external_ref_forbidden'); // v1: out of pure-git scope
|
|
152
|
+
if (isInternalRef(ref))
|
|
153
|
+
return { ...rec }; // JSON pointer within doc — self-contained, kept as-is
|
|
154
|
+
const { file, pointer } = splitRef(ref);
|
|
155
|
+
const targetPath = resolveRelative(curDir, file);
|
|
156
|
+
const key = `${targetPath}#${pointer}`;
|
|
157
|
+
if (depth + 1 > maxDepth)
|
|
158
|
+
throw new RefError('ref_depth_exceeded', targetPath);
|
|
159
|
+
if (stack.has(key))
|
|
160
|
+
throw new RefError('ref_cycle', targetPath);
|
|
161
|
+
const blob = getBlob(input, refSide, targetPath);
|
|
162
|
+
if (blob === null || blob === undefined)
|
|
163
|
+
throw new RefError('missing_ref_target', targetPath);
|
|
164
|
+
if (typeof blob === 'object')
|
|
165
|
+
throw new RefError(blob.error, targetPath);
|
|
166
|
+
deps.add(targetPath);
|
|
167
|
+
let targetDoc;
|
|
168
|
+
try {
|
|
169
|
+
targetDoc = (0, resolver_yaml_js_1.parseDoc)(blob);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
throw new RefError('parse_error', targetPath);
|
|
173
|
+
}
|
|
174
|
+
const resolved = jsonPointer(targetDoc, pointer);
|
|
175
|
+
if (resolved === undefined)
|
|
176
|
+
throw new RefError('missing_ref_target', targetPath);
|
|
177
|
+
const inlined = inline(resolved, dirname(targetPath), depth + 1, new Set([...stack, key]));
|
|
178
|
+
const slug = slugify(`${targetPath}__${pointer}`);
|
|
179
|
+
components[slug] = inlined;
|
|
180
|
+
return { $ref: `#/components/${slug}` };
|
|
181
|
+
}
|
|
182
|
+
const out = {};
|
|
183
|
+
for (const k of Object.keys(rec))
|
|
184
|
+
out[k] = inline(rec[k], curDir, depth, stack);
|
|
185
|
+
return out;
|
|
186
|
+
}
|
|
187
|
+
return node;
|
|
188
|
+
};
|
|
189
|
+
const inlinedRoot = inline(root, dirname(rootPath), 0, new Set());
|
|
190
|
+
if (Object.keys(components).length > 0) {
|
|
191
|
+
const existing = (inlinedRoot.components && typeof inlinedRoot.components === 'object') ? inlinedRoot.components : {};
|
|
192
|
+
inlinedRoot.components = { ...existing, ...components };
|
|
193
|
+
}
|
|
194
|
+
return (0, resolver_yaml_js_1.stableStringify)(inlinedRoot);
|
|
195
|
+
}
|
|
196
|
+
// ── blob access ───────────────────────────────────────────────────────────────────────────────
|
|
197
|
+
function getBlob(input, ref, path) {
|
|
198
|
+
return input.blobs[`${ref}:${path}`];
|
|
199
|
+
}
|
|
200
|
+
function loadRoot(path, type, input, config) {
|
|
201
|
+
const baseBlob = getBlob(input, input.baseRef, path);
|
|
202
|
+
const headBlob = getBlob(input, input.headRef, path);
|
|
203
|
+
if (baseBlob && typeof baseBlob === 'object')
|
|
204
|
+
return { unresolved: { path, reason: baseBlob.error } };
|
|
205
|
+
if (headBlob && typeof headBlob === 'object')
|
|
206
|
+
return { unresolved: { path, reason: headBlob.error } };
|
|
207
|
+
const baseNull = baseBlob === null || baseBlob === undefined;
|
|
208
|
+
const headNull = headBlob === null || headBlob === undefined;
|
|
209
|
+
if (baseNull && headNull)
|
|
210
|
+
return { unresolved: { path, reason: 'empty_changed_contract' } };
|
|
211
|
+
let before = baseNull ? '' : baseBlob;
|
|
212
|
+
let after = headNull ? '' : headBlob;
|
|
213
|
+
const deps = new Set();
|
|
214
|
+
const assemble = (type === 'openapi' || type === 'asyncapi') && (config.openApiAssembly ?? 'bundle_inline') === 'bundle_inline';
|
|
215
|
+
if (assemble) {
|
|
216
|
+
try {
|
|
217
|
+
if (before !== '' && scanRefs(before).some((r) => !isInternalRef(r)))
|
|
218
|
+
before = assembleSide(path, before, input.baseRef, input, config, deps);
|
|
219
|
+
if (after !== '' && scanRefs(after).some((r) => !isInternalRef(r)))
|
|
220
|
+
after = assembleSide(path, after, input.headRef, input, config, deps);
|
|
221
|
+
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
if (e instanceof RefError)
|
|
224
|
+
return { unresolved: { path, reason: e.reason, ...(e.related ? { related_paths: [e.related] } : {}) } };
|
|
225
|
+
throw e;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const id = input.repository ? `${input.repository}:${type}:${path}` : `${type}:${path}`;
|
|
229
|
+
return { artifact: { id, type, before, after }, deps: [...deps] };
|
|
230
|
+
}
|
|
231
|
+
function selectGroups(candidates, config, generatedGlobs) {
|
|
232
|
+
const n = candidates.length;
|
|
233
|
+
const parent = Array.from({ length: n }, (_, i) => i);
|
|
234
|
+
const find = (x) => { while (parent[x] !== x) {
|
|
235
|
+
parent[x] = parent[parent[x]];
|
|
236
|
+
x = parent[x];
|
|
237
|
+
} return x; };
|
|
238
|
+
const union = (a, b) => { const ra = find(a); const rb = find(b); if (ra !== rb)
|
|
239
|
+
parent[Math.max(ra, rb)] = Math.min(ra, rb); };
|
|
240
|
+
// forceSameSurfaceGroup: union all listed candidates.
|
|
241
|
+
if (Array.isArray(config.forceSameSurfaceGroup)) {
|
|
242
|
+
const idxs = candidates.map((c, i) => (config.forceSameSurfaceGroup.includes(c.path) ? i : -1)).filter((i) => i >= 0);
|
|
243
|
+
for (let k = 1; k < idxs.length; k += 1)
|
|
244
|
+
union(idxs[0], idxs[k]);
|
|
245
|
+
}
|
|
246
|
+
// generated↔source auto-pairing: per type, if the type mixes generated + non-generated → union all.
|
|
247
|
+
const byType = new Map();
|
|
248
|
+
candidates.forEach((c, i) => { const a = byType.get(c.type) ?? []; a.push(i); byType.set(c.type, a); });
|
|
249
|
+
for (const idxs of byType.values()) {
|
|
250
|
+
const gen = idxs.filter((i) => (0, resolver_glob_js_1.matchAny)(generatedGlobs, candidates[i].path));
|
|
251
|
+
if (gen.length > 0 && gen.length < idxs.length)
|
|
252
|
+
for (let k = 1; k < idxs.length; k += 1)
|
|
253
|
+
union(idxs[0], idxs[k]);
|
|
254
|
+
}
|
|
255
|
+
const groups = new Map();
|
|
256
|
+
for (let i = 0; i < n; i += 1) {
|
|
257
|
+
const r = find(i);
|
|
258
|
+
const g = groups.get(r) ?? [];
|
|
259
|
+
g.push(i);
|
|
260
|
+
groups.set(r, g);
|
|
261
|
+
}
|
|
262
|
+
const selections = [];
|
|
263
|
+
const chosen = [];
|
|
264
|
+
const ambiguous = [];
|
|
265
|
+
for (const g of groups.values()) {
|
|
266
|
+
const members = g.map((i) => candidates[i].path).sort();
|
|
267
|
+
if (members.length === 1) {
|
|
268
|
+
chosen.push(candidates[g[0]]);
|
|
269
|
+
selections.push({ chosen: members[0], deferred: [], reason: 'single' });
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
// ssotPrefer first-match wins.
|
|
273
|
+
const prefRanked = members.map((p) => ({ p, rank: (0, resolver_glob_js_1.firstMatchIndex)(config.ssotPrefer, p) })).filter((x) => x.rank >= 0);
|
|
274
|
+
if (prefRanked.length > 0) {
|
|
275
|
+
prefRanked.sort((a, b) => (a.rank - b.rank) || (a.p < b.p ? -1 : 1));
|
|
276
|
+
const chosenPath = prefRanked[0].p;
|
|
277
|
+
chosen.push(candidates[g.find((i) => candidates[i].path === chosenPath)]);
|
|
278
|
+
selections.push({ chosen: chosenPath, deferred: members.filter((m) => m !== chosenPath), reason: 'ssotPrefer' });
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
// generated deprioritization: exactly one non-generated source wins.
|
|
282
|
+
const nongen = members.filter((p) => !(0, resolver_glob_js_1.matchAny)(generatedGlobs, p));
|
|
283
|
+
if (nongen.length === 1) {
|
|
284
|
+
const chosenPath = nongen[0];
|
|
285
|
+
chosen.push(candidates[g.find((i) => candidates[i].path === chosenPath)]);
|
|
286
|
+
selections.push({ chosen: chosenPath, deferred: members.filter((m) => m !== chosenPath), reason: 'generated_deprioritized' });
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
// else ambiguous — no pick-by-guess.
|
|
290
|
+
ambiguous.push(...members);
|
|
291
|
+
}
|
|
292
|
+
return { selections, chosen, ambiguous };
|
|
293
|
+
}
|
|
294
|
+
// ── the pure resolve (§1.1) ─────────────────────────────────────────────────────────────────────
|
|
295
|
+
function resolve(input, config = {}) {
|
|
296
|
+
const generatedGlobs = config.generatedGlobs ?? DEFAULT_GENERATED;
|
|
297
|
+
// 1-2. normalize + stable-dedupe changedFiles.
|
|
298
|
+
const seen = new Set();
|
|
299
|
+
const paths = [];
|
|
300
|
+
for (const raw of (Array.isArray(input.changedFiles) ? input.changedFiles : [])) {
|
|
301
|
+
const p = normalizePath(raw);
|
|
302
|
+
if (p && !seen.has(p)) {
|
|
303
|
+
seen.add(p);
|
|
304
|
+
paths.push(p);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// 3-4. discover contract candidates vs ignored non-contract.
|
|
308
|
+
const candidates = [];
|
|
309
|
+
const ignored = [];
|
|
310
|
+
for (const p of paths) {
|
|
311
|
+
if ((0, resolver_glob_js_1.matchAny)(VENDOR_GLOBS, p)) {
|
|
312
|
+
ignored.push(p);
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
let type = config.pathTypeHints?.[p] ?? classifyByName(p);
|
|
316
|
+
if (type === null || isMcpByNameNeedingContent(p)) {
|
|
317
|
+
const peek = firstDefinedText(getBlob(input, input.headRef, p), getBlob(input, input.baseRef, p));
|
|
318
|
+
const sniff = classifyByContent(peek);
|
|
319
|
+
if (isMcpByNameNeedingContent(p))
|
|
320
|
+
type = sniff === 'mcp_manifest' ? 'mcp_manifest' : (type ?? sniff);
|
|
321
|
+
else
|
|
322
|
+
type = sniff;
|
|
323
|
+
}
|
|
324
|
+
if (type)
|
|
325
|
+
candidates.push({ path: p, type });
|
|
326
|
+
else
|
|
327
|
+
ignored.push(p);
|
|
328
|
+
}
|
|
329
|
+
const unresolved = [];
|
|
330
|
+
let effectiveCandidates = candidates;
|
|
331
|
+
// strict SSOT: a required, declared, exact ssotPrefer path that is absent → config_ssot_missing.
|
|
332
|
+
if (config.requireSsotIfConfigured && Array.isArray(config.ssotPrefer)) {
|
|
333
|
+
const missing = config.ssotPrefer.filter((pref) => !hasGlobChar(pref) && !existsInTree(input, pref));
|
|
334
|
+
const hasGenerated = candidates.some((c) => (0, resolver_glob_js_1.matchAny)(generatedGlobs, c.path));
|
|
335
|
+
if (missing.length > 0 && hasGenerated) {
|
|
336
|
+
for (const pref of missing)
|
|
337
|
+
unresolved.push({ path: pref, reason: 'config_ssot_missing' });
|
|
338
|
+
effectiveCandidates = candidates.filter((c) => !(0, resolver_glob_js_1.matchAny)(generatedGlobs, c.path)); // deprioritized generated suppressed
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// 5. SSOT grouping + selection.
|
|
342
|
+
const { selections, chosen, ambiguous } = selectGroups(effectiveCandidates, config, generatedGlobs);
|
|
343
|
+
for (const p of [...new Set(ambiguous)].sort())
|
|
344
|
+
unresolved.push({ path: p, reason: 'ambiguous_ssot' });
|
|
345
|
+
// 7. load each selected root → artifact | unresolved; reclassify $ref dependency files.
|
|
346
|
+
const artifacts = [];
|
|
347
|
+
const selBySel = new Map(selections.map((s) => [s.chosen, s]));
|
|
348
|
+
for (const c of chosen.slice().sort((a, b) => (a.path < b.path ? -1 : 1))) {
|
|
349
|
+
const res = loadRoot(c.path, c.type, input, config);
|
|
350
|
+
if ('artifact' in res) {
|
|
351
|
+
artifacts.push(res.artifact);
|
|
352
|
+
const sel = selBySel.get(c.path);
|
|
353
|
+
for (const dep of res.deps) {
|
|
354
|
+
const idx = ignored.indexOf(dep);
|
|
355
|
+
if (idx >= 0)
|
|
356
|
+
ignored.splice(idx, 1);
|
|
357
|
+
if (sel && !sel.deferred.includes(dep) && dep !== c.path)
|
|
358
|
+
sel.deferred.push(dep);
|
|
359
|
+
}
|
|
360
|
+
if (sel)
|
|
361
|
+
sel.deferred.sort();
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
unresolved.push(res.unresolved);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// 6/7. coverage (§7).
|
|
368
|
+
const A = artifacts.length;
|
|
369
|
+
const U = unresolved.length;
|
|
370
|
+
const chosenCount = chosen.length;
|
|
371
|
+
let coverage;
|
|
372
|
+
if (chosenCount === 0 && U === 0)
|
|
373
|
+
coverage = 'EMPTY';
|
|
374
|
+
else if (U === 0 && A >= 1 && A === chosenCount)
|
|
375
|
+
coverage = 'COMPLETE';
|
|
376
|
+
else if (A >= 1 && U >= 1)
|
|
377
|
+
coverage = 'PARTIAL';
|
|
378
|
+
else
|
|
379
|
+
coverage = 'UNRESOLVED';
|
|
380
|
+
// sort outputs deterministically (§6).
|
|
381
|
+
artifacts.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
382
|
+
unresolved.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : (a.reason < b.reason ? -1 : a.reason > b.reason ? 1 : 0)));
|
|
383
|
+
ignored.sort();
|
|
384
|
+
const contractDiscovered = effectiveCandidates.map((c) => c.path).slice().sort();
|
|
385
|
+
return {
|
|
386
|
+
artifacts,
|
|
387
|
+
unresolved,
|
|
388
|
+
coverage,
|
|
389
|
+
report: {
|
|
390
|
+
version: 'artifact-resolver-report/1.0',
|
|
391
|
+
baseRef: input.baseRef,
|
|
392
|
+
headRef: input.headRef,
|
|
393
|
+
contract_paths_discovered: contractDiscovered,
|
|
394
|
+
ignored_non_contract: ignored,
|
|
395
|
+
ssot_selections: selections,
|
|
396
|
+
claim: {
|
|
397
|
+
artifacts_ready_for_preflight: coverage === 'COMPLETE' || coverage === 'EMPTY',
|
|
398
|
+
produces_verdict: false,
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
function firstDefinedText(...vals) {
|
|
404
|
+
for (const v of vals)
|
|
405
|
+
if (typeof v === 'string')
|
|
406
|
+
return v;
|
|
407
|
+
return undefined;
|
|
408
|
+
}
|
|
409
|
+
function hasGlobChar(p) { return /[*?]/.test(p); }
|
|
410
|
+
function existsInTree(input, path) {
|
|
411
|
+
return typeof getBlob(input, input.baseRef, path) === 'string' || typeof getBlob(input, input.headRef, path) === 'string';
|
|
412
|
+
}
|
|
413
|
+
//# sourceMappingURL=artifact-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-resolver.js","sourceRoot":"","sources":["../../src/artifact-resolver.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;AAmTH,0BAgGC;AAjZD,yDAA8E;AAC9E,yDAA+D;AAwD/D,MAAM,iBAAiB,GAAG,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;AAC3D,MAAM,YAAY,GAAG,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC;AAE5D,oGAAoG;AACpG,SAAS,aAAa,CAAC,CAAS;IAC9B,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,CAAC;AACX,CAAC;AACD,SAAS,OAAO,CAAC,CAAS;IACxB,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACvC,CAAC;AACD,SAAS,QAAQ,CAAC,CAAS;IACzB,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACvC,CAAC;AACD,SAAS,OAAO,CAAC,CAAS;IACxB,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AACtD,CAAC;AACD,SAAS,eAAe,CAAC,GAAW,EAAE,GAAW;IAC/C,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAChF,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,KAAK,GAAG;YAAE,SAAS;QACxC,IAAI,GAAG,KAAK,IAAI;YAAE,GAAG,CAAC,GAAG,EAAE,CAAC;;YACvB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,mGAAmG;AACnG,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,QAAQ,GAAG,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,CAAC;IACnE,IAAI,QAAQ,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACnF,IAAI,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IAC1D,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC;IACzD,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,MAAM,CAAC;IACnC,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,oBAAoB;QAAE,OAAO,cAAc,CAAC;IAC1E,OAAO,IAAI,CAAC;AACd,CAAC;AACD,SAAS,iBAAiB,CAAC,IAAwB;IACjD,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,IAAI,4CAA4C,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACtI,IAAI,iCAAiC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,UAAU,CAAC;IACpE,IAAI,oDAAoD,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACtF,IAAI,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/D,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,aAAa,IAAK,CAAY,CAAC;YAAE,OAAO,cAAc,CAAC;IACvJ,CAAC;IAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAC1B,OAAO,IAAI,CAAC;AACd,CAAC;AACD,wGAAwG;AACxG,SAAS,yBAAyB,CAAC,IAAY;IAC7C,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IACvC,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC;AAC3E,CAAC;AAED,qGAAqG;AACrG,MAAM,MAAM,GAAG,0CAA0C,CAAC;AAC1D,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,CAAyB,CAAC;IAC9B,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC;IACrB,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI;QAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,OAAO,GAAG,CAAC;AACb,CAAC;AACD,SAAS,aAAa,CAAC,GAAW,IAAa,OAAO,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACrH,SAAS,aAAa,CAAC,GAAW,IAAa,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC5E,SAAS,QAAQ,CAAC,GAAW;IAC3B,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;AACtG,CAAC;AACD,SAAS,WAAW,CAAC,GAAY,EAAE,OAAe;IAChD,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,GAAG,CAAC;IAClD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAC1G,IAAI,GAAG,GAAY,GAAG,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,IAAI,IAAK,GAA+B;YAAE,GAAG,GAAI,GAA+B,CAAC,IAAI,CAAC,CAAC;;YACxH,OAAO,SAAS,CAAC;IACxB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AACD,SAAS,OAAO,CAAC,CAAS,IAAY,OAAO,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAEhF,MAAM,QAAS,SAAQ,KAAK;IAC1B,MAAM,CAAmB;IACzB,OAAO,CAAU;IACjB,YAAY,MAAwB,EAAE,OAAgB,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;CACzH;AAED,0GAA0G;AAC1G,SAAS,YAAY,CACnB,QAAgB,EAAE,QAAgB,EAAE,OAAe,EAAE,KAAmB,EAAE,MAAqB,EAAE,IAAiB;IAElH,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC;IACzC,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QAAC,IAAI,GAAG,IAAA,2BAAQ,EAAC,QAAQ,CAAC,CAAC;IAAC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,YAAY,gCAAa;YAAE,MAAM,IAAI,QAAQ,CAAC,aAAa,CAAC,CAAC;QAClE,MAAM,CAAC,CAAC;IACV,CAAC;IACD,MAAM,UAAU,GAA4B,EAAE,CAAC;IAE/C,MAAM,MAAM,GAAG,CAAC,IAAa,EAAE,MAAc,EAAE,KAAa,EAAE,KAAkB,EAAW,EAAE;QAC3F,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACjF,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,IAA+B,CAAC;YAC5C,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACjC,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;gBACrB,IAAI,aAAa,CAAC,GAAG,CAAC;oBAAE,MAAM,IAAI,QAAQ,CAAC,wBAAwB,CAAC,CAAC,CAAC,4BAA4B;gBAClG,IAAI,aAAa,CAAC,GAAG,CAAC;oBAAE,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,uDAAuD;gBAClG,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;gBACxC,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACjD,MAAM,GAAG,GAAG,GAAG,UAAU,IAAI,OAAO,EAAE,CAAC;gBACvC,IAAI,KAAK,GAAG,CAAC,GAAG,QAAQ;oBAAE,MAAM,IAAI,QAAQ,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;gBAC/E,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,MAAM,IAAI,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;gBAChE,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;gBACjD,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;oBAAE,MAAM,IAAI,QAAQ,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;gBAC9F,IAAI,OAAO,IAAI,KAAK,QAAQ;oBAAE,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBACzE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACrB,IAAI,SAAkB,CAAC;gBACvB,IAAI,CAAC;oBAAC,SAAS,GAAG,IAAA,2BAAQ,EAAC,IAAI,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC;oBAAC,MAAM,IAAI,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;gBAAC,CAAC;gBAC5F,MAAM,QAAQ,GAAG,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBACjD,IAAI,QAAQ,KAAK,SAAS;oBAAE,MAAM,IAAI,QAAQ,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;gBACjF,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC3F,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,UAAU,KAAK,OAAO,EAAE,CAAC,CAAC;gBAClD,UAAU,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;gBAC3B,OAAO,EAAE,IAAI,EAAE,gBAAgB,IAAI,EAAE,EAAE,CAAC;YAC1C,CAAC;YACD,MAAM,GAAG,GAA4B,EAAE,CAAC;YACxC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAChF,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,EAAE,CAA4B,CAAC;IAC7F,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,CAAC,WAAW,CAAC,UAAU,IAAI,OAAO,WAAW,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,UAAqC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjJ,WAAW,CAAC,UAAU,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,UAAU,EAAE,CAAC;IAC1D,CAAC;IACD,OAAO,IAAA,kCAAe,EAAC,WAAW,CAAC,CAAC;AACtC,CAAC;AAED,iGAAiG;AACjG,SAAS,OAAO,CAAC,KAAmB,EAAE,GAAW,EAAE,IAAY;IAC7D,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;AACvC,CAAC;AAKD,SAAS,QAAQ,CAAC,IAAY,EAAE,IAAkB,EAAE,KAAmB,EAAE,MAAqB;IAC5F,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAErD,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;IACtG,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;IAEtG,MAAM,QAAQ,GAAG,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,CAAC;IAC7D,MAAM,QAAQ,GAAG,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,CAAC;IAC7D,IAAI,QAAQ,IAAI,QAAQ;QAAE,OAAO,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,wBAAwB,EAAE,EAAE,CAAC;IAE5F,IAAI,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,QAAmB,CAAC;IAClD,IAAI,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,QAAmB,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,MAAM,QAAQ,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,eAAe,CAAC,KAAK,eAAe,CAAC;IAChI,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC;YACH,IAAI,MAAM,KAAK,EAAE,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBAAE,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;YAC9I,IAAI,KAAK,KAAK,EAAE,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBAAE,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC5I,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,YAAY,QAAQ;gBAAE,OAAO,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACnI,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAED,MAAM,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,UAAU,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IACxF,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;AACpE,CAAC;AAKD,SAAS,YAAY,CAAC,UAAuB,EAAE,MAAqB,EAAE,cAAwB;IAE5F,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;IAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE,GAAG,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5H,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhJ,sDAAsD;IACtD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,qBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACvH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,oGAAoG;IACpG,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IACjD,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxG,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,2BAAQ,EAAC,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7E,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM;YAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACnH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAAC,CAAC;IAEjH,MAAM,UAAU,GAAoB,EAAE,CAAC;IACvC,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QACxD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9B,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YACxE,SAAS;QACX,CAAC;QACD,+BAA+B;QAC/B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAA,kCAAe,EAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACvH,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrE,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAE,CAAC,CAAC,CAAC;YAC3E,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,UAAU,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;YACjH,SAAS;QACX,CAAC;QACD,qEAAqE;QACrE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAA,2BAAQ,EAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC;QACnE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAE,CAAC,CAAC,CAAC;YAC3E,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,UAAU,CAAC,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC,CAAC;YAC9H,SAAS;QACX,CAAC;QACD,qCAAqC;QACrC,SAAS,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC3C,CAAC;AAED,mGAAmG;AACnG,SAAgB,OAAO,CAAC,KAAmB,EAAE,SAAwB,EAAE;IACrE,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,iBAAiB,CAAC;IAElE,+CAA+C;IAC/C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAChF,MAAM,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;IACxD,CAAC;IAED,6DAA6D;IAC7D,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,IAAA,2BAAQ,EAAC,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC7D,IAAI,IAAI,GAAwB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC;QAC/E,IAAI,IAAI,KAAK,IAAI,IAAI,yBAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YAClG,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,yBAAyB,CAAC,CAAC,CAAC;gBAAE,IAAI,GAAG,KAAK,KAAK,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC;;gBAChG,IAAI,GAAG,KAAK,CAAC;QACpB,CAAC;QACD,IAAI,IAAI;YAAE,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;;YACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,UAAU,GAAsB,EAAE,CAAC;IACzC,IAAI,mBAAmB,GAAG,UAAU,CAAC;IAErC,iGAAiG;IACjG,IAAI,MAAM,CAAC,uBAAuB,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QACvE,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QACrG,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,2BAAQ,EAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9E,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,EAAE,CAAC;YACvC,KAAK,MAAM,IAAI,IAAI,OAAO;gBAAE,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC,CAAC;YAC3F,mBAAmB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAA,2BAAQ,EAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,qCAAqC;QAC1H,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,mBAAmB,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IACpG,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE;QAAE,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAEvG,wFAAwF;IACxF,MAAM,SAAS,GAAuB,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACpD,IAAI,UAAU,IAAI,GAAG,EAAE,CAAC;YACtB,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC7B,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACjC,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACjC,IAAI,GAAG,IAAI,CAAC;oBAAE,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBACrC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI;oBAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnF,CAAC;YACD,IAAI,GAAG;gBAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC;IAC3B,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;IAC5B,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IAClC,IAAI,QAAyB,CAAC;IAC9B,IAAI,WAAW,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,QAAQ,GAAG,OAAO,CAAC;SAChD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,WAAW;QAAE,QAAQ,GAAG,UAAU,CAAC;SAClE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,QAAQ,GAAG,SAAS,CAAC;;QAC3C,QAAQ,GAAG,YAAY,CAAC;IAE7B,uCAAuC;IACvC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnI,OAAO,CAAC,IAAI,EAAE,CAAC;IACf,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;IAEjF,OAAO;QACL,SAAS;QACT,UAAU;QACV,QAAQ;QACR,MAAM,EAAE;YACN,OAAO,EAAE,8BAA8B;YACvC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,yBAAyB,EAAE,kBAAkB;YAC7C,oBAAoB,EAAE,OAAO;YAC7B,eAAe,EAAE,UAAU;YAC3B,KAAK,EAAE;gBACL,6BAA6B,EAAE,QAAQ,KAAK,UAAU,IAAI,QAAQ,KAAK,OAAO;gBAC9E,gBAAgB,EAAE,KAAK;aACxB;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAG,IAA+B;IAC1D,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC;IAC1D,OAAO,SAAS,CAAC;AACnB,CAAC;AACD,SAAS,WAAW,CAAC,CAAS,IAAa,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnE,SAAS,YAAY,CAAC,KAAmB,EAAE,IAAY;IACrD,OAAO,OAAO,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,QAAQ,CAAC;AAC5H,CAAC"}
|
package/dist/cjs/guard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EACV,WAAW,EAAE,YAAY,EACT,kBAAkB,EAAE,cAAc,EAEnD,MAAM,YAAY,CAAC;AA+
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EACV,WAAW,EAAE,YAAY,EACT,kBAAkB,EAAE,cAAc,EAEnD,MAAM,YAAY,CAAC;AA+JpB,wBAAsB,aAAa,CAAC,CAAC,EACnC,IAAI,EAAE,kBAAkB,EACxB,cAAc,EAAE,cAAc,CAAC,CAAC,CAAC,EACjC,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAoL1B"}
|
package/dist/cjs/guard.js
CHANGED
|
@@ -152,6 +152,23 @@ async function runUnenforced(config, factory, envelope, verdict, preflighted, re
|
|
|
152
152
|
function blocked(verdict, preflighted) {
|
|
153
153
|
return { executionAttempted: false, executed: false, enforced: false, verdict, preflighted };
|
|
154
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* True iff at least one supplied artifact carries analyzable before/after content. A preflight
|
|
157
|
+
* trigger with no such content cannot be analyzed by the server (an empty list comes back as an
|
|
158
|
+
* opaque REQUEST_REJECTED), so the guard fails closed LOCALLY with MISSING_ARTIFACT_CONTENT instead.
|
|
159
|
+
* Reads defensively — the caller's artifacts are untrusted runtime data.
|
|
160
|
+
*/
|
|
161
|
+
function hasAnalyzableContent(artifacts) {
|
|
162
|
+
if (!Array.isArray(artifacts) || artifacts.length === 0)
|
|
163
|
+
return false;
|
|
164
|
+
return artifacts.some((a) => {
|
|
165
|
+
if (!a || typeof a !== 'object')
|
|
166
|
+
return false;
|
|
167
|
+
const before = a.before;
|
|
168
|
+
const after = a.after;
|
|
169
|
+
return (typeof before === 'string' && before.length > 0) || (typeof after === 'string' && after.length > 0);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
155
172
|
function unavailableVerdict(parts, count) {
|
|
156
173
|
return { kind: 'UNAVAILABLE', decisionMissing: true, unavailableCount: count, ...parts };
|
|
157
174
|
}
|
|
@@ -187,6 +204,20 @@ async function guardToolCall(call, executeFactory, config) {
|
|
|
187
204
|
const verdict = { kind: 'SKIPPED', reason: 'NOT_A_CONTRACT_CALL', signals: detection.signals, detectorVersion: detector.version };
|
|
188
205
|
return runUnenforced(config, executeFactory, null, verdict, false, redacted);
|
|
189
206
|
}
|
|
207
|
+
// MISSING_ARTIFACT_CONTENT — developer-adoption fail-closed (audit #1). The detector says a contract
|
|
208
|
+
// change is happening (trigger:true) but the caller supplied NO analyzable content: no artifacts, or
|
|
209
|
+
// artifacts without before/after. Sending an empty list to the server returns an opaque
|
|
210
|
+
// REQUEST_REJECTED; instead fail closed LOCALLY with a clear, actionable cause so the developer knows
|
|
211
|
+
// to pass artifacts:[{ id, type, before, after }]. The tool does NOT execute (fail-closed preserved).
|
|
212
|
+
// This can only fire when preflight is genuinely required — a non-contract/readonly call already
|
|
213
|
+
// returned via the SKIPPED path above. It is NOT a server-availability failure, so it does NOT trip
|
|
214
|
+
// the breaker (a developer's missing content must not degrade the open-policy path for later calls).
|
|
215
|
+
if (!hasAnalyzableContent(detection.artifacts)) {
|
|
216
|
+
emit(config, { type: 'artifact_content_missing', at: iso(), cause: 'MISSING_ARTIFACT_CONTENT', signals: detection.signals });
|
|
217
|
+
const count = (breakers.get(config)?.fails.length) ?? 0;
|
|
218
|
+
const v = unavailableVerdict({ cause: 'MISSING_ARTIFACT_CONTENT', failPolicy, resolution: 'CLOSED', action: 'STOP' }, count);
|
|
219
|
+
return blocked(v, false);
|
|
220
|
+
}
|
|
190
221
|
// config validation: lkg policy requires an LkgStore.
|
|
191
222
|
if (failPolicy === 'lkg' && !config.lkg) {
|
|
192
223
|
breakerRecord(config);
|