@oscharko-dev/keiko-contracts 0.2.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 (227) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/bff-wire.d.ts +661 -0
  3. package/dist/bff-wire.d.ts.map +1 -0
  4. package/dist/bff-wire.js +102 -0
  5. package/dist/bug-investigation-events.d.ts +92 -0
  6. package/dist/bug-investigation-events.d.ts.map +1 -0
  7. package/dist/bug-investigation-events.js +18 -0
  8. package/dist/coding-context.d.ts +76 -0
  9. package/dist/coding-context.d.ts.map +1 -0
  10. package/dist/coding-context.js +158 -0
  11. package/dist/connected-context.d.ts +174 -0
  12. package/dist/connected-context.d.ts.map +1 -0
  13. package/dist/connected-context.js +636 -0
  14. package/dist/conversation-budget.d.ts +37 -0
  15. package/dist/conversation-budget.d.ts.map +1 -0
  16. package/dist/conversation-budget.js +97 -0
  17. package/dist/editor-agent.d.ts +131 -0
  18. package/dist/editor-agent.d.ts.map +1 -0
  19. package/dist/editor-agent.js +197 -0
  20. package/dist/editor-completion.d.ts +62 -0
  21. package/dist/editor-completion.d.ts.map +1 -0
  22. package/dist/editor-completion.js +147 -0
  23. package/dist/editor-dirty-close.d.ts +17 -0
  24. package/dist/editor-dirty-close.d.ts.map +1 -0
  25. package/dist/editor-dirty-close.js +8 -0
  26. package/dist/editor-hot-exit.d.ts +18 -0
  27. package/dist/editor-hot-exit.d.ts.map +1 -0
  28. package/dist/editor-hot-exit.js +42 -0
  29. package/dist/editor-inline-completion.d.ts +70 -0
  30. package/dist/editor-inline-completion.d.ts.map +1 -0
  31. package/dist/editor-inline-completion.js +215 -0
  32. package/dist/editor-layout.d.ts +105 -0
  33. package/dist/editor-layout.d.ts.map +1 -0
  34. package/dist/editor-layout.js +479 -0
  35. package/dist/editor-patch-apply.d.ts +77 -0
  36. package/dist/editor-patch-apply.d.ts.map +1 -0
  37. package/dist/editor-patch-apply.js +122 -0
  38. package/dist/editor-session.d.ts +31 -0
  39. package/dist/editor-session.d.ts.map +1 -0
  40. package/dist/editor-session.js +75 -0
  41. package/dist/editor-test-generation.d.ts +104 -0
  42. package/dist/editor-test-generation.d.ts.map +1 -0
  43. package/dist/editor-test-generation.js +211 -0
  44. package/dist/evaluations.d.ts +75 -0
  45. package/dist/evaluations.d.ts.map +1 -0
  46. package/dist/evaluations.js +16 -0
  47. package/dist/evidence.d.ts +297 -0
  48. package/dist/evidence.d.ts.map +1 -0
  49. package/dist/evidence.js +9 -0
  50. package/dist/gateway.d.ts +129 -0
  51. package/dist/gateway.d.ts.map +1 -0
  52. package/dist/gateway.js +66 -0
  53. package/dist/harness.d.ts +274 -0
  54. package/dist/harness.d.ts.map +1 -0
  55. package/dist/harness.js +38 -0
  56. package/dist/index.d.ts +101 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +83 -0
  59. package/dist/language-service.d.ts +145 -0
  60. package/dist/language-service.d.ts.map +1 -0
  61. package/dist/language-service.js +161 -0
  62. package/dist/local-knowledge-large-document-validation.d.ts +7 -0
  63. package/dist/local-knowledge-large-document-validation.d.ts.map +1 -0
  64. package/dist/local-knowledge-large-document-validation.js +161 -0
  65. package/dist/local-knowledge-large-document.d.ts +113 -0
  66. package/dist/local-knowledge-large-document.d.ts.map +1 -0
  67. package/dist/local-knowledge-large-document.js +142 -0
  68. package/dist/local-knowledge-paths.d.ts +3 -0
  69. package/dist/local-knowledge-paths.d.ts.map +1 -0
  70. package/dist/local-knowledge-paths.js +65 -0
  71. package/dist/local-knowledge-records.d.ts +190 -0
  72. package/dist/local-knowledge-records.d.ts.map +1 -0
  73. package/dist/local-knowledge-records.js +36 -0
  74. package/dist/local-knowledge-schema-validation.d.ts +19 -0
  75. package/dist/local-knowledge-schema-validation.d.ts.map +1 -0
  76. package/dist/local-knowledge-schema-validation.js +115 -0
  77. package/dist/local-knowledge-schema.d.ts +14 -0
  78. package/dist/local-knowledge-schema.d.ts.map +1 -0
  79. package/dist/local-knowledge-schema.js +715 -0
  80. package/dist/local-knowledge-validation.d.ts +20 -0
  81. package/dist/local-knowledge-validation.d.ts.map +1 -0
  82. package/dist/local-knowledge-validation.js +487 -0
  83. package/dist/local-knowledge.d.ts +158 -0
  84. package/dist/local-knowledge.d.ts.map +1 -0
  85. package/dist/local-knowledge.js +63 -0
  86. package/dist/memory-audit-events.d.ts +73 -0
  87. package/dist/memory-audit-events.d.ts.map +1 -0
  88. package/dist/memory-audit-events.js +44 -0
  89. package/dist/memory-audit-validation.d.ts +4 -0
  90. package/dist/memory-audit-validation.d.ts.map +1 -0
  91. package/dist/memory-audit-validation.js +151 -0
  92. package/dist/memory-barrel.d.ts +15 -0
  93. package/dist/memory-barrel.d.ts.map +1 -0
  94. package/dist/memory-barrel.js +20 -0
  95. package/dist/memory-internal.d.ts +26 -0
  96. package/dist/memory-internal.d.ts.map +1 -0
  97. package/dist/memory-internal.js +104 -0
  98. package/dist/memory-operations-validation.d.ts +12 -0
  99. package/dist/memory-operations-validation.d.ts.map +1 -0
  100. package/dist/memory-operations-validation.js +267 -0
  101. package/dist/memory-operations.d.ts +156 -0
  102. package/dist/memory-operations.d.ts.map +1 -0
  103. package/dist/memory-operations.js +29 -0
  104. package/dist/memory-record-validation.d.ts +10 -0
  105. package/dist/memory-record-validation.d.ts.map +1 -0
  106. package/dist/memory-record-validation.js +101 -0
  107. package/dist/memory-records.d.ts +66 -0
  108. package/dist/memory-records.d.ts.map +1 -0
  109. package/dist/memory-records.js +22 -0
  110. package/dist/memory-retrieval-validation.d.ts +6 -0
  111. package/dist/memory-retrieval-validation.d.ts.map +1 -0
  112. package/dist/memory-retrieval-validation.js +108 -0
  113. package/dist/memory-validation.d.ts +31 -0
  114. package/dist/memory-validation.d.ts.map +1 -0
  115. package/dist/memory-validation.js +318 -0
  116. package/dist/memory-workflow-port.d.ts +26 -0
  117. package/dist/memory-workflow-port.d.ts.map +1 -0
  118. package/dist/memory-workflow-port.js +13 -0
  119. package/dist/memory.d.ts +81 -0
  120. package/dist/memory.d.ts.map +1 -0
  121. package/dist/memory.js +104 -0
  122. package/dist/prompt-enhancer-analyzer.d.ts +7 -0
  123. package/dist/prompt-enhancer-analyzer.d.ts.map +1 -0
  124. package/dist/prompt-enhancer-analyzer.js +745 -0
  125. package/dist/prompt-enhancer-bff.d.ts +67 -0
  126. package/dist/prompt-enhancer-bff.d.ts.map +1 -0
  127. package/dist/prompt-enhancer-bff.js +156 -0
  128. package/dist/prompt-enhancer-critic.d.ts +46 -0
  129. package/dist/prompt-enhancer-critic.d.ts.map +1 -0
  130. package/dist/prompt-enhancer-critic.js +35 -0
  131. package/dist/prompt-enhancer-grounding.d.ts +19 -0
  132. package/dist/prompt-enhancer-grounding.d.ts.map +1 -0
  133. package/dist/prompt-enhancer-grounding.js +235 -0
  134. package/dist/prompt-enhancer-safety.d.ts +66 -0
  135. package/dist/prompt-enhancer-safety.d.ts.map +1 -0
  136. package/dist/prompt-enhancer-safety.js +446 -0
  137. package/dist/prompt-enhancer-validation.d.ts +28 -0
  138. package/dist/prompt-enhancer-validation.d.ts.map +1 -0
  139. package/dist/prompt-enhancer-validation.js +931 -0
  140. package/dist/prompt-enhancer.d.ts +184 -0
  141. package/dist/prompt-enhancer.d.ts.map +1 -0
  142. package/dist/prompt-enhancer.js +350 -0
  143. package/dist/qualityIntelligence/assertNever.d.ts +2 -0
  144. package/dist/qualityIntelligence/assertNever.d.ts.map +1 -0
  145. package/dist/qualityIntelligence/assertNever.js +7 -0
  146. package/dist/qualityIntelligence/auditSummary.d.ts +25 -0
  147. package/dist/qualityIntelligence/auditSummary.d.ts.map +1 -0
  148. package/dist/qualityIntelligence/auditSummary.js +7 -0
  149. package/dist/qualityIntelligence/bffWire.d.ts +356 -0
  150. package/dist/qualityIntelligence/bffWire.d.ts.map +1 -0
  151. package/dist/qualityIntelligence/bffWire.js +22 -0
  152. package/dist/qualityIntelligence/coverageMap.d.ts +21 -0
  153. package/dist/qualityIntelligence/coverageMap.d.ts.map +1 -0
  154. package/dist/qualityIntelligence/coverageMap.js +29 -0
  155. package/dist/qualityIntelligence/editableRevision.d.ts +21 -0
  156. package/dist/qualityIntelligence/editableRevision.d.ts.map +1 -0
  157. package/dist/qualityIntelligence/editableRevision.js +8 -0
  158. package/dist/qualityIntelligence/evidenceAtom.d.ts +35 -0
  159. package/dist/qualityIntelligence/evidenceAtom.d.ts.map +1 -0
  160. package/dist/qualityIntelligence/evidenceAtom.js +29 -0
  161. package/dist/qualityIntelligence/exportBundle.d.ts +28 -0
  162. package/dist/qualityIntelligence/exportBundle.d.ts.map +1 -0
  163. package/dist/qualityIntelligence/exportBundle.js +46 -0
  164. package/dist/qualityIntelligence/handoffEnvelope.d.ts +23 -0
  165. package/dist/qualityIntelligence/handoffEnvelope.d.ts.map +1 -0
  166. package/dist/qualityIntelligence/handoffEnvelope.js +8 -0
  167. package/dist/qualityIntelligence/ids.d.ts +58 -0
  168. package/dist/qualityIntelligence/ids.d.ts.map +1 -0
  169. package/dist/qualityIntelligence/ids.js +93 -0
  170. package/dist/qualityIntelligence/index.d.ts +29 -0
  171. package/dist/qualityIntelligence/index.d.ts.map +1 -0
  172. package/dist/qualityIntelligence/index.js +20 -0
  173. package/dist/qualityIntelligence/reviewRecord.d.ts +19 -0
  174. package/dist/qualityIntelligence/reviewRecord.d.ts.map +1 -0
  175. package/dist/qualityIntelligence/reviewRecord.js +20 -0
  176. package/dist/qualityIntelligence/runPlanAndEvents.d.ts +84 -0
  177. package/dist/qualityIntelligence/runPlanAndEvents.d.ts.map +1 -0
  178. package/dist/qualityIntelligence/runPlanAndEvents.js +51 -0
  179. package/dist/qualityIntelligence/sourceEnvelope.d.ts +77 -0
  180. package/dist/qualityIntelligence/sourceEnvelope.d.ts.map +1 -0
  181. package/dist/qualityIntelligence/sourceEnvelope.js +118 -0
  182. package/dist/qualityIntelligence/testCaseCandidate.d.ts +21 -0
  183. package/dist/qualityIntelligence/testCaseCandidate.d.ts.map +1 -0
  184. package/dist/qualityIntelligence/testCaseCandidate.js +21 -0
  185. package/dist/qualityIntelligence/testQualityRubric.d.ts +17 -0
  186. package/dist/qualityIntelligence/testQualityRubric.d.ts.map +1 -0
  187. package/dist/qualityIntelligence/testQualityRubric.js +32 -0
  188. package/dist/qualityIntelligence/validationFinding.d.ts +48 -0
  189. package/dist/qualityIntelligence/validationFinding.d.ts.map +1 -0
  190. package/dist/qualityIntelligence/validationFinding.js +36 -0
  191. package/dist/relationships-validation.d.ts +13 -0
  192. package/dist/relationships-validation.d.ts.map +1 -0
  193. package/dist/relationships-validation.js +422 -0
  194. package/dist/relationships.d.ts +79 -0
  195. package/dist/relationships.d.ts.map +1 -0
  196. package/dist/relationships.js +307 -0
  197. package/dist/text-safety.d.ts +7 -0
  198. package/dist/text-safety.d.ts.map +1 -0
  199. package/dist/text-safety.js +58 -0
  200. package/dist/tools.d.ts +153 -0
  201. package/dist/tools.d.ts.map +1 -0
  202. package/dist/tools.js +118 -0
  203. package/dist/unit-test-events.d.ts +87 -0
  204. package/dist/unit-test-events.d.ts.map +1 -0
  205. package/dist/unit-test-events.js +14 -0
  206. package/dist/verification-summary.d.ts +38 -0
  207. package/dist/verification-summary.d.ts.map +1 -0
  208. package/dist/verification-summary.js +5 -0
  209. package/dist/verification.d.ts +64 -0
  210. package/dist/verification.d.ts.map +1 -0
  211. package/dist/verification.js +13 -0
  212. package/dist/workflow-descriptor.d.ts +21 -0
  213. package/dist/workflow-descriptor.d.ts.map +1 -0
  214. package/dist/workflow-descriptor.js +8 -0
  215. package/dist/workflow-handoff.d.ts +69 -0
  216. package/dist/workflow-handoff.d.ts.map +1 -0
  217. package/dist/workflow-handoff.js +381 -0
  218. package/dist/workspace-descriptors.d.ts +21 -0
  219. package/dist/workspace-descriptors.d.ts.map +1 -0
  220. package/dist/workspace-descriptors.js +180 -0
  221. package/dist/workspace-ui.d.ts +119 -0
  222. package/dist/workspace-ui.d.ts.map +1 -0
  223. package/dist/workspace-ui.js +105 -0
  224. package/dist/workspace.d.ts +104 -0
  225. package/dist/workspace.d.ts.map +1 -0
  226. package/dist/workspace.js +27 -0
  227. package/package.json +71 -0
@@ -0,0 +1,307 @@
1
+ // Public type contracts for the Keiko relationship engine (Epic #532, Issue #538).
2
+ //
3
+ // Pure types and frozen constant tables only — no IO, no clock reads, no hashing, no
4
+ // randomness, no filesystem access. Leaf-package rule (ADR-0019 direction 1): no
5
+ // `@oscharko-dev/keiko-*` imports may appear in this module. The schemaVersion discriminant
6
+ // follows the same evolution rule as MEMORY_AUDIT_EVENT_SCHEMA_VERSION and
7
+ // LOCAL_KNOWLEDGE_SCHEMA_VERSION: a breaking change introduces a NEW literal member rather
8
+ // than mutating "1".
9
+ //
10
+ // Foundations: docs/relationship-engine/taxonomy.md (object kinds, relationship types,
11
+ // per-type metadata), docs/relationship-engine/compatibility-matrix.md (source × target
12
+ // pairs), docs/relationship-engine/denial-reasons.md (the 18-code catalog and resolution
13
+ // order), docs/relationship-engine/lifecycle.md (the 7-state machine), and
14
+ // docs/relationship-engine/activity-state.md (the 9 transient activity states derived from
15
+ // existing event streams — durable on the lifecycle column, never persisted on their own).
16
+ //
17
+ // The relationship record is BODY-FREE by construction (taxonomy.md §12, audit-events.md
18
+ // §8.3). The `metadata` bag is a `Readonly<Record<string, unknown>>` so callers may attach
19
+ // non-sensitive structural hints; the deterministic validator (relationships-validation.ts)
20
+ // rejects forbidden keys outright so a client never accidentally smuggles a prompt or
21
+ // document excerpt past the redactor.
22
+ // ─── Schema version ───────────────────────────────────────────────────────────
23
+ export const RELATIONSHIP_SCHEMA_VERSION = "1";
24
+ // ─── Object kinds ─────────────────────────────────────────────────────────────
25
+ // Closed enumeration of the 14 object kinds a relationship endpoint may carry. The order
26
+ // of this tuple matches the column order of compatibility-matrix.md §2 (alphabetical,
27
+ // ignoring the forward-looking suffix) so test fixtures can iterate deterministically.
28
+ export const RELATIONSHIP_OBJECT_KINDS = [
29
+ "agent",
30
+ "capsule",
31
+ "capsule-set",
32
+ "chat",
33
+ "connector",
34
+ "data-source",
35
+ "evidence-run",
36
+ "mcp-tool",
37
+ "memory",
38
+ "patch-proposal",
39
+ "skill",
40
+ "tool",
41
+ "workflow-run",
42
+ "workspace-path",
43
+ ];
44
+ // Kinds the relationship engine accepts TODAY. Forward-looking kinds (agent, connector,
45
+ // data-source, skill, mcp-tool) are members of RELATIONSHIP_OBJECT_KINDS so the schema is
46
+ // stable when their owning registries land (taxonomy.md §4.2), but the validator rejects
47
+ // proposals naming them with `denied/object-kind-not-yet-supported`.
48
+ export const RELATIONSHIP_SUPPORTED_OBJECT_KINDS = [
49
+ "capsule",
50
+ "capsule-set",
51
+ "chat",
52
+ "evidence-run",
53
+ "memory",
54
+ "patch-proposal",
55
+ "tool",
56
+ "workflow-run",
57
+ "workspace-path",
58
+ ];
59
+ // ─── Relationship types ───────────────────────────────────────────────────────
60
+ // Closed enumeration of the seven relationship types (taxonomy.md §5.8). Order matches
61
+ // the taxonomy's section ordering so reviewers can cross-walk the table.
62
+ export const RELATIONSHIP_TYPES = [
63
+ "reads-context",
64
+ "proposes-patch",
65
+ "uses-tool",
66
+ "starts-workflow",
67
+ "produces-evidence",
68
+ "references-document",
69
+ "depends-on",
70
+ ];
71
+ // ─── Lifecycle states ─────────────────────────────────────────────────────────
72
+ // Closed enumeration of durable lifecycle states (lifecycle.md §1; taxonomy.md §6.1).
73
+ export const RELATIONSHIP_LIFECYCLE_STATES = [
74
+ "draft",
75
+ "active",
76
+ "archived",
77
+ "superseded",
78
+ "revoked",
79
+ "blocked",
80
+ "stale",
81
+ ];
82
+ // ─── Activity states (transient, in-memory derived) ───────────────────────────
83
+ // The nine transient activity states from activity-state.md §2. These are NOT persisted
84
+ // on the relationship record; the lifecycle column is durable, this enumeration powers
85
+ // the inspector / graph overlays only. Surfaced here so downstream UI code can pin
86
+ // against a stable closed set in `@oscharko-dev/keiko-contracts`.
87
+ export const RELATIONSHIP_ACTIVITY_STATES = [
88
+ "inactive",
89
+ "queued",
90
+ "active",
91
+ "processing",
92
+ "completed",
93
+ "failed",
94
+ "blocked",
95
+ "degraded",
96
+ "high-throughput",
97
+ ];
98
+ // ─── Denial codes ─────────────────────────────────────────────────────────────
99
+ // Closed enumeration of the 18 denial codes (denial-reasons.md §"Catalog"). Tuple order
100
+ // matches the normative "Resolution order" so the validator and reviewers can keep the
101
+ // two views in lock-step. Adding a new code follows the additive-evolution rule from
102
+ // taxonomy.md §3.2 (append, document in denial-reasons.md, slot into resolution order).
103
+ export const RELATIONSHIP_DENIAL_CODES = [
104
+ "denied/non-existent-source",
105
+ "denied/non-existent-target",
106
+ "denied/object-kind-not-yet-supported",
107
+ "denied/source-kind-not-allowed",
108
+ "denied/target-kind-not-allowed",
109
+ "denied/kind-incompatible",
110
+ "denied/cardinality-exceeded",
111
+ "denied/cycle-forbidden",
112
+ "denied/cross-workspace",
113
+ "denied/path-not-contained",
114
+ "denied/denied-by-deny-list",
115
+ "denied/lifecycle-illegal-transition",
116
+ "denied/endpoint-tombstoned",
117
+ "denied/endpoint-retired",
118
+ "denied/endpoint-unavailable",
119
+ "denied/payload-content-not-permitted",
120
+ "denied/authority-insufficient",
121
+ "denied/schema-version-unsupported",
122
+ ];
123
+ // The seven definitions (taxonomy.md §5.1 — §5.7). Kept verbose so a future reader does
124
+ // not need to round-trip through the markdown to understand the contract.
125
+ export const RELATIONSHIP_TYPE_DEFINITIONS = {
126
+ "reads-context": {
127
+ id: "reads-context",
128
+ displayName: "reads context",
129
+ semantics: "A consumer endpoint reads the contextual content of the target at a specific point in time.",
130
+ validSourceKinds: ["workflow-run", "chat"],
131
+ validTargetKinds: [
132
+ "memory",
133
+ "capsule",
134
+ "capsule-set",
135
+ "evidence-run",
136
+ "workspace-path",
137
+ "connector",
138
+ "data-source",
139
+ ],
140
+ cardinality: "N:N",
141
+ direction: "directed",
142
+ lifecycle: {
143
+ creatable: true,
144
+ immutable: true,
145
+ reconnectable: false,
146
+ deletable: false,
147
+ archivable: true,
148
+ },
149
+ auditEventOnMutation: true,
150
+ evidenceRelevance: "reference",
151
+ ownerPackage: "@oscharko-dev/keiko-workflows",
152
+ trustBoundary: "per-endpoint",
153
+ },
154
+ "proposes-patch": {
155
+ id: "proposes-patch",
156
+ displayName: "proposes patch",
157
+ semantics: "A workflow run proposes a patch against one or more workspace paths. The relationship records the proposal; diff content stays in the harness PatchProposedEvent.",
158
+ validSourceKinds: ["workflow-run"],
159
+ validTargetKinds: ["workspace-path", "patch-proposal"],
160
+ cardinality: "1:N",
161
+ direction: "directed",
162
+ lifecycle: {
163
+ creatable: true,
164
+ immutable: true,
165
+ reconnectable: false,
166
+ deletable: true,
167
+ archivable: true,
168
+ },
169
+ auditEventOnMutation: true,
170
+ evidenceRelevance: "reference",
171
+ ownerPackage: "@oscharko-dev/keiko-workflows",
172
+ trustBoundary: "fs",
173
+ },
174
+ "uses-tool": {
175
+ id: "uses-tool",
176
+ displayName: "uses tool",
177
+ semantics: "A workflow run uses a registered tool. Per-call arguments and results remain in the harness ToolCallRequest / ToolCallResult envelopes.",
178
+ validSourceKinds: ["workflow-run"],
179
+ validTargetKinds: ["tool", "mcp-tool"],
180
+ cardinality: "N:N",
181
+ direction: "directed",
182
+ lifecycle: {
183
+ creatable: true,
184
+ immutable: true,
185
+ reconnectable: false,
186
+ deletable: false,
187
+ archivable: true,
188
+ },
189
+ auditEventOnMutation: true,
190
+ evidenceRelevance: "reference",
191
+ ownerPackage: "@oscharko-dev/keiko-workflows",
192
+ trustBoundary: "tool",
193
+ },
194
+ "starts-workflow": {
195
+ id: "starts-workflow",
196
+ displayName: "starts workflow",
197
+ semantics: "A chat or a parent workflow run initiates a workflow run. The relationship records the origin; run identity belongs to the workflow ledger.",
198
+ validSourceKinds: ["chat", "workflow-run"],
199
+ validTargetKinds: ["workflow-run"],
200
+ // The exported cardinality is source-centric for UI display and contract summaries:
201
+ // one chat / parent run may start many runs over time. The validator still enforces
202
+ // the target-side 1:1 invariant separately via startsWorkflowForTarget.
203
+ cardinality: "1:N",
204
+ direction: "directed",
205
+ lifecycle: {
206
+ creatable: true,
207
+ immutable: true,
208
+ reconnectable: false,
209
+ deletable: false,
210
+ archivable: true,
211
+ },
212
+ auditEventOnMutation: true,
213
+ evidenceRelevance: "reference",
214
+ ownerPackage: "@oscharko-dev/keiko-workflows",
215
+ trustBoundary: "per-endpoint",
216
+ },
217
+ "produces-evidence": {
218
+ id: "produces-evidence",
219
+ displayName: "produces evidence",
220
+ semantics: "A workflow run produces exactly one durable evidence-run record. If a run produces no evidence, no relationship is recorded.",
221
+ validSourceKinds: ["workflow-run"],
222
+ validTargetKinds: ["evidence-run"],
223
+ cardinality: "1:1",
224
+ direction: "directed",
225
+ lifecycle: {
226
+ creatable: true,
227
+ immutable: true,
228
+ reconnectable: false,
229
+ deletable: false,
230
+ archivable: true,
231
+ },
232
+ auditEventOnMutation: true,
233
+ evidenceRelevance: "produces",
234
+ ownerPackage: "@oscharko-dev/keiko-evidence",
235
+ trustBoundary: "evidence",
236
+ },
237
+ "references-document": {
238
+ id: "references-document",
239
+ displayName: "references document",
240
+ semantics: "A chat or workflow run holds a structural pointer to a document (workspace file or local-knowledge capsule). Distinct from reads-context: a reference is structural, a read is an event.",
241
+ validSourceKinds: ["chat", "workflow-run"],
242
+ validTargetKinds: ["workspace-path", "capsule", "capsule-set"],
243
+ cardinality: "N:N",
244
+ direction: "directed",
245
+ lifecycle: {
246
+ creatable: true,
247
+ immutable: false,
248
+ reconnectable: true,
249
+ deletable: true,
250
+ archivable: true,
251
+ },
252
+ auditEventOnMutation: true,
253
+ evidenceRelevance: "reference",
254
+ ownerPackage: "@oscharko-dev/keiko-workflows",
255
+ trustBoundary: "per-endpoint",
256
+ },
257
+ "depends-on": {
258
+ id: "depends-on",
259
+ displayName: "depends on",
260
+ semantics: "A capsule, capsule-set, workflow run, or memory depends on another. Used by impact analysis (#542). Self-loops and direct two-edge cycles are forbidden at validation time; transitive cycle detection is deferred to impact traversal.",
261
+ validSourceKinds: ["capsule", "capsule-set", "workflow-run", "memory"],
262
+ validTargetKinds: [
263
+ "capsule",
264
+ "capsule-set",
265
+ "workflow-run",
266
+ "memory",
267
+ "evidence-run",
268
+ "workspace-path",
269
+ ],
270
+ cardinality: "N:N",
271
+ direction: "directed",
272
+ lifecycle: {
273
+ creatable: true,
274
+ immutable: false,
275
+ reconnectable: true,
276
+ deletable: true,
277
+ archivable: true,
278
+ },
279
+ auditEventOnMutation: true,
280
+ evidenceRelevance: "reference",
281
+ ownerPackage: "@oscharko-dev/keiko-contracts",
282
+ trustBoundary: "per-endpoint",
283
+ },
284
+ };
285
+ // ─── Forbidden-payload key list ───────────────────────────────────────────────
286
+ // The deterministic validator rejects any metadata key whose lowercase form contains
287
+ // one of these substrings. The list mirrors audit-events.md §8.3 (raw prompts, model
288
+ // output text, document content, tool stdout/stderr, patch bodies, secrets, credentials)
289
+ // reduced to the smallest set of token-substrings a payload object would carry. The
290
+ // redactor at `packages/keiko-security/src/redaction.ts` runs at the persist boundary;
291
+ // this list lets the validator reject upstream so the operator sees the rejection
292
+ // rather than a silent redaction (denial-reasons.md `denied/payload-content-not-permitted`).
293
+ //
294
+ // Case-insensitive substring match: e.g. "promptText" → matches "prompt", "ApiKey" →
295
+ // matches "apikey", "rawDocumentContent" → matches "documentcontent".
296
+ export const RELATIONSHIP_FORBIDDEN_METADATA_KEY_SUBSTRINGS = [
297
+ "prompt",
298
+ "documentcontent",
299
+ "filecontent",
300
+ "toolstdout",
301
+ "toolstderr",
302
+ "secret",
303
+ "credential",
304
+ "apikey",
305
+ "password",
306
+ "token",
307
+ ];
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Remove Unicode bidi/zero-width/BOM/format spoofing code points and C0/C1/DEL control
3
+ * characters from `value`, preserving TAB/LF/CR. Pure; returns the input unchanged (a no-op,
4
+ * byte-identical) when it contains no unsafe code points.
5
+ */
6
+ export declare function stripUnsafeFormatChars(value: string): string;
7
+ //# sourceMappingURL=text-safety.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-safety.d.ts","sourceRoot":"","sources":["../src/text-safety.ts"],"names":[],"mappings":"AAoCA;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAkB5D"}
@@ -0,0 +1,58 @@
1
+ // Shared text-safety primitive (Epic #177/#189 grounding hardening, GRD-001).
2
+ //
3
+ // Removes Unicode code points that are invisible or that can reorder a display surface's
4
+ // reading order ("Trojan-source" class) plus C0/C1/DEL control characters. Untrusted
5
+ // repository / document evidence flows into (a) the LLM prompt — where reordered or hidden
6
+ // instructions can subvert the answer — and (b) the browser-rendered answer/citation wire —
7
+ // where React escapes HTML but NOT bidi reordering. Stripping at the surface chokepoints
8
+ // (excerpt → prompt/wire) neutralises both without touching persisted offsets.
9
+ //
10
+ // Whitespace policy: TAB (U+0009), LF (U+000A), and CR (U+000D) are preserved so legitimate
11
+ // formatting of evidence survives; every other control code point is removed.
12
+ //
13
+ // This lives in keiko-contracts (the base layer) so both keiko-local-knowledge and
14
+ // keiko-server can compose it; it mirrors the QI-domain `stripUnsafeFormatChars` without
15
+ // creating a dependency on the QI package.
16
+ // True for an invisible / text-reordering code point: bidi override/embedding/isolate,
17
+ // zero-width joiners, BOM, LRM/RLM, and the Arabic letter mark. Numeric scan keeps the set
18
+ // auditable and avoids embedding invisible literals in the source.
19
+ function isBidiOrZeroWidthCodePoint(cp) {
20
+ return (cp === 0x061c ||
21
+ (cp >= 0x200b && cp <= 0x200f) ||
22
+ (cp >= 0x202a && cp <= 0x202e) ||
23
+ (cp >= 0x2066 && cp <= 0x2069) ||
24
+ cp === 0xfeff);
25
+ }
26
+ // True for a C0 control (0x00–0x1F) or DEL/C1 control (0x7F–0x9F), EXCEPT TAB/LF/CR which
27
+ // are legitimate whitespace and preserved.
28
+ function isStrippableControlCodePoint(cp) {
29
+ if (cp === 0x09 || cp === 0x0a || cp === 0x0d)
30
+ return false;
31
+ return cp <= 0x1f || (cp >= 0x7f && cp <= 0x9f);
32
+ }
33
+ /**
34
+ * Remove Unicode bidi/zero-width/BOM/format spoofing code points and C0/C1/DEL control
35
+ * characters from `value`, preserving TAB/LF/CR. Pure; returns the input unchanged (a no-op,
36
+ * byte-identical) when it contains no unsafe code points.
37
+ */
38
+ export function stripUnsafeFormatChars(value) {
39
+ // Fast path: scan once; only allocate a rebuilt string if something must be removed.
40
+ let needsStrip = false;
41
+ for (const ch of value) {
42
+ const cp = ch.codePointAt(0) ?? 0;
43
+ if (isBidiOrZeroWidthCodePoint(cp) || isStrippableControlCodePoint(cp)) {
44
+ needsStrip = true;
45
+ break;
46
+ }
47
+ }
48
+ if (!needsStrip)
49
+ return value;
50
+ let out = "";
51
+ for (const ch of value) {
52
+ const cp = ch.codePointAt(0) ?? 0;
53
+ if (isBidiOrZeroWidthCodePoint(cp) || isStrippableControlCodePoint(cp))
54
+ continue;
55
+ out += ch;
56
+ }
57
+ return out;
58
+ }
@@ -0,0 +1,153 @@
1
+ import type { ToolDefinition } from "./gateway.js";
2
+ export type NetworkPolicy = "inherit" | "none";
3
+ export type FilesystemPolicy = "inherit" | "execution-root";
4
+ export interface SandboxPolicy {
5
+ readonly envAllowlist: readonly string[];
6
+ readonly network: NetworkPolicy;
7
+ readonly filesystem?: FilesystemPolicy | undefined;
8
+ readonly maxOutputBytes: number;
9
+ readonly defaultTimeoutMs: number;
10
+ readonly terminationGraceMs: number;
11
+ }
12
+ export declare const DEFAULT_ENV_ALLOWLIST: readonly string[];
13
+ export declare const DEFAULT_SANDBOX_POLICY: SandboxPolicy;
14
+ export type SandboxBackend = "bubblewrap" | "unshare" | "seatbelt" | "container-docker" | "container-podman" | "none";
15
+ export declare const SANDBOX_BACKENDS: readonly SandboxBackend[];
16
+ export interface SandboxAttestation {
17
+ readonly backend: SandboxBackend;
18
+ readonly networkEnforced: boolean;
19
+ readonly filesystemEnforced: boolean;
20
+ readonly platform: string;
21
+ }
22
+ export interface CommandRule {
23
+ readonly executable: string;
24
+ readonly allowedSubcommands?: readonly string[] | undefined;
25
+ readonly deniedSubcommands?: readonly string[] | undefined;
26
+ readonly valueFlags?: readonly string[] | undefined;
27
+ readonly requiredLeadingFlags?: readonly string[] | undefined;
28
+ readonly denyFlags?: readonly string[] | undefined;
29
+ readonly knownSubcommands?: readonly string[] | undefined;
30
+ }
31
+ export declare const DEFAULT_COMMAND_RULES: readonly CommandRule[];
32
+ export interface CommandRunInput {
33
+ readonly command: string;
34
+ readonly args?: readonly string[] | undefined;
35
+ readonly cwd?: string | undefined;
36
+ readonly timeoutMs?: number | undefined;
37
+ readonly signal: AbortSignal;
38
+ }
39
+ export interface CommandResult {
40
+ readonly command: string;
41
+ readonly args: readonly string[];
42
+ readonly exitCode: number | null;
43
+ readonly signal: string | null;
44
+ readonly stdout: string;
45
+ readonly stderr: string;
46
+ readonly durationMs: number;
47
+ readonly timedOut: boolean;
48
+ readonly truncated: boolean;
49
+ readonly attestation?: SandboxAttestation | undefined;
50
+ }
51
+ export type PatchChangeKind = "create" | "modify" | "delete";
52
+ export interface PatchHunk {
53
+ readonly oldStart: number;
54
+ readonly oldLines: number;
55
+ readonly newStart: number;
56
+ readonly newLines: number;
57
+ readonly lines: readonly string[];
58
+ }
59
+ export interface PatchFileChange {
60
+ readonly path: string;
61
+ readonly kind: PatchChangeKind;
62
+ readonly hunks: readonly PatchHunk[];
63
+ readonly addedLines: number;
64
+ readonly removedLines: number;
65
+ }
66
+ export type PatchRejectionCode = "size-limit" | "binary" | "path-unsafe" | "path-denied" | "line-limit" | "file-limit" | "malformed";
67
+ export interface PatchRejection {
68
+ readonly code: PatchRejectionCode;
69
+ readonly message: string;
70
+ readonly path?: string | undefined;
71
+ }
72
+ export interface PatchConflict {
73
+ readonly path: string;
74
+ readonly hunkIndex: number;
75
+ readonly reason: string;
76
+ }
77
+ export interface PatchValidation {
78
+ readonly ok: boolean;
79
+ readonly files: readonly PatchFileChange[];
80
+ readonly totalChangedLines: number;
81
+ readonly totalBytes: number;
82
+ readonly normalizedDiff?: string | undefined;
83
+ readonly reasons: readonly PatchRejection[];
84
+ readonly conflicts: readonly PatchConflict[];
85
+ }
86
+ export interface PatchLimits {
87
+ readonly maxPatchBytes: number;
88
+ readonly maxChangedLines: number;
89
+ readonly maxFilesChanged: number;
90
+ }
91
+ export declare const DEFAULT_PATCH_LIMITS: PatchLimits;
92
+ export interface PatchApplyResult {
93
+ readonly changedFiles: readonly string[];
94
+ readonly created: readonly string[];
95
+ readonly deleted: readonly string[];
96
+ }
97
+ export interface ToolHostConfig {
98
+ readonly sandbox: SandboxPolicy;
99
+ readonly commandRules: readonly CommandRule[];
100
+ readonly patchLimits: PatchLimits;
101
+ readonly applyEnabled: boolean;
102
+ readonly maxReadBytes: number;
103
+ }
104
+ export declare const DEFAULT_TOOL_HOST_CONFIG: ToolHostConfig;
105
+ export interface ToolHostConfigInput {
106
+ readonly sandbox?: Partial<SandboxPolicy> | undefined;
107
+ readonly commandRules?: readonly CommandRule[] | undefined;
108
+ readonly patchLimits?: Partial<PatchLimits> | undefined;
109
+ readonly applyEnabled?: boolean | undefined;
110
+ readonly maxReadBytes?: number | undefined;
111
+ }
112
+ export interface ToolCallRequest {
113
+ readonly toolCallId: string;
114
+ readonly toolName: string;
115
+ readonly arguments: Record<string, unknown>;
116
+ readonly signal: AbortSignal;
117
+ }
118
+ export type ToolCallMetadata = {
119
+ readonly kind: "command";
120
+ readonly executable: string;
121
+ readonly argCount: number;
122
+ readonly exitCode: number | null;
123
+ readonly timedOut: boolean;
124
+ readonly sandbox: {
125
+ readonly envAllowlist: readonly string[];
126
+ readonly network: "inherit" | "none";
127
+ readonly maxOutputBytes: number;
128
+ readonly timeoutMs: number;
129
+ readonly terminationGraceMs: number;
130
+ readonly cwdRequested: boolean;
131
+ readonly filesystem?: FilesystemPolicy | undefined;
132
+ readonly networkEnforced?: boolean | undefined;
133
+ readonly filesystemEnforced?: boolean | undefined;
134
+ readonly backend?: SandboxBackend | undefined;
135
+ };
136
+ } | {
137
+ readonly kind: "patch-apply";
138
+ readonly changedFiles: number;
139
+ readonly created: number;
140
+ readonly deleted: number;
141
+ };
142
+ export interface ToolCallResult {
143
+ readonly toolCallId: string;
144
+ readonly output: string;
145
+ readonly durationMs: number;
146
+ readonly commandExecuted?: boolean | undefined;
147
+ readonly metadata?: ToolCallMetadata | undefined;
148
+ }
149
+ export interface ToolPort {
150
+ readonly execute: (request: ToolCallRequest) => Promise<ToolCallResult>;
151
+ readonly listTools: () => readonly ToolDefinition[];
152
+ }
153
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/dist/tools.js ADDED
@@ -0,0 +1,118 @@
1
+ // Tool-layer contract types and frozen default tables (env allowlist, command rules,
2
+ // sandbox policy, limits, host config). No runtime logic lives here — the
3
+ // `resolveToolHostConfig` helper stays in src/tools/types.ts because it is layer logic, not a
4
+ // contract. `readonly` everywhere; optional props are `| undefined` because
5
+ // exactOptionalPropertyTypes is on. Imports end `.js`, double quotes, `type` keyword.
6
+ // Cross-platform name allowlist. Only names that are PRESENT in the parent are copied, so an
7
+ // absent Windows var on POSIX (or vice versa) is simply skipped.
8
+ //
9
+ // HOME and USERPROFILE are deliberately ABSENT (C5). Forwarding the developer's real home would let
10
+ // a subprocess read ~/.npmrc (npm tokens), ~/.git-credentials, and ~/.aws/… by standard home-dir
11
+ // lookup. runCommand instead injects an ephemeral, EMPTY per-run dir as HOME/USERPROFILE so those
12
+ // lookups resolve to nothing (ADR-0006 D2 Dimension 1).
13
+ export const DEFAULT_ENV_ALLOWLIST = Object.freeze([
14
+ "PATH",
15
+ "LANG",
16
+ "LC_ALL",
17
+ "LC_CTYPE",
18
+ "TZ",
19
+ "TERM",
20
+ "TMPDIR",
21
+ // Windows essentials so spawned tools resolve the shell-less executable correctly.
22
+ "SystemRoot",
23
+ "SystemDrive",
24
+ "PATHEXT",
25
+ "COMSPEC",
26
+ "NUMBER_OF_PROCESSORS",
27
+ "WINDIR",
28
+ ]);
29
+ export const DEFAULT_SANDBOX_POLICY = {
30
+ envAllowlist: DEFAULT_ENV_ALLOWLIST,
31
+ // `"inherit"` stays the default for the read-only command tools. A caller that executes UNTRUSTED
32
+ // code (e.g. the #1202 assured pre-filter) passes `network: "none"` explicitly; keiko-sandbox then
33
+ // wraps the spawn in an OS/container egress boundary, so `"none"` is now HONOURED, not merely
34
+ // documented (ADR-0043). Leaving the default at `"inherit"` keeps the blast radius minimal.
35
+ network: "inherit",
36
+ maxOutputBytes: 262_144,
37
+ defaultTimeoutMs: 30_000,
38
+ terminationGraceMs: 2_000,
39
+ };
40
+ export const SANDBOX_BACKENDS = Object.freeze([
41
+ "bubblewrap",
42
+ "unshare",
43
+ "seatbelt",
44
+ "container-docker",
45
+ "container-podman",
46
+ "none",
47
+ ]);
48
+ // Minimal, justified default rules. Everything not listed is denied (deny-by-default).
49
+ export const DEFAULT_COMMAND_RULES = Object.freeze([
50
+ {
51
+ executable: "npm",
52
+ // Read-only npm only. Mutating/package-installing subcommands are excluded by omission.
53
+ allowedSubcommands: Object.freeze([
54
+ "audit",
55
+ "ls",
56
+ "list",
57
+ "outdated",
58
+ "view",
59
+ "info",
60
+ "help",
61
+ "ping",
62
+ ]),
63
+ // `-c`/`--call` execute a command string in a shell; deny outright (S-H2).
64
+ denyFlags: Object.freeze(["-c", "--call"]),
65
+ },
66
+ {
67
+ executable: "git",
68
+ // READ-ONLY git only; push/reset/checkout/commit/merge/rebase/clean/config/remote denied.
69
+ allowedSubcommands: Object.freeze([
70
+ "status",
71
+ "diff",
72
+ "log",
73
+ "show",
74
+ "rev-parse",
75
+ "ls-files",
76
+ "describe",
77
+ "blame",
78
+ "cat-file",
79
+ ]),
80
+ // Global value flags that precede the subcommand (`git -C DIR <sub>`). Skipping them prevents
81
+ // the value (DIR) from being read as the subcommand (S-H2).
82
+ valueFlags: Object.freeze([
83
+ "-C",
84
+ "-c",
85
+ "--git-dir",
86
+ "--work-tree",
87
+ "--namespace",
88
+ "--exec-path",
89
+ ]),
90
+ // Deny git's code-execution / external-driver flags. `git -c diff.external=<cmd> diff` (and
91
+ // --config-env/--ext-diff/--textconv) make git spawn an arbitrary command via its OWN shell,
92
+ // defeating the Node spawn's shell:false; --exec-path redirects git to attacker-supplied sub-binaries.
93
+ // hasDeniedFlag runs BEFORE subcommand resolution and matches both `--flag value` and
94
+ // `--flag=value`. `-C`/--git-dir/--work-tree stay value-flags (location only, not execution).
95
+ denyFlags: Object.freeze([
96
+ "-c",
97
+ "--config-env",
98
+ "--exec-path",
99
+ "--ext-diff",
100
+ "--textconv",
101
+ "--no-index",
102
+ "--output",
103
+ "--contents",
104
+ ]),
105
+ },
106
+ ]);
107
+ export const DEFAULT_PATCH_LIMITS = {
108
+ maxPatchBytes: 65_536,
109
+ maxChangedLines: 2_000,
110
+ maxFilesChanged: 50,
111
+ };
112
+ export const DEFAULT_TOOL_HOST_CONFIG = {
113
+ sandbox: DEFAULT_SANDBOX_POLICY,
114
+ commandRules: DEFAULT_COMMAND_RULES,
115
+ patchLimits: DEFAULT_PATCH_LIMITS,
116
+ applyEnabled: false,
117
+ maxReadBytes: 262_144,
118
+ };