@eddacraft/anvil-kindling-integration 0.1.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 (84) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +542 -0
  3. package/dist/adapter.d.ts +49 -0
  4. package/dist/adapter.d.ts.map +1 -0
  5. package/dist/adapter.js +100 -0
  6. package/dist/config.d.ts +89 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +173 -0
  9. package/dist/emitters/action-emitter.d.ts +40 -0
  10. package/dist/emitters/action-emitter.d.ts.map +1 -0
  11. package/dist/emitters/action-emitter.js +52 -0
  12. package/dist/emitters/constraint-emitter.d.ts +32 -0
  13. package/dist/emitters/constraint-emitter.d.ts.map +1 -0
  14. package/dist/emitters/constraint-emitter.js +41 -0
  15. package/dist/emitters/error-emitter.d.ts +33 -0
  16. package/dist/emitters/error-emitter.d.ts.map +1 -0
  17. package/dist/emitters/error-emitter.js +50 -0
  18. package/dist/emitters/gate-emitter.d.ts +37 -0
  19. package/dist/emitters/gate-emitter.d.ts.map +1 -0
  20. package/dist/emitters/gate-emitter.js +53 -0
  21. package/dist/emitters/human-input-emitter.d.ts +30 -0
  22. package/dist/emitters/human-input-emitter.d.ts.map +1 -0
  23. package/dist/emitters/human-input-emitter.js +38 -0
  24. package/dist/emitters/index.d.ts +13 -0
  25. package/dist/emitters/index.d.ts.map +1 -0
  26. package/dist/emitters/index.js +19 -0
  27. package/dist/emitters/plan-emitter.d.ts +75 -0
  28. package/dist/emitters/plan-emitter.d.ts.map +1 -0
  29. package/dist/emitters/plan-emitter.js +116 -0
  30. package/dist/emitters/session-emitter.d.ts +57 -0
  31. package/dist/emitters/session-emitter.d.ts.map +1 -0
  32. package/dist/emitters/session-emitter.js +80 -0
  33. package/dist/index.d.ts +40 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +111 -0
  36. package/dist/kindling-service.d.ts +122 -0
  37. package/dist/kindling-service.d.ts.map +1 -0
  38. package/dist/kindling-service.js +203 -0
  39. package/dist/observation-contract.d.ts +561 -0
  40. package/dist/observation-contract.d.ts.map +1 -0
  41. package/dist/observation-contract.js +391 -0
  42. package/dist/query-contract.d.ts +463 -0
  43. package/dist/query-contract.d.ts.map +1 -0
  44. package/dist/query-contract.js +314 -0
  45. package/dist/query-limits.d.ts +40 -0
  46. package/dist/query-limits.d.ts.map +1 -0
  47. package/dist/query-limits.js +79 -0
  48. package/dist/query-service.d.ts +109 -0
  49. package/dist/query-service.d.ts.map +1 -0
  50. package/dist/query-service.js +140 -0
  51. package/dist/retention.d.ts +79 -0
  52. package/dist/retention.d.ts.map +1 -0
  53. package/dist/retention.js +81 -0
  54. package/dist/sensitive-data-validator.d.ts +47 -0
  55. package/dist/sensitive-data-validator.d.ts.map +1 -0
  56. package/dist/sensitive-data-validator.js +135 -0
  57. package/dist/status.d.ts +104 -0
  58. package/dist/status.d.ts.map +1 -0
  59. package/dist/status.js +136 -0
  60. package/dist/utils/debug.d.ts +9 -0
  61. package/dist/utils/debug.d.ts.map +1 -0
  62. package/dist/utils/debug.js +55 -0
  63. package/package.json +114 -0
  64. package/src/adapter.ts +117 -0
  65. package/src/config.ts +202 -0
  66. package/src/emitters/action-emitter.ts +90 -0
  67. package/src/emitters/constraint-emitter.ts +73 -0
  68. package/src/emitters/error-emitter.ts +86 -0
  69. package/src/emitters/gate-emitter.ts +87 -0
  70. package/src/emitters/human-input-emitter.ts +71 -0
  71. package/src/emitters/index.ts +40 -0
  72. package/src/emitters/plan-emitter.ts +183 -0
  73. package/src/emitters/session-emitter.ts +131 -0
  74. package/src/index.ts +254 -0
  75. package/src/kindling-service.ts +272 -0
  76. package/src/malicious-ai.test.ts +949 -0
  77. package/src/observation-contract.ts +500 -0
  78. package/src/query-contract.ts +389 -0
  79. package/src/query-limits.ts +106 -0
  80. package/src/query-service.ts +217 -0
  81. package/src/retention.ts +153 -0
  82. package/src/sensitive-data-validator.ts +167 -0
  83. package/src/status.ts +221 -0
  84. package/src/utils/debug.ts +65 -0
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Kindling Configuration Schema (KINDLING-002)
3
+ *
4
+ * Defines configuration for the Kindling integration layer.
5
+ * Configuration is read from `.anvilrc` or `anvil.config.json` in the project root.
6
+ *
7
+ * @see kindling-service.ts for how config is consumed
8
+ */
9
+ import { z } from 'zod';
10
+ /**
11
+ * Capture flags: which observation kinds to record
12
+ */
13
+ export declare const CaptureConfigSchema: z.ZodObject<{
14
+ sessions: z.ZodDefault<z.ZodBoolean>;
15
+ gates: z.ZodDefault<z.ZodBoolean>;
16
+ actions: z.ZodDefault<z.ZodBoolean>;
17
+ plans: z.ZodDefault<z.ZodBoolean>;
18
+ human_inputs: z.ZodDefault<z.ZodBoolean>;
19
+ constraints: z.ZodDefault<z.ZodBoolean>;
20
+ errors: z.ZodDefault<z.ZodBoolean>;
21
+ }, z.core.$strip>;
22
+ export type CaptureConfig = z.infer<typeof CaptureConfigSchema>;
23
+ /**
24
+ * Retention policy
25
+ */
26
+ export declare const RetentionConfigSchema: z.ZodObject<{
27
+ days: z.ZodDefault<z.ZodNumber>;
28
+ auto_prune: z.ZodDefault<z.ZodBoolean>;
29
+ }, z.core.$strip>;
30
+ export type RetentionConfig = z.infer<typeof RetentionConfigSchema>;
31
+ /**
32
+ * Query limit defaults
33
+ */
34
+ export declare const QueryLimitConfigSchema: z.ZodObject<{
35
+ max_results: z.ZodDefault<z.ZodNumber>;
36
+ max_payload_bytes: z.ZodDefault<z.ZodNumber>;
37
+ }, z.core.$strip>;
38
+ export type QueryLimitConfig = z.infer<typeof QueryLimitConfigSchema>;
39
+ /**
40
+ * Full Kindling configuration
41
+ */
42
+ export declare const KindlingConfigSchema: z.ZodObject<{
43
+ enabled: z.ZodDefault<z.ZodBoolean>;
44
+ database_path: z.ZodDefault<z.ZodString>;
45
+ retention: z.ZodDefault<z.ZodObject<{
46
+ days: z.ZodDefault<z.ZodNumber>;
47
+ auto_prune: z.ZodDefault<z.ZodBoolean>;
48
+ }, z.core.$strip>>;
49
+ capture: z.ZodDefault<z.ZodObject<{
50
+ sessions: z.ZodDefault<z.ZodBoolean>;
51
+ gates: z.ZodDefault<z.ZodBoolean>;
52
+ actions: z.ZodDefault<z.ZodBoolean>;
53
+ plans: z.ZodDefault<z.ZodBoolean>;
54
+ human_inputs: z.ZodDefault<z.ZodBoolean>;
55
+ constraints: z.ZodDefault<z.ZodBoolean>;
56
+ errors: z.ZodDefault<z.ZodBoolean>;
57
+ }, z.core.$strip>>;
58
+ query_limits: z.ZodDefault<z.ZodObject<{
59
+ max_results: z.ZodDefault<z.ZodNumber>;
60
+ max_payload_bytes: z.ZodDefault<z.ZodNumber>;
61
+ }, z.core.$strip>>;
62
+ }, z.core.$strip>;
63
+ export type KindlingConfig = z.infer<typeof KindlingConfigSchema>;
64
+ /**
65
+ * Default configuration: disabled, sensible defaults for everything else
66
+ */
67
+ export declare const DEFAULT_KINDLING_CONFIG: KindlingConfig;
68
+ /**
69
+ * Load Kindling configuration from the project root.
70
+ *
71
+ * Searches for `.anvilrc` or `anvil.config.json` in the given directory.
72
+ * Expects a JSON file with an optional `kindling` key containing the config.
73
+ *
74
+ * Returns the default (disabled) config if no file is found or if the
75
+ * `kindling` key is absent.
76
+ *
77
+ * @param projectRoot - Absolute path to the project root directory
78
+ * @returns Parsed and validated KindlingConfig
79
+ */
80
+ export declare function loadKindlingConfig(projectRoot: string): KindlingConfig;
81
+ /**
82
+ * Check whether a specific observation kind should be captured based on config.
83
+ *
84
+ * @param config - Kindling configuration
85
+ * @param kind - Observation kind string
86
+ * @returns true if the observation should be captured
87
+ */
88
+ export declare function shouldCapture(config: KindlingConfig, kind: string): boolean;
89
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;iBAQ9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;iBAGhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;iBAejC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;iBAuB/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMlE;;GAEG;AACH,eAAO,MAAM,uBAAuB,EAAE,cAA+C,CAAC;AAWtF;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CAwCtE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CA4B3E"}
package/dist/config.js ADDED
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Kindling Configuration Schema (KINDLING-002)
3
+ *
4
+ * Defines configuration for the Kindling integration layer.
5
+ * Configuration is read from `.anvilrc` or `anvil.config.json` in the project root.
6
+ *
7
+ * @see kindling-service.ts for how config is consumed
8
+ */
9
+ import { z } from 'zod';
10
+ import { readFileSync, existsSync } from 'node:fs';
11
+ import { join } from 'node:path';
12
+ // =============================================================================
13
+ // Configuration Schema
14
+ // =============================================================================
15
+ /**
16
+ * Capture flags: which observation kinds to record
17
+ */
18
+ export const CaptureConfigSchema = z.object({
19
+ sessions: z.boolean().default(true).describe('Record session start/end'),
20
+ gates: z.boolean().default(true).describe('Record gate evaluations'),
21
+ actions: z.boolean().default(true).describe('Record action executions'),
22
+ plans: z.boolean().default(true).describe('Record plan lifecycle events'),
23
+ human_inputs: z.boolean().default(true).describe('Record human inputs'),
24
+ constraints: z.boolean().default(true).describe('Record constraint applications'),
25
+ errors: z.boolean().default(true).describe('Record errors'),
26
+ });
27
+ /**
28
+ * Retention policy
29
+ */
30
+ export const RetentionConfigSchema = z.object({
31
+ days: z.number().int().positive().default(90).describe('Days to retain observations'),
32
+ auto_prune: z.boolean().default(false).describe('Automatically prune on session start'),
33
+ });
34
+ /**
35
+ * Query limit defaults
36
+ */
37
+ export const QueryLimitConfigSchema = z.object({
38
+ max_results: z
39
+ .number()
40
+ .int()
41
+ .positive()
42
+ .max(1000)
43
+ .default(100)
44
+ .describe('Default max results per query'),
45
+ max_payload_bytes: z
46
+ .number()
47
+ .int()
48
+ .positive()
49
+ .max(10 * 1024 * 1024)
50
+ .default(1024 * 1024)
51
+ .describe('Default max payload size in bytes'),
52
+ });
53
+ /**
54
+ * Full Kindling configuration
55
+ */
56
+ export const KindlingConfigSchema = z.object({
57
+ enabled: z.boolean().default(false).describe('Whether Kindling recording is active'),
58
+ database_path: z
59
+ .string()
60
+ .default('.anvil/kindling.db')
61
+ .describe('Path to the SQLite database (relative to project root)'),
62
+ retention: RetentionConfigSchema.default(() => ({
63
+ days: 90,
64
+ auto_prune: false,
65
+ })),
66
+ capture: CaptureConfigSchema.default(() => ({
67
+ sessions: true,
68
+ gates: true,
69
+ actions: true,
70
+ plans: true,
71
+ human_inputs: true,
72
+ constraints: true,
73
+ errors: true,
74
+ })),
75
+ query_limits: QueryLimitConfigSchema.default(() => ({
76
+ max_results: 100,
77
+ max_payload_bytes: 1024 * 1024,
78
+ })),
79
+ });
80
+ // =============================================================================
81
+ // Default Configuration
82
+ // =============================================================================
83
+ /**
84
+ * Default configuration: disabled, sensible defaults for everything else
85
+ */
86
+ export const DEFAULT_KINDLING_CONFIG = KindlingConfigSchema.parse({});
87
+ // =============================================================================
88
+ // Configuration Loading
89
+ // =============================================================================
90
+ /**
91
+ * Known configuration file names, checked in order
92
+ */
93
+ const CONFIG_FILE_NAMES = ['.anvilrc', 'anvil.config.json'];
94
+ /**
95
+ * Load Kindling configuration from the project root.
96
+ *
97
+ * Searches for `.anvilrc` or `anvil.config.json` in the given directory.
98
+ * Expects a JSON file with an optional `kindling` key containing the config.
99
+ *
100
+ * Returns the default (disabled) config if no file is found or if the
101
+ * `kindling` key is absent.
102
+ *
103
+ * @param projectRoot - Absolute path to the project root directory
104
+ * @returns Parsed and validated KindlingConfig
105
+ */
106
+ export function loadKindlingConfig(projectRoot) {
107
+ for (const fileName of CONFIG_FILE_NAMES) {
108
+ const filePath = join(projectRoot, fileName);
109
+ if (!existsSync(filePath)) {
110
+ continue;
111
+ }
112
+ try {
113
+ const raw = readFileSync(filePath, 'utf-8');
114
+ const parsed = JSON.parse(raw);
115
+ if (parsed === null || typeof parsed !== 'object') {
116
+ continue;
117
+ }
118
+ const record = parsed;
119
+ if (!('kindling' in record) || record['kindling'] === undefined) {
120
+ // Config file exists but has no kindling section
121
+ return DEFAULT_KINDLING_CONFIG;
122
+ }
123
+ const result = KindlingConfigSchema.safeParse(record['kindling']);
124
+ if (result.success) {
125
+ return result.data;
126
+ }
127
+ // Invalid config shape -- fall back to defaults rather than crashing
128
+ // The caller (service layer) will operate in disabled mode
129
+ return DEFAULT_KINDLING_CONFIG;
130
+ }
131
+ catch {
132
+ // JSON parse error or read error -- fall back to defaults
133
+ return DEFAULT_KINDLING_CONFIG;
134
+ }
135
+ }
136
+ // No config file found
137
+ return DEFAULT_KINDLING_CONFIG;
138
+ }
139
+ /**
140
+ * Check whether a specific observation kind should be captured based on config.
141
+ *
142
+ * @param config - Kindling configuration
143
+ * @param kind - Observation kind string
144
+ * @returns true if the observation should be captured
145
+ */
146
+ export function shouldCapture(config, kind) {
147
+ if (!config.enabled) {
148
+ return false;
149
+ }
150
+ switch (kind) {
151
+ case 'session_start':
152
+ case 'session_end':
153
+ return config.capture.sessions;
154
+ case 'gate_evaluated':
155
+ return config.capture.gates;
156
+ case 'action_executed':
157
+ return config.capture.actions;
158
+ case 'plan_created':
159
+ case 'plan_edited':
160
+ case 'plan_approved':
161
+ case 'plan_rejected':
162
+ return config.capture.plans;
163
+ case 'human_input':
164
+ return config.capture.human_inputs;
165
+ case 'constraint_applied':
166
+ return config.capture.constraints;
167
+ case 'error':
168
+ return config.capture.errors;
169
+ default:
170
+ // Unknown kinds are captured by default when enabled
171
+ return true;
172
+ }
173
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Action Emitter (KINDLING-005)
3
+ *
4
+ * Emits action_executed observations when commands, tool invocations,
5
+ * file operations, or diff applications occur.
6
+ */
7
+ import type { KindlingService } from '../kindling-service.js';
8
+ /**
9
+ * Action execution details to be recorded
10
+ */
11
+ export interface ActionDetails {
12
+ session_id: string;
13
+ action_type: 'command' | 'tool_invocation' | 'file_write' | 'file_delete' | 'diff_apply';
14
+ details: {
15
+ command?: string;
16
+ tool_name?: string;
17
+ file_paths?: string[];
18
+ diff_summary?: {
19
+ additions: number;
20
+ deletions: number;
21
+ files_changed: number;
22
+ };
23
+ working_directory: string;
24
+ environment_target?: string;
25
+ };
26
+ governed_by_gate_id?: string;
27
+ governed_by_plan_id?: string;
28
+ outcome: 'success' | 'failure' | 'partial';
29
+ exit_code?: number;
30
+ duration_ms: number;
31
+ }
32
+ /**
33
+ * Emit an action_executed observation.
34
+ *
35
+ * @param service - KindlingService instance
36
+ * @param actionDetails - Action execution details
37
+ * @returns The generated action_id
38
+ */
39
+ export declare function emitActionExecuted(service: KindlingService, actionDetails: ActionDetails): string;
40
+ //# sourceMappingURL=action-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/action-emitter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAU9D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,SAAS,GAAG,iBAAiB,GAAG,YAAY,GAAG,aAAa,GAAG,YAAY,CAAC;IACzF,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,YAAY,CAAC,EAAE;YACb,SAAS,EAAE,MAAM,CAAC;YAClB,SAAS,EAAE,MAAM,CAAC;YAClB,aAAa,EAAE,MAAM,CAAC;SACvB,CAAC;QACF,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,GAAG,MAAM,CAmCjG"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Action Emitter (KINDLING-005)
3
+ *
4
+ * Emits action_executed observations when commands, tool invocations,
5
+ * file operations, or diff applications occur.
6
+ */
7
+ import { randomUUID } from 'node:crypto';
8
+ import { createDebugger } from '../utils/debug.js';
9
+ const debug = createDebugger('kindling');
10
+ // =============================================================================
11
+ // Emitter
12
+ // =============================================================================
13
+ /**
14
+ * Emit an action_executed observation.
15
+ *
16
+ * @param service - KindlingService instance
17
+ * @param actionDetails - Action execution details
18
+ * @returns The generated action_id
19
+ */
20
+ export function emitActionExecuted(service, actionDetails) {
21
+ const actionId = randomUUID();
22
+ debug('emitting action_executed', {
23
+ actionId,
24
+ actionType: actionDetails.action_type,
25
+ outcome: actionDetails.outcome,
26
+ });
27
+ const observation = {
28
+ kind: 'action_executed',
29
+ session_id: actionDetails.session_id,
30
+ timestamp: new Date().toISOString(),
31
+ action_id: actionId,
32
+ action_type: actionDetails.action_type,
33
+ details: {
34
+ command: actionDetails.details.command,
35
+ tool_name: actionDetails.details.tool_name,
36
+ file_paths: actionDetails.details.file_paths,
37
+ diff_summary: actionDetails.details.diff_summary,
38
+ working_directory: actionDetails.details.working_directory,
39
+ environment_target: actionDetails.details.environment_target,
40
+ },
41
+ governed_by_gate_id: actionDetails.governed_by_gate_id,
42
+ governed_by_plan_id: actionDetails.governed_by_plan_id,
43
+ outcome: actionDetails.outcome,
44
+ exit_code: actionDetails.exit_code,
45
+ duration_ms: actionDetails.duration_ms,
46
+ };
47
+ // Fire-and-forget
48
+ service.emit(observation).catch(() => {
49
+ // Silently swallow
50
+ });
51
+ return actionId;
52
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Constraint Emitter (KINDLING-007b)
3
+ *
4
+ * Emits constraint_applied observations when Anvil prevents an action
5
+ * due to policy, scope, environment, or approval requirements.
6
+ */
7
+ import type { KindlingService } from '../kindling-service.js';
8
+ /**
9
+ * Constraint application details to be recorded
10
+ */
11
+ export interface ConstraintDetails {
12
+ session_id: string;
13
+ constraint_type: 'policy' | 'rule' | 'scope' | 'environment' | 'approval_required';
14
+ prevented_action: {
15
+ action_type: string;
16
+ action_target?: string;
17
+ };
18
+ reason: string;
19
+ scope?: string;
20
+ environment?: string;
21
+ options_available?: string[];
22
+ options_allowed?: string[];
23
+ }
24
+ /**
25
+ * Emit a constraint_applied observation.
26
+ *
27
+ * @param service - KindlingService instance
28
+ * @param constraint - Constraint application details
29
+ * @returns The generated constraint_id
30
+ */
31
+ export declare function emitConstraintApplied(service: KindlingService, constraint: ConstraintDetails): string;
32
+ //# sourceMappingURL=constraint-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraint-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/constraint-emitter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAO9D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,GAAG,mBAAmB,CAAC;IACnF,gBAAgB,EAAE;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAMD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,eAAe,EACxB,UAAU,EAAE,iBAAiB,GAC5B,MAAM,CA0BR"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Constraint Emitter (KINDLING-007b)
3
+ *
4
+ * Emits constraint_applied observations when Anvil prevents an action
5
+ * due to policy, scope, environment, or approval requirements.
6
+ */
7
+ import { randomUUID } from 'node:crypto';
8
+ // =============================================================================
9
+ // Emitter
10
+ // =============================================================================
11
+ /**
12
+ * Emit a constraint_applied observation.
13
+ *
14
+ * @param service - KindlingService instance
15
+ * @param constraint - Constraint application details
16
+ * @returns The generated constraint_id
17
+ */
18
+ export function emitConstraintApplied(service, constraint) {
19
+ const constraintId = randomUUID();
20
+ const observation = {
21
+ kind: 'constraint_applied',
22
+ session_id: constraint.session_id,
23
+ timestamp: new Date().toISOString(),
24
+ constraint_id: constraintId,
25
+ constraint_type: constraint.constraint_type,
26
+ prevented_action: {
27
+ action_type: constraint.prevented_action.action_type,
28
+ action_target: constraint.prevented_action.action_target,
29
+ },
30
+ reason: constraint.reason,
31
+ scope: constraint.scope,
32
+ environment: constraint.environment,
33
+ options_available: constraint.options_available,
34
+ options_allowed: constraint.options_allowed,
35
+ };
36
+ // Fire-and-forget
37
+ service.emit(observation).catch(() => {
38
+ // Silently swallow
39
+ });
40
+ return constraintId;
41
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Error Emitter (KINDLING-008)
3
+ *
4
+ * Emits error observations when failures occur.
5
+ * "Errors are not noise, they are data."
6
+ */
7
+ import type { KindlingService } from '../kindling-service.js';
8
+ /**
9
+ * Error details to be recorded
10
+ */
11
+ export interface ErrorDetails {
12
+ session_id: string;
13
+ error_type: 'command_failure' | 'tool_error' | 'aborted_execution' | 'partial_state' | 'validation_failure';
14
+ context: {
15
+ component: string;
16
+ action_id?: string;
17
+ gate_id?: string;
18
+ };
19
+ error_message: string;
20
+ error_code?: string;
21
+ exit_code?: number;
22
+ recoverable: boolean;
23
+ partial_state_description?: string;
24
+ }
25
+ /**
26
+ * Emit an error observation.
27
+ *
28
+ * @param service - KindlingService instance
29
+ * @param errorDetails - Error details
30
+ * @returns The generated error_id
31
+ */
32
+ export declare function emitError(service: KindlingService, errorDetails: ErrorDetails): string;
33
+ //# sourceMappingURL=error-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/error-emitter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAU9D;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EACN,iBAAiB,GACjB,YAAY,GACZ,mBAAmB,GACnB,eAAe,GACf,oBAAoB,CAAC;IACzB,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAMD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,GAAG,MAAM,CAiCtF"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Error Emitter (KINDLING-008)
3
+ *
4
+ * Emits error observations when failures occur.
5
+ * "Errors are not noise, they are data."
6
+ */
7
+ import { randomUUID } from 'node:crypto';
8
+ import { createDebugger } from '../utils/debug.js';
9
+ const debug = createDebugger('kindling');
10
+ // =============================================================================
11
+ // Emitter
12
+ // =============================================================================
13
+ /**
14
+ * Emit an error observation.
15
+ *
16
+ * @param service - KindlingService instance
17
+ * @param errorDetails - Error details
18
+ * @returns The generated error_id
19
+ */
20
+ export function emitError(service, errorDetails) {
21
+ const errorId = randomUUID();
22
+ debug('emitting error observation', {
23
+ errorId,
24
+ errorType: errorDetails.error_type,
25
+ component: errorDetails.context.component,
26
+ recoverable: errorDetails.recoverable,
27
+ });
28
+ const observation = {
29
+ kind: 'error',
30
+ session_id: errorDetails.session_id,
31
+ timestamp: new Date().toISOString(),
32
+ error_id: errorId,
33
+ error_type: errorDetails.error_type,
34
+ context: {
35
+ component: errorDetails.context.component,
36
+ action_id: errorDetails.context.action_id,
37
+ gate_id: errorDetails.context.gate_id,
38
+ },
39
+ error_message: errorDetails.error_message,
40
+ error_code: errorDetails.error_code,
41
+ exit_code: errorDetails.exit_code,
42
+ recoverable: errorDetails.recoverable,
43
+ partial_state_description: errorDetails.partial_state_description,
44
+ };
45
+ // Fire-and-forget
46
+ service.emit(observation).catch(() => {
47
+ // Silently swallow
48
+ });
49
+ return errorId;
50
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Gate Emitter (KINDLING-004)
3
+ *
4
+ * Emits gate_evaluated observations when gates are checked.
5
+ * Gate evaluations form the governance record -- why things were
6
+ * allowed or blocked.
7
+ */
8
+ import type { KindlingService } from '../kindling-service.js';
9
+ /**
10
+ * Gate evaluation result to be recorded
11
+ */
12
+ export interface GateResult {
13
+ session_id: string;
14
+ gate_id: string;
15
+ gate_version?: string;
16
+ inputs: {
17
+ file_count?: number;
18
+ changed_files?: string[];
19
+ baseline_hash?: string;
20
+ };
21
+ outcome: 'pass' | 'fail' | 'error' | 'skipped';
22
+ rules_evaluated: string[];
23
+ rules_violated?: string[];
24
+ enforcement: 'blocking' | 'warning' | 'informational';
25
+ duration_ms: number;
26
+ violation_count?: number;
27
+ warning_count?: number;
28
+ }
29
+ /**
30
+ * Emit a gate_evaluated observation.
31
+ *
32
+ * @param service - KindlingService instance
33
+ * @param gateResult - Gate evaluation result
34
+ * @returns The generated gate_eval_id
35
+ */
36
+ export declare function emitGateEvaluated(service: KindlingService, gateResult: GateResult): string;
37
+ //# sourceMappingURL=gate-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/gate-emitter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAU9D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE;QACN,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC/C,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAE,UAAU,GAAG,SAAS,GAAG,eAAe,CAAC;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,GAAG,MAAM,CAmC1F"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Gate Emitter (KINDLING-004)
3
+ *
4
+ * Emits gate_evaluated observations when gates are checked.
5
+ * Gate evaluations form the governance record -- why things were
6
+ * allowed or blocked.
7
+ */
8
+ import { randomUUID } from 'node:crypto';
9
+ import { createDebugger } from '../utils/debug.js';
10
+ const debug = createDebugger('kindling');
11
+ // =============================================================================
12
+ // Emitter
13
+ // =============================================================================
14
+ /**
15
+ * Emit a gate_evaluated observation.
16
+ *
17
+ * @param service - KindlingService instance
18
+ * @param gateResult - Gate evaluation result
19
+ * @returns The generated gate_eval_id
20
+ */
21
+ export function emitGateEvaluated(service, gateResult) {
22
+ const gateEvalId = randomUUID();
23
+ debug('emitting gate_evaluated', {
24
+ gateId: gateResult.gate_id,
25
+ outcome: gateResult.outcome,
26
+ gateEvalId,
27
+ });
28
+ const observation = {
29
+ kind: 'gate_evaluated',
30
+ session_id: gateResult.session_id,
31
+ timestamp: new Date().toISOString(),
32
+ gate_eval_id: gateEvalId,
33
+ gate_id: gateResult.gate_id,
34
+ gate_version: gateResult.gate_version,
35
+ inputs: {
36
+ file_count: gateResult.inputs.file_count,
37
+ changed_files: gateResult.inputs.changed_files,
38
+ baseline_hash: gateResult.inputs.baseline_hash,
39
+ },
40
+ outcome: gateResult.outcome,
41
+ rules_evaluated: gateResult.rules_evaluated,
42
+ rules_violated: gateResult.rules_violated,
43
+ enforcement: gateResult.enforcement,
44
+ duration_ms: gateResult.duration_ms,
45
+ violation_count: gateResult.violation_count,
46
+ warning_count: gateResult.warning_count,
47
+ };
48
+ // Fire-and-forget
49
+ service.emit(observation).catch(() => {
50
+ // Silently swallow
51
+ });
52
+ return gateEvalId;
53
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Human Input Emitter (KINDLING-007a)
3
+ *
4
+ * Emits human_input observations when a user makes a decision
5
+ * (approval, override, rejection, manual edit, confirmation, cancellation).
6
+ */
7
+ import type { KindlingService } from '../kindling-service.js';
8
+ /**
9
+ * Human input details to be recorded
10
+ */
11
+ export interface HumanInputDetails {
12
+ session_id: string;
13
+ input_type: 'approval' | 'override' | 'rejection' | 'manual_edit' | 'confirmation' | 'cancellation';
14
+ context: {
15
+ prompt?: string;
16
+ target?: string;
17
+ };
18
+ decision: string;
19
+ reason?: string;
20
+ user_identifier: string;
21
+ }
22
+ /**
23
+ * Emit a human_input observation.
24
+ *
25
+ * @param service - KindlingService instance
26
+ * @param input - Human input details
27
+ * @returns A generated ID for linking purposes
28
+ */
29
+ export declare function emitHumanInput(service: KindlingService, input: HumanInputDetails): string;
30
+ //# sourceMappingURL=human-input-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"human-input-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/human-input-emitter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAO9D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EACN,UAAU,GACV,UAAU,GACV,WAAW,GACX,aAAa,GACb,cAAc,GACd,cAAc,CAAC;IACnB,OAAO,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB;AAMD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAuBzF"}