Building a connector
Connectors are Kamiwaza-managed adapters. Kaizen discovers instances at runtime and walks them through a generic surface contract — which is what lets a new connector type work without a Kaizen code change.
The rule that shapes everything
Never hardcode a connector type in Kaizen.
Kaizen's compose file, environment, and frontend must not enumerate connector types. Discovery is dynamic: Kaizen reads connector instances and their declared surfaces from the current workroom at runtime.
A static catalog would reintroduce the release coupling this design exists to remove — and it would break the moment someone deploys a connector you did not anticipate.
The surface contract
A connector declares surfaces; Kaizen consumes them uniformly. When walking a surface, Kaizen reads each node through a typed adapter rather than assuming a field layout.
This matters more than it sounds. The platform serializes nodes with a content handle and a node type; a walker that assumed different field names would work for exactly the connectors it was written against and silently return nothing for the rest. The adapter is what makes the contract general.
If you are adding a connector and Kaizen returns no documents, check the node contract first — silent emptiness is the characteristic symptom of a shape mismatch.
Federated live queries
Kaizen's live connector entry point does not select a provider from the member's wording. It fans the query across the ready surfaces admitted by the current agent policy. Implement the generic surface operations faithfully and a new connector participates without a Kaizen release:
- return normalized container nodes from root browse;
- mint an opaque
container_idthat browse or scoped search accepts again; - declare whether search is supported;
- when content needs provider locators, put bounded scalar values in
content_handle.queryand accept them unchanged at content fetch.
An unscoped search may reject a request when the provider genuinely requires a container. Kaizen then performs a bounded generic browse and tries returned containers; it does not parse the container value or branch on connector type. Keep root browsing cheap enough for that discovery path, and make cycles and pagination explicit through the standard contract.
Identity flows through
Every connector call runs as the signed-in member. The provider and Kamiwaza apply that member's access.
Design consequences:
- Do not hold a broad service credential that can see more than an individual member.
- Do not cache results across members.
- Do expect two members to legitimately get different results for the same query.
- Do let a revocation take effect at the next call — never at the next reindex.
Two readiness shapes are supported:
| Kind | Ready when |
|---|---|
| Service token | Ready for the whole workroom; no per-user Connect action |
| User-authorized | Ready only after that user completes the platform flow |
Prefer user-authorized for anything sensitive. A service token ready for the whole workroom is exactly as broad as it sounds.
Live retrieval versus sync
Live retrieval consults the connector during a turn. Access is evaluated again every turn, so results are current and correctly scoped.
Kaizen-owned sync walks the surfaces and streams discovered documents into the private index. Synced chunks carry an opaque member/workroom/connector grant that Kaizen revalidates against Kamiwaza on every retrieval — a synced chunk is a pointer that must prove itself again, not a stored permission.
Support both where you can. Sync is what makes a large corpus searchable quickly; live retrieval is what keeps a fast-moving source correct.
Progress reporting
During a walk, report an indeterminate count while discovery, fetch, chunking, and embedding run concurrently. Once the walk establishes the final total, switch the same run to exact percentage progress.
Do not fabricate a total before you have one. An accurate "still discovering" beats an estimate that jumps backwards.
Deployment settings
Connector deployments accept non-secret settings forwarded from the frontend to the running pod, with automatic redeployment when they change.
Use these for site-specific configuration — a base URL, a path prefix, a content filter. Never for credentials: secrets go through the platform's secret handling, declared as such, injected and redacted.
Egress
A connector that reaches the network needs its egress derived from configuration rather than assumed. If it is deployed with a changed endpoint, the egress allowance has to follow — otherwise the connector registers successfully and then silently fails to fetch.
Content is untrusted
Whatever a connector returns is untrusted text. It may contain instructions aimed at the model.
Kaizen's containment is structural: connector content arrives as evidence and cannot grant a tool, widen a scope, approve an action, or supply an identity. As a connector author you do not need to sanitize for prompt injection — but you must not invent a path that turns content into configuration.
Failure behavior
Fail closed and fail partial:
- an unavailable connector should degrade retrieval, not fail the query — Search labels the set partial and returns what other providers authorized;
- an authorization failure must never be worked around with a broader identity;
- a minimum-content threshold that is too aggressive silently drops short documents; make thresholds explicit and tunable.
Checklist
- Nothing in Kaizen enumerates this connector type.
- Every call runs as the signed-in member.
- The node contract is read through the typed adapter, not assumed.
- Root browse and scoped search compose through opaque container ids.
- Content locators round-trip through
content_handle.query. - Sync reports indeterminate, then exact, progress.
- Grants are revalidated on retrieval, not trusted from the index.
- Non-secret settings are configurable; secrets are not in them.
- Egress is derived from configuration.
- Unavailability degrades to partial results.