@neurcode-ai/cli 0.10.1 → 0.14.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/.telemetry-bundle/dist/contracts.d.ts +1 -1
- package/README.md +74 -25
- package/dist/commands/governance.d.ts.map +1 -1
- package/dist/commands/governance.js +12 -0
- package/dist/commands/governance.js.map +1 -1
- package/dist/commands/home.d.ts +21 -0
- package/dist/commands/home.d.ts.map +1 -0
- package/dist/commands/home.js +253 -0
- package/dist/commands/home.js.map +1 -0
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/quickstart.d.ts.map +1 -1
- package/dist/commands/quickstart.js +13 -11
- package/dist/commands/quickstart.js.map +1 -1
- package/dist/commands/remediate-export.d.ts.map +1 -1
- package/dist/commands/remediate-export.js +17 -2
- package/dist/commands/remediate-export.js.map +1 -1
- package/dist/commands/replay.d.ts.map +1 -1
- package/dist/commands/replay.js +36 -0
- package/dist/commands/replay.js.map +1 -1
- package/dist/commands/verify-output.d.ts.map +1 -1
- package/dist/commands/verify-output.js +88 -4
- package/dist/commands/verify-output.js.map +1 -1
- package/dist/commands/verify.d.ts +22 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +467 -37
- package/dist/commands/verify.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +4 -0
- package/dist/daemon/server.js.map +1 -1
- package/dist/governance/canonical-pipeline.d.ts.map +1 -1
- package/dist/governance/canonical-pipeline.js +29 -3
- package/dist/governance/canonical-pipeline.js.map +1 -1
- package/dist/governance/intent/drift-detector.d.ts +100 -0
- package/dist/governance/intent/drift-detector.d.ts.map +1 -0
- package/dist/governance/intent/drift-detector.js +275 -0
- package/dist/governance/intent/drift-detector.js.map +1 -0
- package/dist/governance/intent/glob-match.d.ts +43 -0
- package/dist/governance/intent/glob-match.d.ts.map +1 -0
- package/dist/governance/intent/glob-match.js +108 -0
- package/dist/governance/intent/glob-match.js.map +1 -0
- package/dist/governance/intent/import-graph.d.ts +56 -0
- package/dist/governance/intent/import-graph.d.ts.map +1 -0
- package/dist/governance/intent/import-graph.js +133 -0
- package/dist/governance/intent/import-graph.js.map +1 -0
- package/dist/governance/intent/index.d.ts +23 -0
- package/dist/governance/intent/index.d.ts.map +1 -0
- package/dist/governance/intent/index.js +48 -0
- package/dist/governance/intent/index.js.map +1 -0
- package/dist/governance/intent/intelligence-boundaries.d.ts +69 -0
- package/dist/governance/intent/intelligence-boundaries.d.ts.map +1 -0
- package/dist/governance/intent/intelligence-boundaries.js +163 -0
- package/dist/governance/intent/intelligence-boundaries.js.map +1 -0
- package/dist/governance/intent/intent-contract.d.ts +76 -0
- package/dist/governance/intent/intent-contract.d.ts.map +1 -0
- package/dist/governance/intent/intent-contract.js +397 -0
- package/dist/governance/intent/intent-contract.js.map +1 -0
- package/dist/governance/intent/intent-graph.d.ts +135 -0
- package/dist/governance/intent/intent-graph.d.ts.map +1 -0
- package/dist/governance/intent/intent-graph.js +67 -0
- package/dist/governance/intent/intent-graph.js.map +1 -0
- package/dist/governance/pipeline/computation-trace.d.ts +52 -0
- package/dist/governance/pipeline/computation-trace.d.ts.map +1 -0
- package/dist/governance/pipeline/computation-trace.js +79 -0
- package/dist/governance/pipeline/computation-trace.js.map +1 -0
- package/dist/governance/pipeline/envelope-assembly.d.ts +132 -0
- package/dist/governance/pipeline/envelope-assembly.d.ts.map +1 -0
- package/dist/governance/pipeline/envelope-assembly.js +140 -0
- package/dist/governance/pipeline/envelope-assembly.js.map +1 -0
- package/dist/governance/pipeline/fingerprint.d.ts +34 -0
- package/dist/governance/pipeline/fingerprint.d.ts.map +1 -0
- package/dist/governance/pipeline/fingerprint.js +78 -0
- package/dist/governance/pipeline/fingerprint.js.map +1 -0
- package/dist/governance/pipeline/helpers.d.ts +74 -0
- package/dist/governance/pipeline/helpers.d.ts.map +1 -0
- package/dist/governance/pipeline/helpers.js +112 -0
- package/dist/governance/pipeline/helpers.js.map +1 -0
- package/dist/governance/pipeline/index.d.ts +27 -0
- package/dist/governance/pipeline/index.d.ts.map +1 -0
- package/dist/governance/pipeline/index.js +63 -0
- package/dist/governance/pipeline/index.js.map +1 -0
- package/dist/governance/pipeline/lineage.d.ts +26 -0
- package/dist/governance/pipeline/lineage.d.ts.map +1 -0
- package/dist/governance/pipeline/lineage.js +51 -0
- package/dist/governance/pipeline/lineage.js.map +1 -0
- package/dist/governance/pipeline/orchestration/advisory-mode-contract.d.ts +15 -0
- package/dist/governance/pipeline/orchestration/advisory-mode-contract.d.ts.map +1 -0
- package/dist/governance/pipeline/orchestration/advisory-mode-contract.js +44 -0
- package/dist/governance/pipeline/orchestration/advisory-mode-contract.js.map +1 -0
- package/dist/governance/pipeline/orchestration/advisory-mode.d.ts +102 -0
- package/dist/governance/pipeline/orchestration/advisory-mode.d.ts.map +1 -0
- package/dist/governance/pipeline/orchestration/advisory-mode.js +170 -0
- package/dist/governance/pipeline/orchestration/advisory-mode.js.map +1 -0
- package/dist/governance/pipeline/orchestration/evidence-lifecycle.d.ts +133 -0
- package/dist/governance/pipeline/orchestration/evidence-lifecycle.d.ts.map +1 -0
- package/dist/governance/pipeline/orchestration/evidence-lifecycle.js +125 -0
- package/dist/governance/pipeline/orchestration/evidence-lifecycle.js.map +1 -0
- package/dist/governance/pipeline/orchestration/index.d.ts +16 -0
- package/dist/governance/pipeline/orchestration/index.d.ts.map +1 -0
- package/dist/governance/pipeline/orchestration/index.js +30 -0
- package/dist/governance/pipeline/orchestration/index.js.map +1 -0
- package/dist/governance/pipeline/orchestration/intent-drift-orchestration.d.ts +65 -0
- package/dist/governance/pipeline/orchestration/intent-drift-orchestration.d.ts.map +1 -0
- package/dist/governance/pipeline/orchestration/intent-drift-orchestration.js +102 -0
- package/dist/governance/pipeline/orchestration/intent-drift-orchestration.js.map +1 -0
- package/dist/governance/pipeline/orchestration/plan-structural-analysis.d.ts +41 -0
- package/dist/governance/pipeline/orchestration/plan-structural-analysis.d.ts.map +1 -0
- package/dist/governance/pipeline/orchestration/plan-structural-analysis.js +74 -0
- package/dist/governance/pipeline/orchestration/plan-structural-analysis.js.map +1 -0
- package/dist/governance/pipeline/orchestration/policy-evaluation-summaries.d.ts +165 -0
- package/dist/governance/pipeline/orchestration/policy-evaluation-summaries.d.ts.map +1 -0
- package/dist/governance/pipeline/orchestration/policy-evaluation-summaries.js +160 -0
- package/dist/governance/pipeline/orchestration/policy-evaluation-summaries.js.map +1 -0
- package/dist/governance/pipeline/orchestration/scope-guard-orchestration.d.ts +152 -0
- package/dist/governance/pipeline/orchestration/scope-guard-orchestration.d.ts.map +1 -0
- package/dist/governance/pipeline/orchestration/scope-guard-orchestration.js +188 -0
- package/dist/governance/pipeline/orchestration/scope-guard-orchestration.js.map +1 -0
- package/dist/governance/pipeline/runtime.d.ts +70 -0
- package/dist/governance/pipeline/runtime.d.ts.map +1 -0
- package/dist/governance/pipeline/runtime.js +223 -0
- package/dist/governance/pipeline/runtime.js.map +1 -0
- package/dist/governance/pipeline/shared-types.d.ts +7 -0
- package/dist/governance/pipeline/shared-types.d.ts.map +1 -0
- package/dist/governance/pipeline/shared-types.js +7 -0
- package/dist/governance/pipeline/shared-types.js.map +1 -0
- package/dist/governance/pipeline/stages/compiled-policy-stage.d.ts +28 -0
- package/dist/governance/pipeline/stages/compiled-policy-stage.d.ts.map +1 -0
- package/dist/governance/pipeline/stages/compiled-policy-stage.js +53 -0
- package/dist/governance/pipeline/stages/compiled-policy-stage.js.map +1 -0
- package/dist/governance/pipeline/stages/diff-normalization-stage.d.ts +63 -0
- package/dist/governance/pipeline/stages/diff-normalization-stage.d.ts.map +1 -0
- package/dist/governance/pipeline/stages/diff-normalization-stage.js +140 -0
- package/dist/governance/pipeline/stages/diff-normalization-stage.js.map +1 -0
- package/dist/governance/pipeline/stages/governance-synthesis-stage.d.ts +53 -0
- package/dist/governance/pipeline/stages/governance-synthesis-stage.d.ts.map +1 -0
- package/dist/governance/pipeline/stages/governance-synthesis-stage.js +129 -0
- package/dist/governance/pipeline/stages/governance-synthesis-stage.js.map +1 -0
- package/dist/governance/pipeline/stages/index.d.ts +29 -0
- package/dist/governance/pipeline/stages/index.d.ts.map +1 -0
- package/dist/governance/pipeline/stages/index.js +40 -0
- package/dist/governance/pipeline/stages/index.js.map +1 -0
- package/dist/governance/pipeline/stages/policy-lock-stage.d.ts +31 -0
- package/dist/governance/pipeline/stages/policy-lock-stage.d.ts.map +1 -0
- package/dist/governance/pipeline/stages/policy-lock-stage.js +71 -0
- package/dist/governance/pipeline/stages/policy-lock-stage.js.map +1 -0
- package/dist/governance/pipeline/stages/runtime-guard-stage.d.ts +29 -0
- package/dist/governance/pipeline/stages/runtime-guard-stage.d.ts.map +1 -0
- package/dist/governance/pipeline/stages/runtime-guard-stage.js +65 -0
- package/dist/governance/pipeline/stages/runtime-guard-stage.js.map +1 -0
- package/dist/governance/pipeline/stages/structural-analysis-stage.d.ts +24 -0
- package/dist/governance/pipeline/stages/structural-analysis-stage.d.ts.map +1 -0
- package/dist/governance/pipeline/stages/structural-analysis-stage.js +58 -0
- package/dist/governance/pipeline/stages/structural-analysis-stage.js.map +1 -0
- package/dist/governance/pipeline/summary.d.ts +14 -0
- package/dist/governance/pipeline/summary.d.ts.map +1 -0
- package/dist/governance/pipeline/summary.js +50 -0
- package/dist/governance/pipeline/summary.js.map +1 -0
- package/dist/governance/pipeline/types.d.ts +69 -0
- package/dist/governance/pipeline/types.d.ts.map +1 -0
- package/dist/governance/pipeline/types.js +30 -0
- package/dist/governance/pipeline/types.js.map +1 -0
- package/dist/index.js +44 -3
- package/dist/index.js.map +1 -1
- package/dist/utils/active-engineering-context.d.ts +16 -0
- package/dist/utils/active-engineering-context.d.ts.map +1 -1
- package/dist/utils/active-engineering-context.js +302 -0
- package/dist/utils/active-engineering-context.js.map +1 -1
- package/dist/utils/import-edge-classifier.d.ts +76 -0
- package/dist/utils/import-edge-classifier.d.ts.map +1 -0
- package/dist/utils/import-edge-classifier.js +308 -0
- package/dist/utils/import-edge-classifier.js.map +1 -0
- package/dist/utils/import-edge-extractor.d.ts +52 -0
- package/dist/utils/import-edge-extractor.d.ts.map +1 -0
- package/dist/utils/import-edge-extractor.js +223 -0
- package/dist/utils/import-edge-extractor.js.map +1 -0
- package/dist/utils/import-edge-governance.d.ts +37 -0
- package/dist/utils/import-edge-governance.d.ts.map +1 -0
- package/dist/utils/import-edge-governance.js +56 -0
- package/dist/utils/import-edge-governance.js.map +1 -0
- package/dist/utils/messages.d.ts.map +1 -1
- package/dist/utils/messages.js +19 -10
- package/dist/utils/messages.js.map +1 -1
- package/dist/utils/path-boundary-classifier.d.ts +42 -0
- package/dist/utils/path-boundary-classifier.d.ts.map +1 -0
- package/dist/utils/path-boundary-classifier.js +143 -0
- package/dist/utils/path-boundary-classifier.js.map +1 -0
- package/dist/utils/replay-html-report.d.ts +29 -0
- package/dist/utils/replay-html-report.d.ts.map +1 -0
- package/dist/utils/replay-html-report.js +309 -0
- package/dist/utils/replay-html-report.js.map +1 -0
- package/dist/utils/runtime-state.d.ts +44 -0
- package/dist/utils/runtime-state.d.ts.map +1 -0
- package/dist/utils/runtime-state.js +151 -0
- package/dist/utils/runtime-state.js.map +1 -0
- package/package.json +3 -3
- package/dist/utils/box.d.ts +0 -16
- package/dist/utils/box.d.ts.map +0 -1
- package/dist/utils/box.js +0 -85
- package/dist/utils/box.js.map +0 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent Contract — declarative architectural intent.
|
|
3
|
+
*
|
|
4
|
+
* Canonical path: `.neurcode/intent.json` (project-relative).
|
|
5
|
+
*
|
|
6
|
+
* The contract is the *human-authored* form. The loader validates it and
|
|
7
|
+
* converts it into a typed `IntentGraph` for the drift engine.
|
|
8
|
+
*
|
|
9
|
+
* Canonical form is JSON for two reasons:
|
|
10
|
+
* 1. Replay determinism — JSON parsing is locale-free and YAML has historical
|
|
11
|
+
* ambiguities ("yes" → bool, leading zeros, multiline). The contract is a
|
|
12
|
+
* replay-relevant artifact, so we lock it to JSON.
|
|
13
|
+
* 2. Zero extra dependencies — adding a YAML parser to the CLI is unjustified
|
|
14
|
+
* for a configuration file the team writes once.
|
|
15
|
+
*
|
|
16
|
+
* Contract example:
|
|
17
|
+
*
|
|
18
|
+
* {
|
|
19
|
+
* "schemaVersion": 1,
|
|
20
|
+
* "layers": [
|
|
21
|
+
* { "id": "controller", "glob": ["src/commands/**", "src/handlers/**"] },
|
|
22
|
+
* { "id": "service", "glob": ["src/services/**"] },
|
|
23
|
+
* { "id": "persistence","glob": ["src/repositories/**", "src/db/**"] }
|
|
24
|
+
* ],
|
|
25
|
+
* "allowedEdges": [
|
|
26
|
+
* { "from": "controller", "to": "service" },
|
|
27
|
+
* { "from": "service", "to": "persistence" }
|
|
28
|
+
* ],
|
|
29
|
+
* "forbiddenEdges": [
|
|
30
|
+
* { "from": "controller", "to": "persistence",
|
|
31
|
+
* "reason": "Controllers must access data via service layer" }
|
|
32
|
+
* ]
|
|
33
|
+
* }
|
|
34
|
+
*
|
|
35
|
+
* Intelligence classification: DETERMINISTIC.
|
|
36
|
+
*/
|
|
37
|
+
import { type IntentGraph } from './intent-graph';
|
|
38
|
+
export declare const INTENT_CONTRACT_FILENAME = "intent.json";
|
|
39
|
+
export declare const INTENT_CONTRACT_RELATIVE_PATH = ".neurcode/intent.json";
|
|
40
|
+
export interface IntentContractLoadResult {
|
|
41
|
+
/** Absolute path the loader probed. */
|
|
42
|
+
path: string;
|
|
43
|
+
/** True if a contract file exists at `path`. */
|
|
44
|
+
exists: boolean;
|
|
45
|
+
/** Parsed graph, or `EMPTY_INTENT_GRAPH` when absent / invalid. */
|
|
46
|
+
graph: IntentGraph;
|
|
47
|
+
/** Validation errors encountered while loading. Empty array on success. */
|
|
48
|
+
errors: string[];
|
|
49
|
+
/** Soft warnings — e.g. unknown fields, zero-glob layer. */
|
|
50
|
+
warnings: string[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the canonical contract path for a project. Does not check existence.
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolveIntentContractPath(projectRoot: string, override?: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Load and validate the intent contract for a project.
|
|
58
|
+
*
|
|
59
|
+
* Behaviour:
|
|
60
|
+
* - If the file does not exist → `exists: false`, graph is empty, no errors.
|
|
61
|
+
* - If the file is malformed JSON → `exists: true`, graph is empty, `errors`
|
|
62
|
+
* contains the parser error.
|
|
63
|
+
* - If the schema is wrong → `exists: true`, graph is empty, `errors` lists
|
|
64
|
+
* every validation failure.
|
|
65
|
+
* - On success → `exists: true`, graph is populated, errors is empty.
|
|
66
|
+
*
|
|
67
|
+
* The loader never throws. Drift detection is opt-in; an unparseable contract
|
|
68
|
+
* must not break verification.
|
|
69
|
+
*/
|
|
70
|
+
export declare function loadIntentContract(projectRoot: string, override?: string): IntentContractLoadResult;
|
|
71
|
+
/**
|
|
72
|
+
* Parse + validate a raw contract value (already-parsed JSON) and build the graph.
|
|
73
|
+
* Exposed for tests so we don't need to touch the filesystem.
|
|
74
|
+
*/
|
|
75
|
+
export declare function buildIntentGraphFromRaw(raw: unknown): IntentContractLoadResult;
|
|
76
|
+
//# sourceMappingURL=intent-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-contract.d.ts","sourceRoot":"","sources":["../../../src/governance/intent/intent-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAKH,OAAO,EAIL,KAAK,WAAW,EAIjB,MAAM,gBAAgB,CAAC;AAIxB,eAAO,MAAM,wBAAwB,gBAAgB,CAAC;AACtD,eAAO,MAAM,6BAA6B,0BAA0C,CAAC;AAIrF,MAAM,WAAW,wBAAwB;IACvC,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,MAAM,EAAE,OAAO,CAAC;IAChB,mEAAmE;IACnE,KAAK,EAAE,WAAW,CAAC;IACnB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAID;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAKxF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,GAChB,wBAAwB,CA0C1B;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,wBAAwB,CAE9E"}
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Intent Contract — declarative architectural intent.
|
|
4
|
+
*
|
|
5
|
+
* Canonical path: `.neurcode/intent.json` (project-relative).
|
|
6
|
+
*
|
|
7
|
+
* The contract is the *human-authored* form. The loader validates it and
|
|
8
|
+
* converts it into a typed `IntentGraph` for the drift engine.
|
|
9
|
+
*
|
|
10
|
+
* Canonical form is JSON for two reasons:
|
|
11
|
+
* 1. Replay determinism — JSON parsing is locale-free and YAML has historical
|
|
12
|
+
* ambiguities ("yes" → bool, leading zeros, multiline). The contract is a
|
|
13
|
+
* replay-relevant artifact, so we lock it to JSON.
|
|
14
|
+
* 2. Zero extra dependencies — adding a YAML parser to the CLI is unjustified
|
|
15
|
+
* for a configuration file the team writes once.
|
|
16
|
+
*
|
|
17
|
+
* Contract example:
|
|
18
|
+
*
|
|
19
|
+
* {
|
|
20
|
+
* "schemaVersion": 1,
|
|
21
|
+
* "layers": [
|
|
22
|
+
* { "id": "controller", "glob": ["src/commands/**", "src/handlers/**"] },
|
|
23
|
+
* { "id": "service", "glob": ["src/services/**"] },
|
|
24
|
+
* { "id": "persistence","glob": ["src/repositories/**", "src/db/**"] }
|
|
25
|
+
* ],
|
|
26
|
+
* "allowedEdges": [
|
|
27
|
+
* { "from": "controller", "to": "service" },
|
|
28
|
+
* { "from": "service", "to": "persistence" }
|
|
29
|
+
* ],
|
|
30
|
+
* "forbiddenEdges": [
|
|
31
|
+
* { "from": "controller", "to": "persistence",
|
|
32
|
+
* "reason": "Controllers must access data via service layer" }
|
|
33
|
+
* ]
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* Intelligence classification: DETERMINISTIC.
|
|
37
|
+
*/
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.INTENT_CONTRACT_RELATIVE_PATH = exports.INTENT_CONTRACT_FILENAME = void 0;
|
|
40
|
+
exports.resolveIntentContractPath = resolveIntentContractPath;
|
|
41
|
+
exports.loadIntentContract = loadIntentContract;
|
|
42
|
+
exports.buildIntentGraphFromRaw = buildIntentGraphFromRaw;
|
|
43
|
+
const fs_1 = require("fs");
|
|
44
|
+
const path_1 = require("path");
|
|
45
|
+
const crypto_1 = require("crypto");
|
|
46
|
+
const intent_graph_1 = require("./intent-graph");
|
|
47
|
+
// ── Canonical artifact path ──────────────────────────────────────────────────
|
|
48
|
+
exports.INTENT_CONTRACT_FILENAME = 'intent.json';
|
|
49
|
+
exports.INTENT_CONTRACT_RELATIVE_PATH = `.neurcode/${exports.INTENT_CONTRACT_FILENAME}`;
|
|
50
|
+
// ── Public API ───────────────────────────────────────────────────────────────
|
|
51
|
+
/**
|
|
52
|
+
* Resolve the canonical contract path for a project. Does not check existence.
|
|
53
|
+
*/
|
|
54
|
+
function resolveIntentContractPath(projectRoot, override) {
|
|
55
|
+
if (override) {
|
|
56
|
+
return (0, path_1.resolve)(projectRoot, override);
|
|
57
|
+
}
|
|
58
|
+
return (0, path_1.join)(projectRoot, '.neurcode', exports.INTENT_CONTRACT_FILENAME);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Load and validate the intent contract for a project.
|
|
62
|
+
*
|
|
63
|
+
* Behaviour:
|
|
64
|
+
* - If the file does not exist → `exists: false`, graph is empty, no errors.
|
|
65
|
+
* - If the file is malformed JSON → `exists: true`, graph is empty, `errors`
|
|
66
|
+
* contains the parser error.
|
|
67
|
+
* - If the schema is wrong → `exists: true`, graph is empty, `errors` lists
|
|
68
|
+
* every validation failure.
|
|
69
|
+
* - On success → `exists: true`, graph is populated, errors is empty.
|
|
70
|
+
*
|
|
71
|
+
* The loader never throws. Drift detection is opt-in; an unparseable contract
|
|
72
|
+
* must not break verification.
|
|
73
|
+
*/
|
|
74
|
+
function loadIntentContract(projectRoot, override) {
|
|
75
|
+
const contractPath = resolveIntentContractPath(projectRoot, override);
|
|
76
|
+
if (!(0, fs_1.existsSync)(contractPath)) {
|
|
77
|
+
return {
|
|
78
|
+
path: contractPath,
|
|
79
|
+
exists: false,
|
|
80
|
+
graph: intent_graph_1.EMPTY_INTENT_GRAPH,
|
|
81
|
+
errors: [],
|
|
82
|
+
warnings: [],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
let raw;
|
|
86
|
+
try {
|
|
87
|
+
raw = (0, fs_1.readFileSync)(contractPath, 'utf8');
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
91
|
+
return {
|
|
92
|
+
path: contractPath,
|
|
93
|
+
exists: true,
|
|
94
|
+
graph: intent_graph_1.EMPTY_INTENT_GRAPH,
|
|
95
|
+
errors: [`failed to read intent contract: ${msg}`],
|
|
96
|
+
warnings: [],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
let parsed;
|
|
100
|
+
try {
|
|
101
|
+
parsed = JSON.parse(raw);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
105
|
+
return {
|
|
106
|
+
path: contractPath,
|
|
107
|
+
exists: true,
|
|
108
|
+
graph: intent_graph_1.EMPTY_INTENT_GRAPH,
|
|
109
|
+
errors: [`invalid JSON in intent contract: ${msg}`],
|
|
110
|
+
warnings: [],
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return validateAndBuildGraph(parsed, contractPath);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Parse + validate a raw contract value (already-parsed JSON) and build the graph.
|
|
117
|
+
* Exposed for tests so we don't need to touch the filesystem.
|
|
118
|
+
*/
|
|
119
|
+
function buildIntentGraphFromRaw(raw) {
|
|
120
|
+
return validateAndBuildGraph(raw, '<inline>');
|
|
121
|
+
}
|
|
122
|
+
// ── Validation ───────────────────────────────────────────────────────────────
|
|
123
|
+
function validateAndBuildGraph(raw, sourcePath) {
|
|
124
|
+
const errors = [];
|
|
125
|
+
const warnings = [];
|
|
126
|
+
if (raw === null || typeof raw !== 'object') {
|
|
127
|
+
return {
|
|
128
|
+
path: sourcePath,
|
|
129
|
+
exists: true,
|
|
130
|
+
graph: intent_graph_1.EMPTY_INTENT_GRAPH,
|
|
131
|
+
errors: ['intent contract must be a JSON object'],
|
|
132
|
+
warnings: [],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const obj = raw;
|
|
136
|
+
// Schema version
|
|
137
|
+
const schemaVersion = obj.schemaVersion;
|
|
138
|
+
if (schemaVersion !== intent_graph_1.INTENT_GRAPH_SCHEMA_VERSION) {
|
|
139
|
+
errors.push(`unsupported schemaVersion: expected ${intent_graph_1.INTENT_GRAPH_SCHEMA_VERSION}, got ${JSON.stringify(schemaVersion)}`);
|
|
140
|
+
}
|
|
141
|
+
// Allowed top-level fields (anything else surfaces as a warning)
|
|
142
|
+
const KNOWN_FIELDS = new Set([
|
|
143
|
+
'schemaVersion',
|
|
144
|
+
'layers',
|
|
145
|
+
'modules',
|
|
146
|
+
'trustBoundaries',
|
|
147
|
+
'allowedEdges',
|
|
148
|
+
'forbiddenEdges',
|
|
149
|
+
]);
|
|
150
|
+
for (const key of Object.keys(obj)) {
|
|
151
|
+
if (!KNOWN_FIELDS.has(key)) {
|
|
152
|
+
warnings.push(`unknown top-level field: ${key}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const layers = validateLayers(obj.layers, errors);
|
|
156
|
+
const modules = validateModules(obj.modules, errors);
|
|
157
|
+
const trustBoundaries = validateTrustBoundaries(obj.trustBoundaries, errors);
|
|
158
|
+
const allowedEdges = validateEdges('allowedEdges', obj.allowedEdges, errors, layers);
|
|
159
|
+
const forbiddenEdges = validateEdges('forbiddenEdges', obj.forbiddenEdges, errors, layers);
|
|
160
|
+
// Soft warnings on the resulting shape
|
|
161
|
+
for (const layer of layers) {
|
|
162
|
+
if (layer.glob.length === 0) {
|
|
163
|
+
warnings.push(`layer "${layer.id}" has no glob patterns; nothing will be classified into it`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (errors.length > 0) {
|
|
167
|
+
return {
|
|
168
|
+
path: sourcePath,
|
|
169
|
+
exists: true,
|
|
170
|
+
graph: intent_graph_1.EMPTY_INTENT_GRAPH,
|
|
171
|
+
errors,
|
|
172
|
+
warnings,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const graph = {
|
|
176
|
+
schemaVersion: intent_graph_1.INTENT_GRAPH_SCHEMA_VERSION,
|
|
177
|
+
layers,
|
|
178
|
+
modules,
|
|
179
|
+
trustBoundaries,
|
|
180
|
+
allowedEdges,
|
|
181
|
+
forbiddenEdges,
|
|
182
|
+
fingerprint: fingerprintGraph({
|
|
183
|
+
layers,
|
|
184
|
+
modules,
|
|
185
|
+
trustBoundaries,
|
|
186
|
+
allowedEdges,
|
|
187
|
+
forbiddenEdges,
|
|
188
|
+
}),
|
|
189
|
+
};
|
|
190
|
+
return {
|
|
191
|
+
path: sourcePath,
|
|
192
|
+
exists: true,
|
|
193
|
+
graph,
|
|
194
|
+
errors: [],
|
|
195
|
+
warnings,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function validateLayers(value, errors) {
|
|
199
|
+
if (value === undefined)
|
|
200
|
+
return [];
|
|
201
|
+
if (!Array.isArray(value)) {
|
|
202
|
+
errors.push('"layers" must be an array');
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
205
|
+
const out = [];
|
|
206
|
+
const seenIds = new Set();
|
|
207
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
208
|
+
const layer = value[i];
|
|
209
|
+
if (layer === null || typeof layer !== 'object') {
|
|
210
|
+
errors.push(`layers[${i}] must be an object`);
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
const rec = layer;
|
|
214
|
+
const id = rec.id;
|
|
215
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
216
|
+
errors.push(`layers[${i}].id must be a non-empty string`);
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (seenIds.has(id)) {
|
|
220
|
+
errors.push(`layers[${i}].id "${id}" is a duplicate`);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
seenIds.add(id);
|
|
224
|
+
const glob = rec.glob;
|
|
225
|
+
if (!Array.isArray(glob) || !glob.every((g) => typeof g === 'string')) {
|
|
226
|
+
errors.push(`layers[${i}].glob must be an array of strings`);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
const description = typeof rec.description === 'string' ? rec.description : undefined;
|
|
230
|
+
out.push({ id, description, glob: glob });
|
|
231
|
+
}
|
|
232
|
+
return out;
|
|
233
|
+
}
|
|
234
|
+
function validateModules(value, errors) {
|
|
235
|
+
if (value === undefined)
|
|
236
|
+
return [];
|
|
237
|
+
if (!Array.isArray(value)) {
|
|
238
|
+
errors.push('"modules" must be an array');
|
|
239
|
+
return [];
|
|
240
|
+
}
|
|
241
|
+
const out = [];
|
|
242
|
+
const seenIds = new Set();
|
|
243
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
244
|
+
const m = value[i];
|
|
245
|
+
if (m === null || typeof m !== 'object') {
|
|
246
|
+
errors.push(`modules[${i}] must be an object`);
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
const rec = m;
|
|
250
|
+
const id = rec.id;
|
|
251
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
252
|
+
errors.push(`modules[${i}].id must be a non-empty string`);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (seenIds.has(id)) {
|
|
256
|
+
errors.push(`modules[${i}].id "${id}" is a duplicate`);
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
seenIds.add(id);
|
|
260
|
+
const glob = rec.glob;
|
|
261
|
+
if (!Array.isArray(glob) || !glob.every((g) => typeof g === 'string')) {
|
|
262
|
+
errors.push(`modules[${i}].glob must be an array of strings`);
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
let entryGlob;
|
|
266
|
+
if (rec.entryGlob !== undefined) {
|
|
267
|
+
if (!Array.isArray(rec.entryGlob) || !rec.entryGlob.every((g) => typeof g === 'string')) {
|
|
268
|
+
errors.push(`modules[${i}].entryGlob must be an array of strings`);
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
entryGlob = rec.entryGlob;
|
|
272
|
+
}
|
|
273
|
+
const description = typeof rec.description === 'string' ? rec.description : undefined;
|
|
274
|
+
out.push({ id, description, glob: glob, ...(entryGlob ? { entryGlob } : {}) });
|
|
275
|
+
}
|
|
276
|
+
return out;
|
|
277
|
+
}
|
|
278
|
+
function validateTrustBoundaries(value, errors) {
|
|
279
|
+
if (value === undefined)
|
|
280
|
+
return [];
|
|
281
|
+
if (!Array.isArray(value)) {
|
|
282
|
+
errors.push('"trustBoundaries" must be an array');
|
|
283
|
+
return [];
|
|
284
|
+
}
|
|
285
|
+
const out = [];
|
|
286
|
+
const seenIds = new Set();
|
|
287
|
+
const VALID_RULES = new Set(['inbound_only', 'outbound_only', 'requires_review']);
|
|
288
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
289
|
+
const tb = value[i];
|
|
290
|
+
if (tb === null || typeof tb !== 'object') {
|
|
291
|
+
errors.push(`trustBoundaries[${i}] must be an object`);
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
const rec = tb;
|
|
295
|
+
const id = rec.id;
|
|
296
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
297
|
+
errors.push(`trustBoundaries[${i}].id must be a non-empty string`);
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (seenIds.has(id)) {
|
|
301
|
+
errors.push(`trustBoundaries[${i}].id "${id}" is a duplicate`);
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
seenIds.add(id);
|
|
305
|
+
const description = rec.description;
|
|
306
|
+
if (typeof description !== 'string' || description.length === 0) {
|
|
307
|
+
errors.push(`trustBoundaries[${i}].description must be a non-empty string`);
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
const insideGlob = rec.insideGlob;
|
|
311
|
+
if (!Array.isArray(insideGlob) || !insideGlob.every((g) => typeof g === 'string')) {
|
|
312
|
+
errors.push(`trustBoundaries[${i}].insideGlob must be an array of strings`);
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
const edgeRule = rec.edgeRule;
|
|
316
|
+
if (typeof edgeRule !== 'string' || !VALID_RULES.has(edgeRule)) {
|
|
317
|
+
errors.push(`trustBoundaries[${i}].edgeRule must be one of: ${[...VALID_RULES].join(', ')}`);
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
out.push({
|
|
321
|
+
id,
|
|
322
|
+
description,
|
|
323
|
+
insideGlob: insideGlob,
|
|
324
|
+
edgeRule: edgeRule,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
return out;
|
|
328
|
+
}
|
|
329
|
+
function validateEdges(fieldName, value, errors, layers) {
|
|
330
|
+
if (value === undefined)
|
|
331
|
+
return [];
|
|
332
|
+
if (!Array.isArray(value)) {
|
|
333
|
+
errors.push(`"${fieldName}" must be an array`);
|
|
334
|
+
return [];
|
|
335
|
+
}
|
|
336
|
+
const knownLayerIds = new Set(layers.map((l) => l.id));
|
|
337
|
+
const out = [];
|
|
338
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
339
|
+
const e = value[i];
|
|
340
|
+
if (e === null || typeof e !== 'object') {
|
|
341
|
+
errors.push(`${fieldName}[${i}] must be an object`);
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
const rec = e;
|
|
345
|
+
const from = rec.from;
|
|
346
|
+
const to = rec.to;
|
|
347
|
+
if (typeof from !== 'string' || from.length === 0) {
|
|
348
|
+
errors.push(`${fieldName}[${i}].from must be a non-empty string`);
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (typeof to !== 'string' || to.length === 0) {
|
|
352
|
+
errors.push(`${fieldName}[${i}].to must be a non-empty string`);
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (!knownLayerIds.has(from)) {
|
|
356
|
+
errors.push(`${fieldName}[${i}].from "${from}" references unknown layer`);
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (!knownLayerIds.has(to)) {
|
|
360
|
+
errors.push(`${fieldName}[${i}].to "${to}" references unknown layer`);
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
const reason = typeof rec.reason === 'string' ? rec.reason : undefined;
|
|
364
|
+
out.push({ from, to, ...(reason ? { reason } : {}) });
|
|
365
|
+
}
|
|
366
|
+
return out;
|
|
367
|
+
}
|
|
368
|
+
// ── Fingerprinting ───────────────────────────────────────────────────────────
|
|
369
|
+
/**
|
|
370
|
+
* Produce a deterministic fingerprint of the contract contents.
|
|
371
|
+
* Used in replay envelopes so runs can be tied back to a specific contract version.
|
|
372
|
+
*/
|
|
373
|
+
function fingerprintGraph(input) {
|
|
374
|
+
// Canonicalise: stable key order, no insignificant whitespace.
|
|
375
|
+
const canonical = canonicalStringify({
|
|
376
|
+
layers: input.layers,
|
|
377
|
+
modules: input.modules,
|
|
378
|
+
trustBoundaries: input.trustBoundaries,
|
|
379
|
+
allowedEdges: input.allowedEdges,
|
|
380
|
+
forbiddenEdges: input.forbiddenEdges,
|
|
381
|
+
});
|
|
382
|
+
return `sha256:${(0, crypto_1.createHash)('sha256').update(canonical).digest('hex')}`;
|
|
383
|
+
}
|
|
384
|
+
/** JSON.stringify with deterministic key ordering. */
|
|
385
|
+
function canonicalStringify(value) {
|
|
386
|
+
if (value === null)
|
|
387
|
+
return 'null';
|
|
388
|
+
if (typeof value !== 'object')
|
|
389
|
+
return JSON.stringify(value);
|
|
390
|
+
if (Array.isArray(value)) {
|
|
391
|
+
return `[${value.map(canonicalStringify).join(',')}]`;
|
|
392
|
+
}
|
|
393
|
+
const keys = Object.keys(value).sort();
|
|
394
|
+
const parts = keys.map((k) => `${JSON.stringify(k)}:${canonicalStringify(value[k])}`);
|
|
395
|
+
return `{${parts.join(',')}}`;
|
|
396
|
+
}
|
|
397
|
+
//# sourceMappingURL=intent-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-contract.js","sourceRoot":"","sources":["../../../src/governance/intent/intent-contract.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;;;AAwCH,8DAKC;AAgBD,gDA6CC;AAMD,0DAEC;AAhHD,2BAA8C;AAC9C,+BAAqC;AACrC,mCAAoC;AACpC,iDAQwB;AAExB,gFAAgF;AAEnE,QAAA,wBAAwB,GAAG,aAAa,CAAC;AACzC,QAAA,6BAA6B,GAAG,aAAa,gCAAwB,EAAE,CAAC;AAiBrF,gFAAgF;AAEhF;;GAEG;AACH,SAAgB,yBAAyB,CAAC,WAAmB,EAAE,QAAiB;IAC9E,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,IAAA,cAAO,EAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,IAAA,WAAI,EAAC,WAAW,EAAE,WAAW,EAAE,gCAAwB,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,kBAAkB,CAChC,WAAmB,EACnB,QAAiB;IAEjB,MAAM,YAAY,GAAG,yBAAyB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAEtE,IAAI,CAAC,IAAA,eAAU,EAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,KAAK;YACb,KAAK,EAAE,iCAAkB;YACzB,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAED,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,IAAA,iBAAY,EAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,iCAAkB;YACzB,MAAM,EAAE,CAAC,mCAAmC,GAAG,EAAE,CAAC;YAClD,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,iCAAkB;YACzB,MAAM,EAAE,CAAC,oCAAoC,GAAG,EAAE,CAAC;YACnD,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAED,OAAO,qBAAqB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,SAAgB,uBAAuB,CAAC,GAAY;IAClD,OAAO,qBAAqB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;AAChD,CAAC;AAED,gFAAgF;AAEhF,SAAS,qBAAqB,CAAC,GAAY,EAAE,UAAkB;IAC7D,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,iCAAkB;YACzB,MAAM,EAAE,CAAC,uCAAuC,CAAC;YACjD,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,GAA8B,CAAC;IAE3C,iBAAiB;IACjB,MAAM,aAAa,GAAG,GAAG,CAAC,aAAa,CAAC;IACxC,IAAI,aAAa,KAAK,0CAA2B,EAAE,CAAC;QAClD,MAAM,CAAC,IAAI,CACT,uCAAuC,0CAA2B,SAAS,IAAI,CAAC,SAAS,CACvF,aAAa,CACd,EAAE,CACJ,CAAC;IACJ,CAAC;IAED,iEAAiE;IACjE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;QAC3B,eAAe;QACf,QAAQ;QACR,SAAS;QACT,iBAAiB;QACjB,cAAc;QACd,gBAAgB;KACjB,CAAC,CAAC;IACH,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACrD,MAAM,eAAe,GAAG,uBAAuB,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAC7E,MAAM,YAAY,GAAG,aAAa,CAAC,cAAc,EAAE,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACrF,MAAM,cAAc,GAAG,aAAa,CAAC,gBAAgB,EAAE,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAE3F,uCAAuC;IACvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,QAAQ,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,EAAE,4DAA4D,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,iCAAkB;YACzB,MAAM;YACN,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAgB;QACzB,aAAa,EAAE,0CAA2B;QAC1C,MAAM;QACN,OAAO;QACP,eAAe;QACf,YAAY;QACZ,cAAc;QACd,WAAW,EAAE,gBAAgB,CAAC;YAC5B,MAAM;YACN,OAAO;YACP,eAAe;YACf,YAAY;YACZ,cAAc;SACf,CAAC;KACH,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,IAAI;QACZ,KAAK;QACL,MAAM,EAAE,EAAE;QACV,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAc,EAAE,MAAgB;IACtD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC;YAC9C,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,KAAgC,CAAC;QAC7C,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;QAClB,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,iCAAiC,CAAC,CAAC;YAC1D,SAAS;QACX,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;YACtD,SAAS;QACX,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;YACtE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,oCAAoC,CAAC,CAAC;YAC7D,SAAS;QACX,CAAC;QACD,MAAM,WAAW,GAAG,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;QACtF,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,IAAgB,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,eAAe,CAAC,KAAc,EAAE,MAAgB;IACvD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC1C,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,qBAAqB,CAAC,CAAC;YAC/C,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,CAA4B,CAAC;QACzC,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;QAClB,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,iCAAiC,CAAC,CAAC;YAC3D,SAAS;QACX,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;YACvD,SAAS;QACX,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;YACtE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,oCAAoC,CAAC,CAAC;YAC9D,SAAS;QACX,CAAC;QACD,IAAI,SAA+B,CAAC;QACpC,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;gBACxF,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,yCAAyC,CAAC,CAAC;gBACnE,SAAS;YACX,CAAC;YACD,SAAS,GAAG,GAAG,CAAC,SAAqB,CAAC;QACxC,CAAC;QACD,MAAM,WAAW,GAAG,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;QACtF,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,IAAgB,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAc,EAAE,MAAgB;IAC/D,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QAClD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAA0B,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAClF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,EAAE,KAAK,IAAI,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,CAAC;YACvD,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,EAA6B,CAAC;QAC1C,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;QAClB,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,iCAAiC,CAAC,CAAC;YACnE,SAAS;QACX,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;YAC/D,SAAS;QACX,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;QACpC,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChE,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,0CAA0C,CAAC,CAAC;YAC5E,SAAS;QACX,CAAC;QACD,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;YAClF,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,0CAA0C,CAAC,CAAC;YAC5E,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;QAC9B,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/D,MAAM,CAAC,IAAI,CACT,mBAAmB,CAAC,8BAA8B,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAChF,CAAC;YACF,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC;YACP,EAAE;YACF,WAAW;YACX,UAAU,EAAE,UAAsB;YAClC,QAAQ,EAAE,QAA2C;SACtD,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,aAAa,CACpB,SAA4C,EAC5C,KAAc,EACd,MAAgB,EAChB,MAAqB;IAErB,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,oBAAoB,CAAC,CAAC;QAC/C,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvD,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,CAAC,qBAAqB,CAAC,CAAC;YACpD,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,CAA4B,CAAC;QACzC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;QAClB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,CAAC,mCAAmC,CAAC,CAAC;YAClE,SAAS;QACX,CAAC;QACD,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,CAAC,iCAAiC,CAAC,CAAC;YAChE,SAAS;QACX,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,CAAC,WAAW,IAAI,4BAA4B,CAAC,CAAC;YAC1E,SAAS;QACX,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,CAAC,SAAS,EAAE,4BAA4B,CAAC,CAAC;YACtE,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QACvE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAEhF;;;GAGG;AACH,SAAS,gBAAgB,CAAC,KAMzB;IACC,+DAA+D;IAC/D,MAAM,SAAS,GAAG,kBAAkB,CAAC;QACnC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,cAAc,EAAE,KAAK,CAAC,cAAc;KACrC,CAAC,CAAC;IACH,OAAO,UAAU,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAC1E,CAAC;AAED,sDAAsD;AACtD,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACxD,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAE,KAAiC,CAAC,CAAC,CAAC,CAAC,EAAE,CAC3F,CAAC;IACF,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent Graph — typed model for architectural intent.
|
|
3
|
+
*
|
|
4
|
+
* The Intent Graph is the foundational data structure for Intent-Aware Governance
|
|
5
|
+
* Intelligence. It represents the *intended* architecture of a codebase as a
|
|
6
|
+
* declarative, machine-verifiable artifact, distinct from:
|
|
7
|
+
*
|
|
8
|
+
* - Plan contracts (`expectedFiles`) — per-change file expectations
|
|
9
|
+
* - Change contracts — diff-vs-plan enforcement
|
|
10
|
+
* - Intent engine (`runIntentEngine`) — NL prompt → code coverage matcher
|
|
11
|
+
* - Structural rules — code-pattern violations (SR001 ...)
|
|
12
|
+
*
|
|
13
|
+
* What the Intent Graph adds: a stable, declarative model of *which parts of the
|
|
14
|
+
* codebase are allowed to depend on which other parts*. Layers, modules, trust
|
|
15
|
+
* boundaries, and directional dependency rules are first-class nodes/edges.
|
|
16
|
+
*
|
|
17
|
+
* Phase 1 scope (this file):
|
|
18
|
+
* - Typed primitives only.
|
|
19
|
+
* - No runtime computation, no I/O, no validation.
|
|
20
|
+
* - Used as the shared vocabulary across intent-contract.ts (loading),
|
|
21
|
+
* drift-detector.ts (analysis), and verify.ts (reporting).
|
|
22
|
+
*
|
|
23
|
+
* Intelligence classification: DETERMINISTIC (pure types).
|
|
24
|
+
*/
|
|
25
|
+
/** Current schema version. Bumped only with a breaking-change migration plan. */
|
|
26
|
+
export declare const INTENT_GRAPH_SCHEMA_VERSION: 1;
|
|
27
|
+
/**
|
|
28
|
+
* A named architectural layer. Layers are the primary organising concept:
|
|
29
|
+
* "controller", "service", "persistence", "infrastructure", etc.
|
|
30
|
+
*
|
|
31
|
+
* Layer membership is determined by `glob` patterns matched against
|
|
32
|
+
* project-relative file paths. Order across the contract's `layers` array
|
|
33
|
+
* matters: when a file matches multiple layers, the first wins. This makes
|
|
34
|
+
* the classification deterministic and human-debuggable.
|
|
35
|
+
*/
|
|
36
|
+
export interface IntentLayer {
|
|
37
|
+
/** Stable identifier referenced by edges. Lowercase, snake_case recommended. */
|
|
38
|
+
id: string;
|
|
39
|
+
/** Optional human description shown in drift reports. */
|
|
40
|
+
description?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Glob patterns matched against project-relative paths.
|
|
43
|
+
* Syntax: `**`, `*`, `?` (see glob-match.ts).
|
|
44
|
+
*/
|
|
45
|
+
glob: string[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A logical module (a bounded subsystem). Modules cut orthogonally to layers:
|
|
49
|
+
* a "billing" module may span controller, service, and persistence layers.
|
|
50
|
+
*
|
|
51
|
+
* Optional `entryGlob` declares the public surface — files outside the module
|
|
52
|
+
* may only reach the module by importing from one of these entry files.
|
|
53
|
+
* (Enforcement of the entry rule is opt-in via the contract `enforceModuleEntries`.)
|
|
54
|
+
*/
|
|
55
|
+
export interface IntentModule {
|
|
56
|
+
id: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
glob: string[];
|
|
59
|
+
/** When set, only these files may be imported from outside the module. */
|
|
60
|
+
entryGlob?: string[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A trust boundary describes a *directional flow rule* across a security
|
|
64
|
+
* or organisational seam (e.g. tenant isolation, encryption zone, third-party
|
|
65
|
+
* API surface).
|
|
66
|
+
*
|
|
67
|
+
* Phase 1: trust boundary detection emits ADVISORY findings only. Promotion to
|
|
68
|
+
* blocking requires explicit per-boundary opt-in via a future schema field.
|
|
69
|
+
*/
|
|
70
|
+
export interface IntentTrustBoundary {
|
|
71
|
+
id: string;
|
|
72
|
+
description: string;
|
|
73
|
+
/** Files considered "inside" the boundary. */
|
|
74
|
+
insideGlob: string[];
|
|
75
|
+
/**
|
|
76
|
+
* Flow rule:
|
|
77
|
+
* - `inbound_only` — external code may call in; internal code must not call out.
|
|
78
|
+
* - `outbound_only` — internal code may call out; external code must not call in.
|
|
79
|
+
* - `requires_review` — any cross-boundary edge surfaces an advisory for review.
|
|
80
|
+
*/
|
|
81
|
+
edgeRule: 'inbound_only' | 'outbound_only' | 'requires_review';
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* A directed allowed-or-forbidden dependency edge between two layers.
|
|
85
|
+
*
|
|
86
|
+
* The graph uses an *explicit-allow + explicit-forbid* model:
|
|
87
|
+
* - If `allowedEdges` is non-empty, ONLY edges in that list are permitted.
|
|
88
|
+
* - `forbiddenEdges` always blocks regardless of `allowedEdges`.
|
|
89
|
+
*
|
|
90
|
+
* When both lists are empty, the contract is in **observation mode**: drift
|
|
91
|
+
* detection runs but produces no violations. This makes the contract safe to
|
|
92
|
+
* adopt incrementally.
|
|
93
|
+
*/
|
|
94
|
+
export interface IntentEdge {
|
|
95
|
+
from: string;
|
|
96
|
+
to: string;
|
|
97
|
+
reason?: string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The complete typed graph. This is the in-memory form produced by
|
|
101
|
+
* `loadIntentContract` and consumed by `runDriftDetection`.
|
|
102
|
+
*
|
|
103
|
+
* The graph is **derived data** — it is built from a declarative contract
|
|
104
|
+
* artifact (intent.json) by the loader. Callers do not construct it directly.
|
|
105
|
+
*/
|
|
106
|
+
export interface IntentGraph {
|
|
107
|
+
schemaVersion: typeof INTENT_GRAPH_SCHEMA_VERSION;
|
|
108
|
+
layers: IntentLayer[];
|
|
109
|
+
modules: IntentModule[];
|
|
110
|
+
trustBoundaries: IntentTrustBoundary[];
|
|
111
|
+
allowedEdges: IntentEdge[];
|
|
112
|
+
forbiddenEdges: IntentEdge[];
|
|
113
|
+
/**
|
|
114
|
+
* Stable fingerprint of the graph contents (SHA-256 over canonicalised JSON).
|
|
115
|
+
* Used in replay envelopes so a verify run records *which* intent graph it ran against.
|
|
116
|
+
*/
|
|
117
|
+
fingerprint: string;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* A canonical empty graph. Used when no intent contract is configured — drift
|
|
121
|
+
* detection short-circuits to "no violations" deterministically.
|
|
122
|
+
*/
|
|
123
|
+
export declare const EMPTY_INTENT_GRAPH: IntentGraph;
|
|
124
|
+
/**
|
|
125
|
+
* Return true when the graph defines *no* layers/modules/boundaries/edges.
|
|
126
|
+
* Drift detection skips entirely when this is true.
|
|
127
|
+
*/
|
|
128
|
+
export declare function isEmptyIntentGraph(graph: IntentGraph): boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Returns true if the graph has at least one rule that can produce a drift
|
|
131
|
+
* finding. A graph with only layers but no edges is "in observation mode" —
|
|
132
|
+
* it can classify files but not flag violations.
|
|
133
|
+
*/
|
|
134
|
+
export declare function intentGraphHasEnforcement(graph: IntentGraph): boolean;
|
|
135
|
+
//# sourceMappingURL=intent-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-graph.d.ts","sourceRoot":"","sources":["../../../src/governance/intent/intent-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,iFAAiF;AACjF,eAAO,MAAM,2BAA2B,EAAG,CAAU,CAAC;AAItD;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,EAAE,EAAE,MAAM,CAAC;IACX,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAID;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAID;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,EAAE,cAAc,GAAG,eAAe,GAAG,iBAAiB,CAAC;CAChE;AAID;;;;;;;;;;GAUG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,OAAO,2BAA2B,CAAC;IAClD,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,eAAe,EAAE,mBAAmB,EAAE,CAAC;IACvC,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,cAAc,EAAE,UAAU,EAAE,CAAC;IAC7B;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAID;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAQhB,CAAC;AAIlB;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAQ9D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAErE"}
|