@fourier-labs/harbour-contracts 0.4.0 → 0.6.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.
Files changed (91) hide show
  1. package/dist/gen-ts/ai-callsite-inventory.d.ts +49 -0
  2. package/dist/gen-ts/ai-gateway-key-lookup.d.ts +20 -0
  3. package/dist/gen-ts/ai-gateway-key-token.d.ts +4 -0
  4. package/dist/gen-ts/ai-gateway-key-token.js +6 -0
  5. package/dist/gen-ts/ai-governance-decision.d.ts +74 -0
  6. package/dist/gen-ts/ai-policy-snapshot.d.ts +165 -0
  7. package/dist/gen-ts/ai-runtime-contract.d.ts +27 -0
  8. package/dist/gen-ts/ai-trace-event.d.ts +68 -0
  9. package/dist/gen-ts/ai-transform-event.d.ts +47 -0
  10. package/dist/gen-ts/ai-transform-result.d.ts +32 -0
  11. package/dist/gen-ts/ai-verification-evidence.d.ts +49 -0
  12. package/dist/gen-ts/data-dependency.d.ts +42 -0
  13. package/dist/gen-ts/data-grant.d.ts +58 -0
  14. package/dist/gen-ts/data-grant.js +12 -0
  15. package/dist/gen-ts/data-source.d.ts +74 -0
  16. package/dist/{deploy-request.d.ts → gen-ts/deploy-request.d.ts} +30 -0
  17. package/dist/gen-ts/deployment-source.js +3 -0
  18. package/dist/gen-ts/deployment-status-failure.js +3 -0
  19. package/dist/gen-ts/deployment-status-request.js +3 -0
  20. package/dist/gen-ts/deployment-status-response.js +3 -0
  21. package/dist/gen-ts/env-bindings.js +3 -0
  22. package/dist/{error-category-registry.d.ts → gen-ts/error-category-registry.d.ts} +5 -0
  23. package/dist/{error-category-registry.js → gen-ts/error-category-registry.js} +10 -0
  24. package/dist/gen-ts/error-category.js +3 -0
  25. package/dist/gen-ts/error-envelope.js +3 -0
  26. package/dist/{index.d.ts → gen-ts/index.d.ts} +15 -0
  27. package/dist/{index.js → gen-ts/index.js} +15 -0
  28. package/dist/gen-ts/kvs-routing-entry.d.ts +27 -0
  29. package/dist/gen-ts/kvs-routing-entry.js +3 -0
  30. package/dist/gen-ts/promotion-request.d.ts +40 -0
  31. package/dist/gen-ts/promotion-request.js +3 -0
  32. package/dist/gen-ts/promotion-response.js +3 -0
  33. package/dist/gen-ts/secret-reference.d.ts +36 -0
  34. package/dist/gen-ts/secret-reference.js +3 -0
  35. package/dist/gen-ts/transform-report.d.ts +102 -0
  36. package/dist/gen-ts/transform-report.js +3 -0
  37. package/dist/gen-ts/version-state.js +3 -0
  38. package/dist/resolver/index.d.ts +256 -0
  39. package/dist/resolver/index.js +679 -0
  40. package/package.json +14 -4
  41. package/schema/ai-callsite-inventory.schema.json +138 -0
  42. package/schema/ai-gateway-key-lookup.schema.json +53 -0
  43. package/schema/ai-governance-decision.schema.json +105 -0
  44. package/schema/ai-policy-snapshot.schema.json +340 -0
  45. package/schema/ai-runtime-contract.schema.json +85 -0
  46. package/schema/ai-trace-event.schema.json +178 -0
  47. package/schema/ai-transform-event.schema.json +72 -0
  48. package/schema/ai-transform-result.schema.json +46 -0
  49. package/schema/ai-verification-evidence.schema.json +57 -0
  50. package/schema/data-dependency.schema.json +89 -0
  51. package/schema/data-grant.schema.json +107 -0
  52. package/schema/data-source.schema.json +151 -0
  53. package/schema/deploy-request.schema.json +60 -0
  54. package/schema/error-category.enum.json +6 -1
  55. package/schema/kvs-routing-entry.schema.json +28 -8
  56. package/schema/promotion-request.schema.json +38 -0
  57. package/schema/secret-reference.schema.json +70 -0
  58. package/schema/transform-report.schema.json +204 -0
  59. package/dist/kvs-routing-entry.d.ts +0 -13
  60. package/dist/promotion-request.d.ts +0 -17
  61. /package/dist/{api-error-response.js → gen-ts/ai-callsite-inventory.js} +0 -0
  62. /package/dist/{artifact-contract.js → gen-ts/ai-gateway-key-lookup.js} +0 -0
  63. /package/dist/{deploy-request.js → gen-ts/ai-governance-decision.js} +0 -0
  64. /package/dist/{deploy-response.js → gen-ts/ai-policy-snapshot.js} +0 -0
  65. /package/dist/{deployment-environment.js → gen-ts/ai-runtime-contract.js} +0 -0
  66. /package/dist/{deployment-source.js → gen-ts/ai-trace-event.js} +0 -0
  67. /package/dist/{deployment-status-failure.js → gen-ts/ai-transform-event.js} +0 -0
  68. /package/dist/{deployment-status-request.js → gen-ts/ai-transform-result.js} +0 -0
  69. /package/dist/{deployment-status-response.js → gen-ts/ai-verification-evidence.js} +0 -0
  70. /package/dist/{api-error-response.d.ts → gen-ts/api-error-response.d.ts} +0 -0
  71. /package/dist/{env-bindings.js → gen-ts/api-error-response.js} +0 -0
  72. /package/dist/{artifact-contract.d.ts → gen-ts/artifact-contract.d.ts} +0 -0
  73. /package/dist/{error-category.js → gen-ts/artifact-contract.js} +0 -0
  74. /package/dist/{error-envelope.js → gen-ts/data-dependency.js} +0 -0
  75. /package/dist/{kvs-routing-entry.js → gen-ts/data-source.js} +0 -0
  76. /package/dist/{promotion-request.js → gen-ts/deploy-request.js} +0 -0
  77. /package/dist/{deploy-response.d.ts → gen-ts/deploy-response.d.ts} +0 -0
  78. /package/dist/{promotion-response.js → gen-ts/deploy-response.js} +0 -0
  79. /package/dist/{deployment-environment.d.ts → gen-ts/deployment-environment.d.ts} +0 -0
  80. /package/dist/{version-state.js → gen-ts/deployment-environment.js} +0 -0
  81. /package/dist/{deployment-source.d.ts → gen-ts/deployment-source.d.ts} +0 -0
  82. /package/dist/{deployment-status-failure.d.ts → gen-ts/deployment-status-failure.d.ts} +0 -0
  83. /package/dist/{deployment-status-request.d.ts → gen-ts/deployment-status-request.d.ts} +0 -0
  84. /package/dist/{deployment-status-response.d.ts → gen-ts/deployment-status-response.d.ts} +0 -0
  85. /package/dist/{env-bindings.d.ts → gen-ts/env-bindings.d.ts} +0 -0
  86. /package/dist/{error-category.d.ts → gen-ts/error-category.d.ts} +0 -0
  87. /package/dist/{error-envelope.d.ts → gen-ts/error-envelope.d.ts} +0 -0
  88. /package/dist/{promotion-response.d.ts → gen-ts/promotion-response.d.ts} +0 -0
  89. /package/dist/{version-state-machine.d.ts → gen-ts/version-state-machine.d.ts} +0 -0
  90. /package/dist/{version-state-machine.js → gen-ts/version-state-machine.js} +0 -0
  91. /package/dist/{version-state.d.ts → gen-ts/version-state.d.ts} +0 -0
@@ -0,0 +1,49 @@
1
+ export type AiInventoryIdentifier = string;
2
+ export type AiInventoryDigest = string;
3
+ /**
4
+ * Immutable, sanitized AI call-site discovery for one exact Harbour deployment version. Inventory records detection only; planning, transformation, and verification outcomes are separate append-only records.
5
+ */
6
+ export interface AiCallsiteInventory {
7
+ schema: 'harbour.ai-callsite-inventory/1.0';
8
+ tenantId: AiInventoryIdentifier;
9
+ appId: AiInventoryIdentifier;
10
+ environment: AiInventoryIdentifier;
11
+ versionId: string;
12
+ sourceRevision: string;
13
+ analyzerVersion: string;
14
+ coverage: 'complete_for_supported_sdks' | 'partial';
15
+ /**
16
+ * Required and never defaulted. Unavailable security evidence is not represented as a clean scan.
17
+ */
18
+ scanStatus: 'completed' | 'cybersecurity_scan_unavailable';
19
+ /**
20
+ * Canonical order is ascending by fingerprint, then path, then line. Producers MUST serialize this order before digesting or publishing the inventory.
21
+ *
22
+ * @maxItems 1000
23
+ */
24
+ callsites: AiInventoryCallsite[];
25
+ }
26
+ export interface AiInventoryCallsite {
27
+ fingerprint: AiInventoryDigest;
28
+ path: string;
29
+ sourceFileSha256: AiInventoryDigest;
30
+ line: number;
31
+ language: 'javascript' | 'typescript' | 'python' | 'go' | 'unknown';
32
+ sdk: 'openai' | 'openai-compatible' | 'anthropic' | 'google-genai' | 'mistral' | 'bedrock' | 'cohere' | 'ollama' | 'legacy-gemini' | 'direct-provider-rest' | 'unknown';
33
+ method: string;
34
+ requestedModel?: string;
35
+ strategy: 'deployment_injection' | 'deterministic_adapter' | 'unsupported';
36
+ status: 'detected';
37
+ /**
38
+ * @maxItems 64
39
+ */
40
+ securityFindingIds: string[];
41
+ evidence: AiInventoryEvidence;
42
+ }
43
+ export interface AiInventoryEvidence {
44
+ fingerprint: AiInventoryDigest;
45
+ /**
46
+ * Sanitized single-line evidence; never raw source or a prompt.
47
+ */
48
+ excerpt: string;
49
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Value-free Gateway authentication metadata for one version-scoped Harbour key.
3
+ */
4
+ export type AiGatewayKeyLookup = {
5
+ schema: 'harbour.ai-gateway-key-lookup/1.0';
6
+ keyId: string;
7
+ tenantId: AiGatewayKeyIdentifier;
8
+ appId: AiGatewayKeyIdentifier;
9
+ environment: AiGatewayKeyIdentifier;
10
+ versionId: string;
11
+ tokenPrefix: 'hbr_live_' | 'hbr_test_';
12
+ status: 'PENDING' | 'ACTIVE' | 'REVOKED';
13
+ keyMac?: string;
14
+ createdAt: string;
15
+ activatedAt?: string;
16
+ expiresAt?: string;
17
+ overlapExpiresAt?: string;
18
+ revokedAt?: string;
19
+ };
20
+ export type AiGatewayKeyIdentifier = string;
@@ -0,0 +1,4 @@
1
+ export declare const AiGatewayKeyProductionPrefix: "hbr_live_";
2
+ export declare const AiGatewayKeyNonProductionPrefix: "hbr_test_";
3
+ export declare const AiGatewayKeyTokenPatternSource: "^hbr_(live|test)_([0-9a-f]{32})\\.([A-Za-z0-9_-]{43})$";
4
+ export declare const AiGatewayKeyTokenPattern: RegExp;
@@ -0,0 +1,6 @@
1
+ /* eslint-disable */
2
+ // Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
3
+ export const AiGatewayKeyProductionPrefix = "hbr_live_";
4
+ export const AiGatewayKeyNonProductionPrefix = "hbr_test_";
5
+ export const AiGatewayKeyTokenPatternSource = "^hbr_(live|test)_([0-9a-f]{32})\\.([A-Za-z0-9_-]{43})$";
6
+ export const AiGatewayKeyTokenPattern = new RegExp(AiGatewayKeyTokenPatternSource);
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Digest-bound PLAN or VERIFY decision returned to the deployment control plane.
3
+ */
4
+ export type AiGovernanceDecision = {
5
+ schema: 'harbour.ai-governance-decision/1.0';
6
+ phase: 'PLAN' | 'VERIFY';
7
+ tenantId: AiDecisionIdentifier;
8
+ appId: AiDecisionIdentifier;
9
+ environment: AiDecisionIdentifier;
10
+ versionId: string;
11
+ sourceRevision: string;
12
+ decision: 'PASS' | 'BLOCKED';
13
+ interceptionPath: 'NO_AI_CALLS' | 'DEPLOYMENT_INJECTION' | 'DETERMINISTIC_ADAPTER' | 'BLOCKED';
14
+ /**
15
+ * @maxItems 64
16
+ */
17
+ reasonCodes: AiDecisionIdentifier[];
18
+ /**
19
+ * @maxItems 1000
20
+ */
21
+ uncoveredCallsiteFingerprints: AiDecisionDigest[];
22
+ inventoryDigest: AiDecisionDigest;
23
+ policyDigest: AiDecisionDigest;
24
+ runtimeContractDigest?: AiDecisionDigest;
25
+ /**
26
+ * @maxItems 1000
27
+ */
28
+ interceptionPlan: AiInterceptionPlanEntry[];
29
+ interceptionPlanDigest: AiDecisionDigest;
30
+ evidenceDigest?: AiDecisionDigest;
31
+ runtimeContract?: AiDecisionRuntimeContract;
32
+ decidedAt: string;
33
+ };
34
+ export type AiDecisionIdentifier = string;
35
+ export type AiDecisionDigest = string;
36
+ export type AiInterceptionPlanEntry = {
37
+ callSiteFingerprint: AiDecisionDigest;
38
+ sourcePath: string;
39
+ expectedSourceFileSha256: AiDecisionDigest;
40
+ strategy: 'deployment_injection' | 'deterministic_adapter';
41
+ /**
42
+ * @minItems 1
43
+ * @maxItems 32
44
+ */
45
+ allowedSyntaxKinds: AiDecisionIdentifier[];
46
+ configurationMappingId?: AiDecisionIdentifier;
47
+ configurationMappingVersion?: string;
48
+ transformId?: AiDecisionIdentifier;
49
+ transformVersion?: string;
50
+ runtimeShimName?: string;
51
+ runtimeShimVersion?: string;
52
+ runtimeShimDigest?: AiDecisionDigest;
53
+ };
54
+ export interface AiDecisionRuntimeContract {
55
+ schema: 'harbour.ai-runtime-contract/1.0';
56
+ tenantId: AiDecisionIdentifier;
57
+ appId: AiDecisionIdentifier;
58
+ environment: AiDecisionIdentifier;
59
+ versionId: string;
60
+ sourceRevision: string;
61
+ mode: 'observe' | 'enforce';
62
+ gatewayBaseUrl: string;
63
+ gatewayKeySecretRef: string;
64
+ modelAliases: {
65
+ generation?: string;
66
+ embeddings?: string;
67
+ };
68
+ policyDigest: AiDecisionDigest;
69
+ /**
70
+ * @minItems 1
71
+ * @maxItems 2
72
+ */
73
+ requiredStrategies: ('deployment_injection' | 'deterministic_adapter')[];
74
+ }
@@ -0,0 +1,165 @@
1
+ export type AiPolicyScope = {
2
+ level: 'tenant' | 'application_environment';
3
+ tenantId: AiPolicyIdentifier;
4
+ appId?: AiPolicyIdentifier;
5
+ environment?: AiPolicyIdentifier;
6
+ };
7
+ export type AiPolicyIdentifier = string;
8
+ export type AiPolicyDigest = string;
9
+ export type AiPolicyGuardrailRule = {
10
+ ruleId: AiPolicyIdentifier;
11
+ detectorId: AiPolicyIdentifier;
12
+ detectorVersion: string;
13
+ phase: 'input' | 'output';
14
+ action: 'ALLOW' | 'OBSERVE' | 'REDACT' | 'BLOCK';
15
+ parameters?: AiPolicyGuardrailParameters;
16
+ };
17
+ /**
18
+ * Bounded, closed JSON Schema subset carried by an output.json_schema guardrail. Every node is a closed object over an enumerated keyword set; object nodes must state additionalProperties: false, so the validated output shape is closed too. Size is bounded per node (maxProperties/maxLength/maxItems); the consuming validator additionally enforces an overall byte budget at policy load.
19
+ */
20
+ export type AiPolicyEmbeddedJsonSchema = {
21
+ type: 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
22
+ description?: string;
23
+ properties?: {
24
+ [k: string]: AiPolicyEmbeddedJsonSchema;
25
+ };
26
+ /**
27
+ * @maxItems 64
28
+ */
29
+ required?: string[];
30
+ additionalProperties?: false;
31
+ items?: AiPolicyEmbeddedJsonSchema;
32
+ /**
33
+ * @minItems 1
34
+ * @maxItems 64
35
+ */
36
+ enum?: (string | number | boolean | null)[];
37
+ minimum?: number;
38
+ maximum?: number;
39
+ minLength?: number;
40
+ maxLength?: number;
41
+ minItems?: number;
42
+ maxItems?: number;
43
+ };
44
+ /**
45
+ * Immutable, content-addressed AI policy snapshot consumed by the Harbour AI Gateway. Provider credentials are represented only by Secrets Manager references.
46
+ */
47
+ export interface AiPolicySnapshot {
48
+ schema: 'harbour.ai-policy-snapshot/1.0';
49
+ scope: AiPolicyScope;
50
+ revision: number;
51
+ publishedAt: string;
52
+ contentDigest: AiPolicyDigest;
53
+ baselineDigest: AiPolicyDigest;
54
+ classificationMinimum?: AiPolicyClassificationMinimum;
55
+ /**
56
+ * @maxItems 64
57
+ */
58
+ providers: AiPolicyProvider[];
59
+ /**
60
+ * @maxItems 512
61
+ */
62
+ models: AiPolicyModel[];
63
+ /**
64
+ * @maxItems 256
65
+ */
66
+ routes: AiPolicyRoute[];
67
+ /**
68
+ * @maxItems 256
69
+ */
70
+ policies: AiPolicyRuleSet[];
71
+ /**
72
+ * @maxItems 128
73
+ */
74
+ limits: AiPolicyLimit[];
75
+ retention: AiPolicyRetention;
76
+ }
77
+ export interface AiPolicyClassificationMinimum {
78
+ classification: 'Green' | 'Yellow' | 'Orange' | 'Red';
79
+ mappingDigest: AiPolicyDigest;
80
+ }
81
+ export interface AiPolicyProvider {
82
+ id: AiPolicyIdentifier;
83
+ provider: 'openai' | 'anthropic' | 'gemini' | 'openrouter';
84
+ baseUrl?: string;
85
+ credentialSecretRef: string;
86
+ enabled: boolean;
87
+ }
88
+ export interface AiPolicyModel {
89
+ id: AiPolicyIdentifier;
90
+ providerId: AiPolicyIdentifier;
91
+ providerModel: string;
92
+ /**
93
+ * @minItems 1
94
+ * @maxItems 2
95
+ */
96
+ capabilities: ('generation' | 'embeddings')[];
97
+ approved: boolean;
98
+ pricing: AiPolicyPricing;
99
+ }
100
+ export interface AiPolicyPricing {
101
+ revision: AiPolicyIdentifier;
102
+ inputMicroUsdPerMillion: number;
103
+ outputMicroUsdPerMillion: number;
104
+ }
105
+ export interface AiPolicyRoute {
106
+ alias: AiPolicyIdentifier;
107
+ version: number;
108
+ capability: 'generation' | 'embeddings';
109
+ /**
110
+ * @minItems 1
111
+ * @maxItems 16
112
+ */
113
+ targets: AiPolicyRouteTarget[];
114
+ retryCount: number;
115
+ timeoutMs: number;
116
+ }
117
+ export interface AiPolicyRouteTarget {
118
+ modelId: AiPolicyIdentifier;
119
+ priority: number;
120
+ weight: number;
121
+ }
122
+ export interface AiPolicyRuleSet {
123
+ name: AiPolicyIdentifier;
124
+ version: number;
125
+ maxRequestBytes: number;
126
+ maxInputTokens: number;
127
+ maxOutputTokens: number;
128
+ bufferedDelivery: boolean;
129
+ permittedRequestFields: AiPolicyPermittedRequestFields;
130
+ /**
131
+ * @maxItems 128
132
+ */
133
+ guardrails: AiPolicyGuardrailRule[];
134
+ }
135
+ export interface AiPolicyPermittedRequestFields {
136
+ temperature: boolean;
137
+ maxOutputTokens: boolean;
138
+ responseFormat: boolean;
139
+ tools: boolean;
140
+ }
141
+ export interface AiPolicyGuardrailParameters {
142
+ /**
143
+ * @minItems 1
144
+ * @maxItems 64
145
+ */
146
+ allowedTools?: string[];
147
+ jsonSchema?: AiPolicyEmbeddedJsonSchema;
148
+ jsonSchemaRef?: AiPolicyDigest;
149
+ }
150
+ export interface AiPolicyLimit {
151
+ name: AiPolicyIdentifier;
152
+ enabled: boolean;
153
+ scope: 'tenant' | 'application';
154
+ requestsPerMinute: number;
155
+ tokensPerMinute: number;
156
+ monthlyBudgetMicroUsd: number;
157
+ }
158
+ export interface AiPolicyRetention {
159
+ captureMode: 'OFF' | 'BEST_EFFORT' | 'REQUIRED';
160
+ retentionDays: number;
161
+ /**
162
+ * @maxItems 16
163
+ */
164
+ revealRoles: AiPolicyIdentifier[];
165
+ }
@@ -0,0 +1,27 @@
1
+ export type AiRuntimeIdentifier = string;
2
+ export type AiRuntimeModelAlias = string;
3
+ export type AiRuntimeDigest = string;
4
+ /**
5
+ * Immutable deployment runtime contract derived by an AI Governance PLAN decision. Contains only scoped configuration and a Secrets Manager reference, never key plaintext.
6
+ */
7
+ export interface AiRuntimeContract {
8
+ schema: 'harbour.ai-runtime-contract/1.0';
9
+ tenantId: AiRuntimeIdentifier;
10
+ appId: AiRuntimeIdentifier;
11
+ environment: AiRuntimeIdentifier;
12
+ versionId: string;
13
+ sourceRevision: string;
14
+ mode: 'observe' | 'enforce';
15
+ gatewayBaseUrl: string;
16
+ gatewayKeySecretRef: string;
17
+ modelAliases: {
18
+ generation?: AiRuntimeModelAlias;
19
+ embeddings?: AiRuntimeModelAlias;
20
+ };
21
+ policyDigest: AiRuntimeDigest;
22
+ /**
23
+ * @minItems 1
24
+ * @maxItems 2
25
+ */
26
+ requiredStrategies: ('deployment_injection' | 'deterministic_adapter')[];
27
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Value-free asynchronous AI Gateway trace metadata. Raw prompts and responses never enter the queue; captured content is referenced only after successful encrypted storage.
3
+ */
4
+ export type AiTraceEvent = {
5
+ schema: 'harbour.ai-trace-event/1.0';
6
+ traceId: string;
7
+ requestId: string;
8
+ tenantId: AiTraceIdentifier;
9
+ appId: AiTraceIdentifier;
10
+ environment: AiTraceIdentifier;
11
+ versionId: string;
12
+ callsiteFingerprint?: AiTraceDigest;
13
+ policyDigest: AiTraceDigest;
14
+ routeRevision?: string;
15
+ requestedModel?: string;
16
+ governedModelAlias?: string;
17
+ provider?: 'openai' | 'anthropic' | 'gemini' | 'openrouter';
18
+ providerModel?: string;
19
+ outcome: 'succeeded' | 'blocked' | 'failed' | 'cancelled';
20
+ usage?: AiTraceUsage;
21
+ priceRevision?: AiTraceIdentifier;
22
+ costMicroUsd: number;
23
+ latencyMs: number;
24
+ retryCount: number;
25
+ fallbackUsed: boolean;
26
+ reservationId?: string;
27
+ /**
28
+ * @minItems 0
29
+ * @maxItems 32
30
+ */
31
+ attempts: AiTraceAttempt[];
32
+ /**
33
+ * @maxItems 128
34
+ */
35
+ guardrailResults: AiTraceGuardrailResult[];
36
+ contentCaptureStatus: 'off' | 'captured' | 'capture_failed';
37
+ contentRef?: string;
38
+ retentionExpiresAt?: string;
39
+ occurredAt: string;
40
+ };
41
+ export type AiTraceIdentifier = string;
42
+ export type AiTraceDigest = string;
43
+ export type AiTraceAttempt = {
44
+ attempt: number;
45
+ provider: 'openai' | 'anthropic' | 'gemini' | 'openrouter';
46
+ providerModel: string;
47
+ priceRevision: AiTraceIdentifier;
48
+ outcome: 'succeeded' | 'failed' | 'timed_out' | 'cancelled';
49
+ /**
50
+ * Provider-reported token usage, or null when the attempt did not succeed and the provider reported none. Null states that usage is UNKNOWN — estimates are never fabricated. A succeeded attempt always reports real usage.
51
+ */
52
+ usage: AiTraceUsage | null;
53
+ costMicroUsd: number;
54
+ latencyMs: number;
55
+ errorCode?: string;
56
+ };
57
+ export interface AiTraceUsage {
58
+ inputTokens: number;
59
+ outputTokens: number;
60
+ }
61
+ export interface AiTraceGuardrailResult {
62
+ ruleId: string;
63
+ detectorId: string;
64
+ detectorVersion: string;
65
+ phase: 'input' | 'output';
66
+ action: 'ALLOW' | 'OBSERVE' | 'REDACT' | 'BLOCK';
67
+ result: 'passed' | 'matched' | 'blocked' | 'redacted';
68
+ }
@@ -0,0 +1,47 @@
1
+ export type AiTransformIdentifier = string;
2
+ export type AiTransformDigest = string;
3
+ export type AiTransformPlanEntry = {
4
+ callSiteFingerprint: AiTransformDigest;
5
+ sourcePath: string;
6
+ expectedSourceFileSha256: AiTransformDigest;
7
+ strategy: 'deployment_injection' | 'deterministic_adapter';
8
+ configurationMappingId?: AiTransformIdentifier;
9
+ configurationMappingVersion?: string;
10
+ transformId?: AiTransformIdentifier;
11
+ transformVersion?: string;
12
+ /**
13
+ * @minItems 1
14
+ * @maxItems 32
15
+ */
16
+ allowedSyntaxKinds: AiTransformIdentifier[];
17
+ runtimeShimName?: string;
18
+ runtimeShimVersion?: string;
19
+ runtimeShimDigest?: AiTransformDigest;
20
+ };
21
+ /**
22
+ * Checksum-bound deterministic AI interception task input. Entries are the complete ordered PLAN interception plan so the task can verify the governance plan digest before applying its deterministic subset; source and patches are referenced, never embedded.
23
+ */
24
+ export interface AiTransformEvent {
25
+ schema: 'harbour.ai-transform-event/1.0';
26
+ tenantId: AiTransformIdentifier;
27
+ appId: AiTransformIdentifier;
28
+ environment: AiTransformIdentifier;
29
+ versionId: string;
30
+ sourceRevision: string;
31
+ workspace: AiTransformWorkspace;
32
+ inventoryDigest: AiTransformDigest;
33
+ policyDigest: AiTransformDigest;
34
+ runtimeContractDigest: AiTransformDigest;
35
+ interceptionPlanDigest: AiTransformDigest;
36
+ /**
37
+ * @minItems 1
38
+ * @maxItems 1000
39
+ */
40
+ entries: AiTransformPlanEntry[];
41
+ }
42
+ export interface AiTransformWorkspace {
43
+ bucket: string;
44
+ key: string;
45
+ sha256: AiTransformDigest;
46
+ size: number;
47
+ }
@@ -0,0 +1,32 @@
1
+ export type AiTransformResultDigest = string;
2
+ export type AiTransformResultIdentifier = string;
3
+ /**
4
+ * Bounded deterministic interception result; contains descriptors and digest evidence only.
5
+ */
6
+ export interface AiTransformResult {
7
+ schema: 'harbour.ai-transform-result/1.0';
8
+ workspace: AiTransformResultWorkspace;
9
+ interceptionPlanDigest: AiTransformResultDigest;
10
+ transformerVersion: string;
11
+ /**
12
+ * @minItems 1
13
+ * @maxItems 1000
14
+ */
15
+ applied: AiTransformApplied[];
16
+ }
17
+ export interface AiTransformResultWorkspace {
18
+ bucket: string;
19
+ key: string;
20
+ sha256: AiTransformResultDigest;
21
+ size: number;
22
+ }
23
+ export interface AiTransformApplied {
24
+ callSiteFingerprint: AiTransformResultDigest;
25
+ transformId: AiTransformResultIdentifier;
26
+ transformVersion: string;
27
+ sourcePath: string;
28
+ beforeSha256: AiTransformResultDigest;
29
+ afterSha256: AiTransformResultDigest;
30
+ governedBoundaryFingerprint: AiTransformResultDigest;
31
+ runtimeShimDigest: AiTransformResultDigest;
32
+ }
@@ -0,0 +1,49 @@
1
+ export type AiVerificationIdentifier = string;
2
+ export type AiVerificationDigest = string;
3
+ /**
4
+ * Bounded, value-free evidence submitted by deployment verification for one governed version.
5
+ */
6
+ export interface AiVerificationEvidence {
7
+ schema: 'harbour.ai-verification-evidence/1.0';
8
+ tenantId: AiVerificationIdentifier;
9
+ appId: AiVerificationIdentifier;
10
+ environment: AiVerificationIdentifier;
11
+ versionId: string;
12
+ sourceRevision: string;
13
+ inventoryDigest: AiVerificationDigest;
14
+ interceptionPlanDigest: AiVerificationDigest;
15
+ runtimeContractDigest: AiVerificationDigest;
16
+ policyDigest: AiVerificationDigest;
17
+ finalWorkspaceDigest: AiVerificationDigest;
18
+ /**
19
+ * @maxItems 1000
20
+ */
21
+ verifiedCallsiteFingerprints: AiVerificationDigest[];
22
+ /**
23
+ * @maxItems 1000
24
+ */
25
+ appliedTransforms: AiVerificationTransform[];
26
+ /**
27
+ * @minItems 1
28
+ * @maxItems 32
29
+ */
30
+ endpointChecks: AiVerificationEndpointCheck[];
31
+ providerCredentialsAbsent: true;
32
+ smokeTraceId: string;
33
+ evidenceDigest: AiVerificationDigest;
34
+ verifiedAt: string;
35
+ }
36
+ export interface AiVerificationTransform {
37
+ callSiteFingerprint: AiVerificationDigest;
38
+ governedBoundaryFingerprint: AiVerificationDigest;
39
+ transformId: AiVerificationIdentifier;
40
+ transformVersion: string;
41
+ beforeSha256: AiVerificationDigest;
42
+ afterSha256: AiVerificationDigest;
43
+ runtimeShimDigest: AiVerificationDigest;
44
+ }
45
+ export interface AiVerificationEndpointCheck {
46
+ name: AiVerificationIdentifier;
47
+ passed: true;
48
+ configurationMappingVersion: string;
49
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * database = a SQL/warehouse connection; api = an HTTP(S) service; app_owned_external = infrastructure the app owns outside Harbour.
3
+ */
4
+ export type DataDependencyKind = 'database' | 'api' | 'app_owned_external';
5
+ /**
6
+ * matched = resolved to a registered source; out_of_scope = resolved but not requestable; unknown = unresolvable; inventory = registered but unused; app_owned_external = app-owned, outside Harbour's remit.
7
+ */
8
+ export type DataDependencyClassification = 'matched' | 'out_of_scope' | 'unknown' | 'inventory' | 'app_owned_external';
9
+ /**
10
+ * declared = stated by the builder; detected = found by analysis.
11
+ */
12
+ export type DataDependencyOrigin = 'declared' | 'detected';
13
+ /**
14
+ * A single external data dependency of an app, either declared by the builder or detected during analysis. Classification records how the dependency resolved against the tenant's registered data-source inventory; matchedSourceId is present only when classification is matched.
15
+ */
16
+ export interface DataDependency {
17
+ kind: DataDependencyKind;
18
+ identifiers: DataDependencyIdentifiers;
19
+ classification: DataDependencyClassification;
20
+ /**
21
+ * sourceId of the registered data source this dependency matched; present only when classification is matched.
22
+ */
23
+ matchedSourceId?: string;
24
+ origin: DataDependencyOrigin;
25
+ }
26
+ /**
27
+ * Evidence identifying the dependency; used to match it against the registered source inventory.
28
+ */
29
+ export interface DataDependencyIdentifiers {
30
+ /**
31
+ * Hostnames the dependency was observed or declared against.
32
+ */
33
+ hosts: string[];
34
+ /**
35
+ * Client driver/library that surfaced the dependency (e.g. pg, snowflake-sdk).
36
+ */
37
+ driver?: string;
38
+ /**
39
+ * Environment-variable names the app reads to configure this dependency.
40
+ */
41
+ envNames: string[];
42
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Access mode. MVP is read-only; write is a deliberate future schema change.
3
+ */
4
+ export type DataGrantMode = 'read';
5
+ /**
6
+ * MVP: one minted service principal per grant. Per-end-user passthrough is a future schema change.
7
+ */
8
+ export type DataGrantIdentityModel = 'service';
9
+ /**
10
+ * Grant lifecycle state. Legal edges live in x-transitions; GRANTED and DENIED are terminal.
11
+ */
12
+ export type DataGrantStatus = 'REQUESTED' | 'GRANTED' | 'DENIED';
13
+ /**
14
+ * An app's approved (or requested) read scope against a registered data source. MVP is deliberately narrow: mode is read-only and identityModel is service (one minted principal per grant, no per-end-user identity passthrough). Grant status is a tiny state machine — legal edges live in x-transitions and codegen turns them into shared CanTransitionDataGrantStatus / IsTerminalDataGrantStatus helpers so control-plane and consumers agree on legality.
15
+ */
16
+ export interface DataGrant {
17
+ /**
18
+ * App the grant belongs to.
19
+ */
20
+ appId: string;
21
+ /**
22
+ * Registered data source the grant targets (data-source.schema.json).
23
+ */
24
+ sourceId: string;
25
+ /**
26
+ * Requested/granted selectors; every selector must fall inside the source's allowedScope.
27
+ *
28
+ * @minItems 1
29
+ */
30
+ scope: string[];
31
+ mode: DataGrantMode;
32
+ identityModel: DataGrantIdentityModel;
33
+ status: DataGrantStatus;
34
+ /**
35
+ * secretref URI of the minted per-grant credential; present once GRANTED.
36
+ */
37
+ credentialRef?: string;
38
+ /**
39
+ * Name of the scoped principal minted on the source for this grant; present once GRANTED.
40
+ */
41
+ mintedPrincipal?: string;
42
+ /**
43
+ * Operation (e.g. deployment analysis) that raised the request, for audit correlation.
44
+ */
45
+ requestedByOperationId?: string;
46
+ /**
47
+ * Admin identity that resolved the request; present once GRANTED or DENIED.
48
+ */
49
+ approvedBy?: string;
50
+ /**
51
+ * RFC 3339 instant the request was resolved; present once GRANTED or DENIED.
52
+ */
53
+ approvedAt?: string;
54
+ }
55
+ /** True iff from→to is a legal DataGrantStatus edge (schema x-transitions). */
56
+ export declare function canTransitionDataGrantStatus(from: string, to: string): boolean;
57
+ /** True iff the DataGrantStatus is terminal (GRANTED, DENIED). */
58
+ export declare function isTerminalDataGrantStatus(state: string): boolean;
@@ -0,0 +1,12 @@
1
+ /* eslint-disable */
2
+ // Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
3
+ const legalDataGrantStatusTransitions = {
4
+ "REQUESTED": { "GRANTED": true, "DENIED": true },
5
+ };
6
+ const terminalDataGrantStatusStates = new Set(["GRANTED", "DENIED"]);
7
+ /** True iff from→to is a legal DataGrantStatus edge (schema x-transitions). */
8
+ export function canTransitionDataGrantStatus(from, to) {
9
+ return Boolean(legalDataGrantStatusTransitions[from]?.[to]);
10
+ }
11
+ /** True iff the DataGrantStatus is terminal (GRANTED, DENIED). */
12
+ export function isTerminalDataGrantStatus(state) { return terminalDataGrantStatusStates.has(state); }