@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,38 @@
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 { randomUUID } from 'node:crypto';
8
+ // =============================================================================
9
+ // Emitter
10
+ // =============================================================================
11
+ /**
12
+ * Emit a human_input observation.
13
+ *
14
+ * @param service - KindlingService instance
15
+ * @param input - Human input details
16
+ * @returns A generated ID for linking purposes
17
+ */
18
+ export function emitHumanInput(service, input) {
19
+ const inputId = randomUUID();
20
+ const observation = {
21
+ kind: 'human_input',
22
+ session_id: input.session_id,
23
+ timestamp: new Date().toISOString(),
24
+ input_type: input.input_type,
25
+ context: {
26
+ prompt: input.context.prompt,
27
+ target: input.context.target,
28
+ },
29
+ decision: input.decision,
30
+ reason: input.reason,
31
+ user_identifier: input.user_identifier,
32
+ };
33
+ // Fire-and-forget
34
+ service.emit(observation).catch(() => {
35
+ // Silently swallow
36
+ });
37
+ return inputId;
38
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Emitters Barrel Export (KINDLING-003 through 008)
3
+ *
4
+ * All emitter functions and their input types, re-exported for convenience.
5
+ */
6
+ export { emitSessionStart, emitSessionEnd, type SessionStartContext, type SessionEndOutcome, } from './session-emitter.js';
7
+ export { emitGateEvaluated, type GateResult } from './gate-emitter.js';
8
+ export { emitActionExecuted, type ActionDetails } from './action-emitter.js';
9
+ export { emitPlanCreated, emitPlanEdited, emitPlanApproved, emitPlanRejected, type PlanCreatedInput, type PlanEditedInput, type PlanApprovedInput, type PlanRejectedInput, } from './plan-emitter.js';
10
+ export { emitHumanInput, type HumanInputDetails } from './human-input-emitter.js';
11
+ export { emitConstraintApplied, type ConstraintDetails } from './constraint-emitter.js';
12
+ export { emitError, type ErrorDetails } from './error-emitter.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/emitters/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,GACvB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGvE,OAAO,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAG7E,OAAO,EACL,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,cAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlF,OAAO,EAAE,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAGxF,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Emitters Barrel Export (KINDLING-003 through 008)
3
+ *
4
+ * All emitter functions and their input types, re-exported for convenience.
5
+ */
6
+ // Session (KINDLING-003)
7
+ export { emitSessionStart, emitSessionEnd, } from './session-emitter.js';
8
+ // Gate (KINDLING-004)
9
+ export { emitGateEvaluated } from './gate-emitter.js';
10
+ // Action (KINDLING-005)
11
+ export { emitActionExecuted } from './action-emitter.js';
12
+ // Plan (KINDLING-006)
13
+ export { emitPlanCreated, emitPlanEdited, emitPlanApproved, emitPlanRejected, } from './plan-emitter.js';
14
+ // Human Input (KINDLING-007a)
15
+ export { emitHumanInput } from './human-input-emitter.js';
16
+ // Constraint (KINDLING-007b)
17
+ export { emitConstraintApplied } from './constraint-emitter.js';
18
+ // Error (KINDLING-008)
19
+ export { emitError } from './error-emitter.js';
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Plan Emitter (KINDLING-006)
3
+ *
4
+ * Emits plan lifecycle observations: created, edited, approved, rejected.
5
+ * Plans are the governance artifacts that authorize actions.
6
+ */
7
+ import type { KindlingService } from '../kindling-service.js';
8
+ export interface PlanCreatedInput {
9
+ session_id: string;
10
+ plan_id?: string;
11
+ plan_version: string;
12
+ plan_path: string;
13
+ plan_hash: string;
14
+ created_by: 'human' | 'ai' | 'system';
15
+ source?: string;
16
+ }
17
+ export interface PlanEditedInput {
18
+ session_id: string;
19
+ plan_id: string;
20
+ previous_version: string;
21
+ new_version: string;
22
+ previous_hash: string;
23
+ new_hash: string;
24
+ edited_by: 'human' | 'ai' | 'system';
25
+ change_summary?: string;
26
+ }
27
+ export interface PlanApprovedInput {
28
+ session_id: string;
29
+ plan_id: string;
30
+ plan_version: string;
31
+ approved_by: string;
32
+ approval_method: 'cli_confirm' | 'explicit_flag' | 'ci_gate';
33
+ }
34
+ export interface PlanRejectedInput {
35
+ session_id: string;
36
+ plan_id: string;
37
+ plan_version: string;
38
+ rejected_by: string;
39
+ rejection_reason?: string;
40
+ }
41
+ /**
42
+ * Emit a plan_created observation.
43
+ *
44
+ * If no plan_id is provided, one is generated.
45
+ *
46
+ * @param service - KindlingService instance
47
+ * @param plan - Plan creation details
48
+ * @returns The plan_id (generated or provided)
49
+ */
50
+ export declare function emitPlanCreated(service: KindlingService, plan: PlanCreatedInput): string;
51
+ /**
52
+ * Emit a plan_edited observation.
53
+ *
54
+ * @param service - KindlingService instance
55
+ * @param edit - Plan edit details
56
+ * @returns The plan_id
57
+ */
58
+ export declare function emitPlanEdited(service: KindlingService, edit: PlanEditedInput): string;
59
+ /**
60
+ * Emit a plan_approved observation.
61
+ *
62
+ * @param service - KindlingService instance
63
+ * @param approval - Plan approval details
64
+ * @returns The plan_id
65
+ */
66
+ export declare function emitPlanApproved(service: KindlingService, approval: PlanApprovedInput): string;
67
+ /**
68
+ * Emit a plan_rejected observation.
69
+ *
70
+ * @param service - KindlingService instance
71
+ * @param rejection - Plan rejection details
72
+ * @returns The plan_id
73
+ */
74
+ export declare function emitPlanRejected(service: KindlingService, rejection: PlanRejectedInput): string;
75
+ //# sourceMappingURL=plan-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/plan-emitter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAe9D,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,GAAG,IAAI,GAAG,QAAQ,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,QAAQ,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,aAAa,GAAG,eAAe,GAAG,SAAS,CAAC;CAC9D;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAMD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAsBxF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,eAAe,GAAG,MAAM,CAsBtF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAmB9F;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,iBAAiB,GAAG,MAAM,CAmB/F"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Plan Emitter (KINDLING-006)
3
+ *
4
+ * Emits plan lifecycle observations: created, edited, approved, rejected.
5
+ * Plans are the governance artifacts that authorize actions.
6
+ */
7
+ import { randomUUID } from 'node:crypto';
8
+ import { createDebugger } from '../utils/debug.js';
9
+ const debug = createDebugger('kindling');
10
+ // =============================================================================
11
+ // Emitters
12
+ // =============================================================================
13
+ /**
14
+ * Emit a plan_created observation.
15
+ *
16
+ * If no plan_id is provided, one is generated.
17
+ *
18
+ * @param service - KindlingService instance
19
+ * @param plan - Plan creation details
20
+ * @returns The plan_id (generated or provided)
21
+ */
22
+ export function emitPlanCreated(service, plan) {
23
+ const planId = plan.plan_id ?? randomUUID();
24
+ debug('emitting plan_created', { planId, createdBy: plan.created_by });
25
+ const observation = {
26
+ kind: 'plan_created',
27
+ session_id: plan.session_id,
28
+ timestamp: new Date().toISOString(),
29
+ plan_id: planId,
30
+ plan_version: plan.plan_version,
31
+ plan_path: plan.plan_path,
32
+ plan_hash: plan.plan_hash,
33
+ created_by: plan.created_by,
34
+ source: plan.source,
35
+ };
36
+ // Fire-and-forget
37
+ service.emit(observation).catch(() => {
38
+ // Silently swallow
39
+ });
40
+ return planId;
41
+ }
42
+ /**
43
+ * Emit a plan_edited observation.
44
+ *
45
+ * @param service - KindlingService instance
46
+ * @param edit - Plan edit details
47
+ * @returns The plan_id
48
+ */
49
+ export function emitPlanEdited(service, edit) {
50
+ debug('emitting plan_edited', { planId: edit.plan_id, editedBy: edit.edited_by });
51
+ const observation = {
52
+ kind: 'plan_edited',
53
+ session_id: edit.session_id,
54
+ timestamp: new Date().toISOString(),
55
+ plan_id: edit.plan_id,
56
+ previous_version: edit.previous_version,
57
+ new_version: edit.new_version,
58
+ previous_hash: edit.previous_hash,
59
+ new_hash: edit.new_hash,
60
+ edited_by: edit.edited_by,
61
+ change_summary: edit.change_summary,
62
+ };
63
+ // Fire-and-forget
64
+ service.emit(observation).catch(() => {
65
+ // Silently swallow
66
+ });
67
+ return edit.plan_id;
68
+ }
69
+ /**
70
+ * Emit a plan_approved observation.
71
+ *
72
+ * @param service - KindlingService instance
73
+ * @param approval - Plan approval details
74
+ * @returns The plan_id
75
+ */
76
+ export function emitPlanApproved(service, approval) {
77
+ debug('emitting plan_approved', { planId: approval.plan_id, approvedBy: approval.approved_by });
78
+ const observation = {
79
+ kind: 'plan_approved',
80
+ session_id: approval.session_id,
81
+ timestamp: new Date().toISOString(),
82
+ plan_id: approval.plan_id,
83
+ plan_version: approval.plan_version,
84
+ approved_by: approval.approved_by,
85
+ approval_method: approval.approval_method,
86
+ };
87
+ // Fire-and-forget
88
+ service.emit(observation).catch(() => {
89
+ // Silently swallow
90
+ });
91
+ return approval.plan_id;
92
+ }
93
+ /**
94
+ * Emit a plan_rejected observation.
95
+ *
96
+ * @param service - KindlingService instance
97
+ * @param rejection - Plan rejection details
98
+ * @returns The plan_id
99
+ */
100
+ export function emitPlanRejected(service, rejection) {
101
+ debug('emitting plan_rejected', { planId: rejection.plan_id, rejectedBy: rejection.rejected_by });
102
+ const observation = {
103
+ kind: 'plan_rejected',
104
+ session_id: rejection.session_id,
105
+ timestamp: new Date().toISOString(),
106
+ plan_id: rejection.plan_id,
107
+ plan_version: rejection.plan_version,
108
+ rejected_by: rejection.rejected_by,
109
+ rejection_reason: rejection.rejection_reason,
110
+ };
111
+ // Fire-and-forget
112
+ service.emit(observation).catch(() => {
113
+ // Silently swallow
114
+ });
115
+ return rejection.plan_id;
116
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Session Emitter (KINDLING-003)
3
+ *
4
+ * Emits session_start and session_end observations.
5
+ * Sessions form the "spine" of Kindling -- every other observation
6
+ * is linked to a session via session_id.
7
+ */
8
+ import type { KindlingService } from '../kindling-service.js';
9
+ /**
10
+ * Context needed to start a session observation
11
+ */
12
+ export interface SessionStartContext {
13
+ working_directory: string;
14
+ git_ref?: string;
15
+ git_dirty?: boolean;
16
+ anvil_version: string;
17
+ command: string;
18
+ args: string[];
19
+ environment: 'development' | 'ci' | 'production' | 'unknown';
20
+ plan_id?: string;
21
+ }
22
+ /**
23
+ * Outcome data for ending a session
24
+ */
25
+ export interface SessionEndOutcome {
26
+ outcome: 'success' | 'failure' | 'partial' | 'cancelled';
27
+ exit_code: number;
28
+ duration_ms: number;
29
+ summary: {
30
+ gates_evaluated: number;
31
+ gates_passed: number;
32
+ gates_failed: number;
33
+ actions_executed: number;
34
+ errors_encountered: number;
35
+ };
36
+ }
37
+ /**
38
+ * Emit a session_start observation.
39
+ *
40
+ * Generates a new session_id and emits fire-and-forget.
41
+ * Returns the generated session_id so callers can link subsequent observations.
42
+ *
43
+ * @param service - KindlingService instance
44
+ * @param context - Session start context
45
+ * @returns The generated session_id
46
+ */
47
+ export declare function emitSessionStart(service: KindlingService, context: SessionStartContext): string;
48
+ /**
49
+ * Emit a session_end observation.
50
+ *
51
+ * @param service - KindlingService instance
52
+ * @param sessionId - The session_id from the corresponding session_start
53
+ * @param outcome - Session outcome data
54
+ * @returns The session_id (same as input, for chaining)
55
+ */
56
+ export declare function emitSessionEnd(service: KindlingService, sessionId: string, outcome: SessionEndOutcome): string;
57
+ //# sourceMappingURL=session-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/session-emitter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAU9D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,EAAE,aAAa,GAAG,IAAI,GAAG,YAAY,GAAG,SAAS,CAAC;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE;QACP,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAAC;CACH;AAMD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,mBAAmB,GAAG,MAAM,CA8B/F;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,iBAAiB,GACzB,MAAM,CAuBR"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Session Emitter (KINDLING-003)
3
+ *
4
+ * Emits session_start and session_end observations.
5
+ * Sessions form the "spine" of Kindling -- every other observation
6
+ * is linked to a session via session_id.
7
+ */
8
+ import { randomUUID } from 'node:crypto';
9
+ import { createDebugger } from '../utils/debug.js';
10
+ const debug = createDebugger('kindling');
11
+ // =============================================================================
12
+ // Emitters
13
+ // =============================================================================
14
+ /**
15
+ * Emit a session_start observation.
16
+ *
17
+ * Generates a new session_id and emits fire-and-forget.
18
+ * Returns the generated session_id so callers can link subsequent observations.
19
+ *
20
+ * @param service - KindlingService instance
21
+ * @param context - Session start context
22
+ * @returns The generated session_id
23
+ */
24
+ export function emitSessionStart(service, context) {
25
+ const sessionId = randomUUID();
26
+ debug('emitting session_start', {
27
+ sessionId,
28
+ command: context.command,
29
+ environment: context.environment,
30
+ });
31
+ const observation = {
32
+ kind: 'session_start',
33
+ session_id: sessionId,
34
+ timestamp: new Date().toISOString(),
35
+ context: {
36
+ working_directory: context.working_directory,
37
+ git_ref: context.git_ref,
38
+ git_dirty: context.git_dirty,
39
+ anvil_version: context.anvil_version,
40
+ command: context.command,
41
+ args: context.args,
42
+ environment: context.environment,
43
+ },
44
+ plan_id: context.plan_id,
45
+ };
46
+ // Fire-and-forget: catch errors silently to not affect main flow
47
+ service.emit(observation).catch(() => {
48
+ // Silently swallow -- Kindling must never break the host
49
+ });
50
+ return sessionId;
51
+ }
52
+ /**
53
+ * Emit a session_end observation.
54
+ *
55
+ * @param service - KindlingService instance
56
+ * @param sessionId - The session_id from the corresponding session_start
57
+ * @param outcome - Session outcome data
58
+ * @returns The session_id (same as input, for chaining)
59
+ */
60
+ export function emitSessionEnd(service, sessionId, outcome) {
61
+ debug('emitting session_end', {
62
+ sessionId,
63
+ outcome: outcome.outcome,
64
+ duration_ms: outcome.duration_ms,
65
+ });
66
+ const observation = {
67
+ kind: 'session_end',
68
+ session_id: sessionId,
69
+ timestamp: new Date().toISOString(),
70
+ outcome: outcome.outcome,
71
+ exit_code: outcome.exit_code,
72
+ duration_ms: outcome.duration_ms,
73
+ summary: outcome.summary,
74
+ };
75
+ // Fire-and-forget
76
+ service.emit(observation).catch(() => {
77
+ // Silently swallow
78
+ });
79
+ return sessionId;
80
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Kindling Integration (v1)
3
+ *
4
+ * This package provides the complete integration layer between Anvil and Kindling.
5
+ *
6
+ * Three surfaces:
7
+ *
8
+ * 1. Observation Contract (Write-Only)
9
+ * - 11 observation kinds covering session, plan, gate, action, constraint, human, error
10
+ * - Immutable, timestamped, linked facts
11
+ *
12
+ * 2. Query Contract (Read-Only)
13
+ * - 4 query scopes: session, plan, gate, action
14
+ * - Mandatory constraints, throttling, output guarantees
15
+ *
16
+ * 3. Service Layer (Orchestration)
17
+ * - KindlingService: validation, sensitive-data checks, store delegation
18
+ * - Emitters: fire-and-forget observation emission
19
+ * - KindlingQueryService: high-level query convenience methods
20
+ * - Configuration, retention, and query limit enforcement
21
+ *
22
+ * GOVERNING RULE:
23
+ * Kindling is a system of record, not a reasoning engine.
24
+ * Queries may retrieve facts; interpretation is the caller's responsibility.
25
+ *
26
+ * @packageDocumentation
27
+ */
28
+ export { OBSERVATION_CONTRACT_VERSION, SessionStartObservationSchema, SessionEndObservationSchema, PlanCreatedObservationSchema, PlanEditedObservationSchema, PlanApprovedObservationSchema, PlanRejectedObservationSchema, ActionExecutedObservationSchema, GateEvaluatedObservationSchema, ConstraintAppliedObservationSchema, HumanInputObservationSchema, ErrorObservationSchema, ObservationSchema, type SessionStartObservation, type SessionEndObservation, type PlanCreatedObservation, type PlanEditedObservation, type PlanApprovedObservation, type PlanRejectedObservation, type ActionExecutedObservation, type GateEvaluatedObservation, type ConstraintAppliedObservation, type HumanInputObservation, type ErrorObservation, type Observation, validateObservation, containsSensitiveData, } from './observation-contract.js';
29
+ export { KINDLING_QUERY_CONTRACT_VERSION, QueryScopeSchema, type QueryScope, ResultShapeSchema, type ResultShape, OutputFormatSchema, type OutputFormat, SessionQuerySchema, PlanQuerySchema, GateQuerySchema, ActionQuerySchema, QueryRequestSchema, QueryRequestBaseSchema, type QueryRequest, type QueryRequestBase, type SessionQuery, type PlanQuery, type GateQuery, type ActionQuery, QueryResponseSchema, QueryResponseMetadataSchema, ProvenanceLinkSchema, type QueryResponse, type QueryResponseMetadata, type ProvenanceLink, validateQueryRequest, validateQueryResponse, } from './query-contract.js';
30
+ export { ObservationSchema as QueryObservationSchema } from './query-contract.js';
31
+ export { KindlingConfigSchema, CaptureConfigSchema, RetentionConfigSchema, QueryLimitConfigSchema, type KindlingConfig, type CaptureConfig, type RetentionConfig, type QueryLimitConfig, DEFAULT_KINDLING_CONFIG, loadKindlingConfig, shouldCapture, } from './config.js';
32
+ export { type IKindlingStore, NoOpKindlingStore, KindlingService, ObservationValidationError, QueryValidationError, createKindlingService, } from './kindling-service.js';
33
+ export { validateNoSensitiveData, redactSensitiveFields, type SensitiveDataValidationResult, } from './sensitive-data-validator.js';
34
+ export { emitSessionStart, emitSessionEnd, type SessionStartContext, type SessionEndOutcome, emitGateEvaluated, type GateResult, emitActionExecuted, type ActionDetails, emitPlanCreated, emitPlanEdited, emitPlanApproved, emitPlanRejected, type PlanCreatedInput, type PlanEditedInput, type PlanApprovedInput, type PlanRejectedInput, emitHumanInput, type HumanInputDetails, emitConstraintApplied, type ConstraintDetails, emitError, type ErrorDetails, } from './emitters/index.js';
35
+ export { KindlingQueryService, type QueryOptions, type SessionQueryOptions, type PlanQueryOptions, type ActionQueryOptions, } from './query-service.js';
36
+ export { enforceQueryLimits, limitsFromConfig, type QueryLimits } from './query-limits.js';
37
+ export { type IRetentionCapableStore, type StorageStats, type PruneResult, isRetentionCapable, pruneOldObservations, getStorageStats, } from './retention.js';
38
+ export { getKindlingStatus, formatKindlingStatus, type KindlingStatus, type KindlingStatusConfig, type KindlingStatusStore, } from './status.js';
39
+ export { AnvilKindlingAdapter, type AnvilKindlingAdapterConfig } from './adapter.js';
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Kindling Integration (v1)
3
+ *
4
+ * This package provides the complete integration layer between Anvil and Kindling.
5
+ *
6
+ * Three surfaces:
7
+ *
8
+ * 1. Observation Contract (Write-Only)
9
+ * - 11 observation kinds covering session, plan, gate, action, constraint, human, error
10
+ * - Immutable, timestamped, linked facts
11
+ *
12
+ * 2. Query Contract (Read-Only)
13
+ * - 4 query scopes: session, plan, gate, action
14
+ * - Mandatory constraints, throttling, output guarantees
15
+ *
16
+ * 3. Service Layer (Orchestration)
17
+ * - KindlingService: validation, sensitive-data checks, store delegation
18
+ * - Emitters: fire-and-forget observation emission
19
+ * - KindlingQueryService: high-level query convenience methods
20
+ * - Configuration, retention, and query limit enforcement
21
+ *
22
+ * GOVERNING RULE:
23
+ * Kindling is a system of record, not a reasoning engine.
24
+ * Queries may retrieve facts; interpretation is the caller's responsibility.
25
+ *
26
+ * @packageDocumentation
27
+ */
28
+ // =============================================================================
29
+ // Observation Contract (Write-Only)
30
+ // =============================================================================
31
+ export {
32
+ // Version
33
+ OBSERVATION_CONTRACT_VERSION,
34
+ // Schemas (individual)
35
+ SessionStartObservationSchema, SessionEndObservationSchema, PlanCreatedObservationSchema, PlanEditedObservationSchema, PlanApprovedObservationSchema, PlanRejectedObservationSchema, ActionExecutedObservationSchema, GateEvaluatedObservationSchema, ConstraintAppliedObservationSchema, HumanInputObservationSchema, ErrorObservationSchema,
36
+ // Schema (union)
37
+ ObservationSchema,
38
+ // Utilities
39
+ validateObservation, containsSensitiveData, } from './observation-contract.js';
40
+ // =============================================================================
41
+ // Query Contract (Read-Only)
42
+ // =============================================================================
43
+ export {
44
+ // Version
45
+ KINDLING_QUERY_CONTRACT_VERSION,
46
+ // Query scopes
47
+ QueryScopeSchema,
48
+ // Result shape
49
+ ResultShapeSchema,
50
+ // Output format
51
+ OutputFormatSchema,
52
+ // Query requests (individual)
53
+ SessionQuerySchema, PlanQuerySchema, GateQuerySchema, ActionQuerySchema,
54
+ // Query request (union)
55
+ QueryRequestSchema, QueryRequestBaseSchema,
56
+ // Query response
57
+ QueryResponseSchema, QueryResponseMetadataSchema, ProvenanceLinkSchema,
58
+ // Utilities
59
+ validateQueryRequest, validateQueryResponse, } from './query-contract.js';
60
+ // Re-export Observation from query-contract for convenience
61
+ export { ObservationSchema as QueryObservationSchema } from './query-contract.js';
62
+ // =============================================================================
63
+ // Configuration (KINDLING-002)
64
+ // =============================================================================
65
+ export { KindlingConfigSchema, CaptureConfigSchema, RetentionConfigSchema, QueryLimitConfigSchema, DEFAULT_KINDLING_CONFIG, loadKindlingConfig, shouldCapture, } from './config.js';
66
+ // =============================================================================
67
+ // Service Layer (KINDLING-001)
68
+ // =============================================================================
69
+ export { NoOpKindlingStore, KindlingService, ObservationValidationError, QueryValidationError, createKindlingService, } from './kindling-service.js';
70
+ // =============================================================================
71
+ // Sensitive Data Validation (KINDLING-015)
72
+ // =============================================================================
73
+ export { validateNoSensitiveData, redactSensitiveFields, } from './sensitive-data-validator.js';
74
+ // =============================================================================
75
+ // Emitters (KINDLING-003 through 008)
76
+ // =============================================================================
77
+ export {
78
+ // Session
79
+ emitSessionStart, emitSessionEnd,
80
+ // Gate
81
+ emitGateEvaluated,
82
+ // Action
83
+ emitActionExecuted,
84
+ // Plan
85
+ emitPlanCreated, emitPlanEdited, emitPlanApproved, emitPlanRejected,
86
+ // Human Input
87
+ emitHumanInput,
88
+ // Constraint
89
+ emitConstraintApplied,
90
+ // Error
91
+ emitError, } from './emitters/index.js';
92
+ // =============================================================================
93
+ // Query Service (KINDLING-009)
94
+ // =============================================================================
95
+ export { KindlingQueryService, } from './query-service.js';
96
+ // =============================================================================
97
+ // Query Limits (KINDLING-010)
98
+ // =============================================================================
99
+ export { enforceQueryLimits, limitsFromConfig } from './query-limits.js';
100
+ // =============================================================================
101
+ // Retention (KINDLING-016)
102
+ // =============================================================================
103
+ export { isRetentionCapable, pruneOldObservations, getStorageStats, } from './retention.js';
104
+ // =============================================================================
105
+ // Status Utility (KINDLING-014)
106
+ // =============================================================================
107
+ export { getKindlingStatus, formatKindlingStatus, } from './status.js';
108
+ // =============================================================================
109
+ // Adapter (Anvil → Kindling Bridge)
110
+ // =============================================================================
111
+ export { AnvilKindlingAdapter } from './adapter.js';