k9o 1.5.0-arm64-darwin
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +132 -0
- data/LICENSE +201 -0
- data/NOTICE +4 -0
- data/README.md +1946 -0
- data/k9o.gemspec +42 -0
- data/lib/k9o/_ffi/kibo_kms_rest_ffi.rb +2815 -0
- data/lib/k9o/_ffi/libkibo_kms_rest_ffi.dylib +0 -0
- data/lib/k9o/ai.rb +43 -0
- data/lib/k9o/analytics.rb +403 -0
- data/lib/k9o/approvals.rb +253 -0
- data/lib/k9o/audit.rb +177 -0
- data/lib/k9o/barbican.rb +239 -0
- data/lib/k9o/client.rb +78 -0
- data/lib/k9o/compute.rb +84 -0
- data/lib/k9o/crypto.rb +471 -0
- data/lib/k9o/custody.rb +28 -0
- data/lib/k9o/data.rb +277 -0
- data/lib/k9o/ed25519.rb +182 -0
- data/lib/k9o/end_users.rb +93 -0
- data/lib/k9o/envelope.rb +79 -0
- data/lib/k9o/functions.rb +169 -0
- data/lib/k9o/gate.rb +94 -0
- data/lib/k9o/http_transport.rb +380 -0
- data/lib/k9o/jcs.rb +117 -0
- data/lib/k9o/kerror.rb +104 -0
- data/lib/k9o/keys.rb +131 -0
- data/lib/k9o/kibo.rb +114 -0
- data/lib/k9o/kibo_client_core.rb +385 -0
- data/lib/k9o/kibo_ffi_core.rb +178 -0
- data/lib/k9o/locate.rb +118 -0
- data/lib/k9o/me.rb +100 -0
- data/lib/k9o/metadata.rb +342 -0
- data/lib/k9o/migrations.rb +244 -0
- data/lib/k9o/moat.rb +443 -0
- data/lib/k9o/multipart.rb +42 -0
- data/lib/k9o/org.rb +226 -0
- data/lib/k9o/orgs.rb +34 -0
- data/lib/k9o/policies.rb +84 -0
- data/lib/k9o/projects.rb +68 -0
- data/lib/k9o/query.rb +174 -0
- data/lib/k9o/rampart.rb +273 -0
- data/lib/k9o/realtime.rb +309 -0
- data/lib/k9o/region.rb +97 -0
- data/lib/k9o/schedules.rb +109 -0
- data/lib/k9o/schema.rb +35 -0
- data/lib/k9o/storage.rb +176 -0
- data/lib/k9o/streams.rb +94 -0
- data/lib/k9o/studio.rb +185 -0
- data/lib/k9o/url_grammar.rb +139 -0
- data/lib/k9o/vault.rb +230 -0
- data/lib/k9o/vectors.rb +124 -0
- data/lib/k9o/version.rb +5 -0
- data/lib/k9o.rb +71 -0
- data/sig/k9o/ai.rbs +20 -0
- data/sig/k9o/approvals.rbs +71 -0
- data/sig/k9o/datasets.rbs +125 -0
- data/sig/k9o/gate.rbs +14 -0
- data/sig/k9o/kerror.rbs +24 -0
- data/sig/k9o/kibo_client_core.rbs +25 -0
- data/sig/k9o/metadata.rbs +54 -0
- data/sig/k9o/migrations.rbs +138 -0
- data/sig/k9o/moat.rbs +29 -0
- data/sig/k9o/query.rbs +26 -0
- data/sig/k9o/rampart.rbs +59 -0
- data/sig/k9o/realtime.rbs +34 -0
- data/sig/k9o/region.rbs +30 -0
- data/sig/k9o/storage.rbs +41 -0
- data/sig/k9o/workload.rbs +64 -0
- metadata +130 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 78d7031c4fd2384c300666f52027387bfde576f78638f53797916f111b213334
|
|
4
|
+
data.tar.gz: 173cd23e945a1dae269486e48d79e8efe200794fc0b62a170bf050638294c6a8
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: b1b30eeab1d44672b521eaf75f2e36ff0484393e8de90d80fd28a3cba2f641aa0c5940645d354b9fa81ef4030fee7921af88cade85a9e6866557f2bfe3979b76
|
|
7
|
+
data.tar.gz: 25f87e0d1bce9bc2825c053f401e70d7b074b1cb0a639a96a62b708ae76c711ed68061b6d1a2380738c2e713d5bad8fea20e9c706839ed008c2a6f6591ed8a1b
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Changelog — k9o (Ruby)
|
|
2
|
+
|
|
3
|
+
## 1.5.0 (unreleased)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `approvals.comments.add(pending_id, body:, visibility:)` and `approvals.comments.list(pending_id, limit: nil, cursor: nil)`: comment on a pending change (`POST` and `GET /@<project>/pending-approvals/<id>/comments`). `body` is 1 to 4000 characters and `visibility` is `"everyone"` or `"approvers_only"`, fixed once posted; `pending_id`, `body`, `visibility` and `limit` (1 to 200) are checked before anything is sent (`K9O_INVALID_FIELD_VALUE`). `list` answers the comments the caller may see, oldest first, as a page with `next_cursor` (`nil` on the last page). Posting needs a session; a personal access token alone is refused (`K9O_RBAC_DENY`). `K9O_APPROVAL_COMMENT_NOT_ELIGIBLE` and `K9O_APPROVAL_COMMENT_CLOSED` arrive as `K9o::KError`.
|
|
8
|
+
- `realtime.replay(topic, from_sequence: nil, until_sequence: nil, limit: nil)`: read a batch of past events for a realtime topic (`POST /@<project>/realtime/replay`), the catch-up for `realtime.subscribe`. `topic` is required; `from_sequence` and `until_sequence` are whole numbers (0 or more) and `limit` is 1 to 10000 (`K9O_INVALID_FIELD_VALUE` before anything is sent). `data` is `{ "events", "nextCursor", "hasMore" }`, plus `"resync"` (`"reread-source"`) when the topic keeps no history, so re-read the current state. Events keep the gateway's spelling that `subscribe` yields. `audit.replay` is unchanged.
|
|
9
|
+
- `gate.sign_in` asks the project which region holds the email first (`POST /@<project>/gate/locate`, the email only, no credential) and sends the password to that region's host. The located host is used only if it is `https`, has no userinfo, port, path, query or fragment, and is your own org, gateway family and apex with the region code added or swapped in; otherwise the base URL is used. The answer is never cached; `refresh_token` and `sign_out` go to the host that issued the session, from a bounded in-memory hint. If the locate step answers 404, the base URL is used. A 429 `K9O_RATE_LIMITED` or 503 `K9O_GATE_REGION_UNAVAILABLE` from that step raises as `K9o::KError`, nothing else is sent, and the call is safe to retry.
|
|
10
|
+
- `crypto.mode` and `crypto.mode(crypt:)` return the gateway's `route` (`"client"` or `"server"`) as `Mode#route`, `nil` on older gateways or for an unknown value; follow it, not `custody_mode`.
|
|
11
|
+
- The custody check before each `crypto.encrypt` names the crypt (`GET /crypto/mode?crypt=<crypt>`), so a personal access token or workload policy scoped to named crypts can encrypt. `crypto.mode` sends no query.
|
|
12
|
+
- `crypto.mode(crypt: nil)`: an optional crypt for the public mode read (`GET /crypto/mode?crypt=<crypt>`); the crypt is checked before sending (`K9O_INVALID_FIELD_VALUE`), and `crypto.mode` is unchanged.
|
|
13
|
+
- `crypto.encrypt` follows the `route` in the project's mode answer. On a BYOK or HYOK project only an explicit route `"server"` sends plaintext to the platform (the answer then needs an epoch, otherwise `K9O_CRYPTO_CUSTODY_UNKNOWN`); a missing route uses your client core. A route that is not `"server"` or `"client"` raises `K9O_CRYPTO_CUSTODY_UNKNOWN` and nothing is sent. The mode is read on every call. `decrypt` and `rewrap` are unchanged.
|
|
14
|
+
- `crypto.crypts_list`, `crypto.crypts_create(name)` and `crypto.crypts_retire(name)`: list, register and retire crypt names. `create` sends only `{ name }`; a name outside 1 to 64 characters of a-z, 0-9 and `-` (or `actions`) raises `K9O_INVALID_FIELD_VALUE` (`field: name`) before anything is sent. Each answers a crypt as `{ "name", "status" ("active" or "retired"), "createdAt", "retiredAt" }`; a malformed gateway answer raises `K9O_INTERNAL_ERROR`. `K9O_CRYPT_ALREADY_EXISTS`, `K9O_CRYPT_LIMIT_EXCEEDED`, `K9O_CRYPT_RETIRED`, `K9O_CRYPT_NOT_FOUND` and access refusals arrive as `K9o::KError`. A retired or unregistered name only makes `encrypt` refuse it; `decrypt` and `rewrap` never read the registry. Needs `crypto:manage_crypts` (project admins by default); a personal access token is refused on retire.
|
|
15
|
+
- `K9o::KiboClientCore`: the client core for `k9o.crypto` on a BYOK or HYOK project. It opens and seals data on this machine against your own KMS or HSM, so the platform never sees plaintext or the key. Register it with `crypto.use_client_core`. The key, provider, region, role and endpoint all come from the configuration you pass; `expected_key_refs:` is required and non-empty, and the configured key must be in it. Before any token is fetched it checks that the bound core lists `expected_key_refs` (otherwise `K9O_CRYPTO_KEY_PIN_UNENFORCED`) and exports the 2.15.0 functions (otherwise `KIBO_WASM_ERROR`). A federated-token response that names another provider or project is refused with `K9O_INVALID_FIELD_VALUE` and nothing is exchanged. The exchange has a deadline (30 s, `exchange_deadline:`; `KIBO_EXCHANGE_TIMEOUT`); the exchanged credential is reused until 60 s before it expires, and a federated token is fetched on every call. A failed item is `{ "ok" => false, "code", "message" }` with the core's code (`UPSTREAM_KMS_ERROR` is your own KMS); a pin, capability, token or exchange problem raises `K9o::KError`. No token or credential appears in an error, `inspect` or `to_s`. A call whose own `expected_key_refs` does not contain the configured key is refused per item with `K9O_CRYPTO_UNEXPECTED_KEY` before the federated token is fetched and before the exchange.
|
|
16
|
+
- `K9o::KiboFfiCore`: a built-in bound core for `K9o::KiboClientCore` that works with the generated Ruby binding (`KiboKmsRestFfi`, zk-bundle-v2.16.3 or later). Pass `core: K9o::KiboFfiCore.new`. It converts the SDK's plain data to the binding's typed records, integer enums and federation variant, and the binding's errors to `CODE: detail` (`UPSTREAM_KMS_ERROR` for your own KMS failing); the cryptography stays in the native core. Requiring `k9o` does not load the binding; building the adapter without it raises `K9o::KError` (`KIBO_WASM_ERROR`). `library:` takes the absolute path of the native library, `binding_path:` the path of the binding file. The Vault federation field for the JWT login is `jwt_auth_mount` (the name Vault serves the JWT login under, `jwt` for `auth/jwt`; not the transit mount); the core receives it as its own `mount` field, and `vault_addr`, `jwt_auth_mount` and `role` are required for `provider: "vault"`.
|
|
17
|
+
- `K9o::Crypto::FederatedToken#provider` and `#project_id`: set when the gateway names them in the federated-token response, otherwise `nil`. They are only checked against your configuration.
|
|
18
|
+
- `crypto.federated_token(crypt, op)`: ask for a short-lived RS256 token (valid for at most 15 minutes) for one crypt and one operation (`"encrypt"`, `"decrypt"` or `"rewrap"`), answered as `K9o::Crypto::FederatedToken` (`token`, `expires_at`, `issuer`, `subject`, `audience`, `kid`). `crypt` and `op` are checked before sending (`K9O_INVALID_FIELD_VALUE`); the call is never retried; a response without any of the six fields raises `K9O_INTERNAL_ERROR`. The token is left out of `inspect`, `to_s` and `pp`.
|
|
19
|
+
- `expected_key_refs:` client option: an `Array` of the key identifiers (from your own cloud configuration) your BYOK or HYOK key may be. It is checked when the client is built (non-empty, no blanks, spaces or `*`; `K9O_INVALID_FIELD_VALUE` otherwise) and passed to the client core as the keyword `expected_key_refs:` on every `crypto.encrypt`, `decrypt` and `rewrap` call when set, so the core refuses any other key (version ignored) before it uses a token or makes a network call. A core declares that it does with a method `enforces_expected_key_refs?` that returns `true`; with the option set and no declaration the call raises `K9O_CRYPTO_KEY_PIN_UNENFORCED` before the core is called. `K9o::Crypto.key_ref_matches?(key_ref, expected, provider:)` is the comparison for core authors (`provider:` is required, one of `:aws`, `:gcp`, `:azure` or `:vault`, and is never guessed from the reference): AWS compares the whole reference; GCP without the version; Azure the first five parts in lower case; Vault `<path>/<key>` without `:<version>`.
|
|
20
|
+
- `custody.status`: read how the project's keys are held (`mode`, `attached`, `provider`, `lastJob`, and `hsm` for a hardware security module); read-only.
|
|
21
|
+
- `KError#retry_after_sec`: the wait the gateway asks for (seconds), or `nil`.
|
|
22
|
+
- `KError#request_id` is filled from the gateway's `x-k9o-request-id` response header (any letter case) when the error body carries no request id, on every error built from a non-2xx response, including a stream open; a request id in the body still wins, and it stays `nil` when neither is present.
|
|
23
|
+
- `require_approval` on single-record writes: `insert(record, require_approval: true)`, and `.require_approval` on `update` and `delete` builders. The write is sent with `?requireApproval=true` and may answer a queued change (HTTP 202); `K9o.queued_write?(result)` tells it from an applied row. `Meta#approval` carries `meta.approval`.
|
|
24
|
+
- `functions.triggers`: `list`, `create`, `update` and `delete` for event triggers.
|
|
25
|
+
- `schedules` namespace: `list`, `get`, `create`, `update`, `delete`, `runs` and `run_now`.
|
|
26
|
+
- `vectors` namespace: `nearest` and `upsert` for vector collections (names start with `_`), sending the embedding in the request body.
|
|
27
|
+
- `metadata` namespace: `filter`, `set`, `search`, `vectors.nearest`, `subscribe`, and `index.get` / `index.declare` for the columns you declare on a collection. Column names in `where`, `search` and `nearest` get the `metadata.` prefix when you leave it out; `set` writes declared columns only. `subscribe` uses the same reconnecting reader as `realtime.subscribe` (events carry the record id only) and takes `from_sequence:`. The SDK checks the surface grammar, limits, cursor rule and the 64-column limit before sending. Gateway codes such as `K9O_METADATA_FIELD_NOT_INDEXED`, `K9O_UNKNOWN_SURFACE` and `K9O_QUERY_RESULT_TOO_LARGE` arrive as `K9o::KError`.
|
|
28
|
+
- `rampart` namespace: `classify(input, label:)` answers the verdict and its signed receipt (advisory; a classifier outage raises `K9O_RAMPART_CLASSIFIER_UNAVAILABLE`), `jwks` reads the public key feed, and `verify_receipt(result_or_receipt, input)` checks a receipt locally (EdDSA, `typ`, issuer, project, clock skew, and the SHA-256 of the canonical `input`) and returns the verified verdict or raises `K9o::Rampart::ReceiptRefusal` with a closed `reason`. The issuer comes from the key feed (`issuer:` overrides it); the project is the `projectId` of the `classify` result (or `project_id:`), and a bare receipt string with neither is refused as `project_unknown`. Keys are cached for the client's life and refetched once on an unknown key id. `K9o::Jcs` (the platform's canonical form: keys sorted by UTF-8 byte order, integers only up to 2^53 - 1, so an input with a fractional number cannot be classified or verified) and `K9o::Ed25519` (openssl, with a built-in fallback) are included, with no new dependency. A long input is scored in overlapping windows and the highest injection score decides; past 16 windows (about 6,000 tokens) the answer is `413 K9O_RAMPART_INPUT_TOO_LONG` with no verdict, and `503 K9O_RAMPART_CLASSIFIER_UNAVAILABLE` still means the classifier could not answer. The thresholds (calibration `rampart-launch-v1`) are a starting calibration and may move; a change is a new `calibrationVersion`.
|
|
29
|
+
- `analytics` namespace for datasets: `list`, `query`, `create`, `get`, `delete`, `materialize`, `read` (cursor paging), `write`, `upload` (raw or multipart with a manifest), `download_original` (answers a `K9o::Download`), plus `analytics.rollups` and `analytics.schedules` (`create`, `list`, `delete`, `reattest`) and the project-wide `rollups` namespace (`list`, `read`, `subscribe`). `reattest` is for people only: a service, workload or extension token gets `403 K9O_RBAC_DENY` (`reason: human_only`), and a rollup or schedule that is not re-attested pauses when its interval ends.
|
|
30
|
+
- `keys` namespace: `list`, `get` and `rotate` for the project's encryption keys (metadata only; `list` takes `status:` `active` or `all` and is not paged). `rotate(key_id, step_up: hook)`: on `401 K9O_STEP_UP_REQUIRED` the SDK calls your hook with the challenge (`KError#step_up`), the HTTP method and the URL, sends the same request once more with the `x-k9o-step-up-proof` header built from its `{ method:, proof: }` answer, and never loops; without a hook the error carries the challenge. Rotation is never retried otherwise, and answers `409 K9O_STATE_CONFLICT` or `429 K9O_RATE_LIMITED` (at most 3 per rolling 24 hours) as `K9o::KError`.
|
|
31
|
+
- `audit.tail(types:, on_resync:)`: live audit events (`auditEventId`, `type`, `actorType`, `occurredAt`, `outcome`, and the frame's `eventId`) read from the gateway's frames (the audit event sits in `payload`; the frame's SSE `id` is the publisher's own id and the `Last-Event-ID` for a resume), on the reconnecting reader of `realtime.subscribe`; on a `replay-ledger` resync it reads the missed events through the new `audit.replay` after the last `auditEventId` delivered, page by page, and yields them once. `audit.replay` answers the typed page `{ events, nextCursor, hasMore }` (events flattened, `sequence` a string).
|
|
32
|
+
- `audit.tail` after a `resync` is gapless: it reconnects fresh and buffers that connection, replays from the last delivered `auditEventId`, then merges replay, buffered and live frames, each event once (a repeated resync backs off). `audit.replay` sends `limit: 1000` when you give none and refuses a limit above 10000 or below 1 with `K9O_INVALID_FIELD_VALUE`. A new connection starts at the live head and may re-send the last few seconds of events (each yielded once), and the informational `resync` that opens it is ignored.
|
|
33
|
+
- `rollups.subscribe` yields the cell from each `cell` frame's `payload` (with `eventId` and a `suppressed` flag for cells below the cohort threshold), resumes with the frame's `id`, and calls `on_resync` on `reread-source`.
|
|
34
|
+
- `crypto` namespace for server-side encryption with the project's key: `encrypt`, `decrypt` and `rewrap` (`POST /crypto/encrypt|decrypt|rewrap`), batches of up to 100 items, bytes in and out with the base64 done for you, `K9o::Crypto.text`, and client-side checks (`K9O_INVALID_FIELD_VALUE`, `K9O_PAYLOAD_TOO_LARGE`) before anything is sent. Never retried automatically. `encrypt` checks the custody mode (`crypto.mode`) on every call and never sends plaintext when the key is in your own KMS or HSM; `decrypt` and `rewrap` try the platform first and reroute client-side on `409 K9O_ZK_STORE_FLOW_REQUIRED`. Register the Kibo client core with `crypto.use_client_core`; without one those calls raise `K9O_ZK_CLIENT_CORE_UNAVAILABLE` (501). An unknown mode or a failed check raises and sends nothing. The gateway route is not live yet.
|
|
35
|
+
- `Rampart::Verdict#windows`: the number of windows the classifier scored, read from the signed `windows` claim (`nil` when absent); unknown claims are ignored. `413 K9O_RAMPART_INPUT_TOO_LONG` raises as `K9o::KError`.
|
|
36
|
+
- `KError#retry_after_sec` also reads the `Retry-After` response header (whole seconds) when the body gives none.
|
|
37
|
+
- `K9o::Moat`: a local guard for one model call with no network access. It pins the system prompt, refuses role and system markers in untrusted input, checks input and output against a documented JSON Schema subset, and runs an optional PII filter you pass in. Refusals raise `K9o::Moat::Refusal` with `reason` `role_marker`, `input_schema`, `output_schema` or `pii`.
|
|
38
|
+
- `K9o::Moat` role-marker scan follows the shared normalisation rule: NFKC, combining marks ignored, default-ignorable and format code points removed, a small set of Cyrillic and Greek look-alikes of the marker letters read as the Latin letter (not general homoglyph detection), case-folded, horizontal whitespace collapsed, then matched line by line; it passes the shared marker vectors.
|
|
39
|
+
- `end_users` namespace: `list`, `get` and `role_grants` (`list`, `grant`, `revoke`).
|
|
40
|
+
- `approvals.list` pages: optional `cursor:` (from `meta.cursor.next`, `nil` on the last page) beside `status:` and `limit:`.
|
|
41
|
+
- `approvals.bulk` result carries `failed`, a list of `{ "id", "code", "reason" }` for rows that did not apply (empty when none); the call answers HTTP 200 even when rows fail.
|
|
42
|
+
|
|
43
|
+
- `realtime.subscribe` resumes: it reconnects with `Last-Event-ID` when the stream ends or the network fails (backoff up to 30 seconds), drops duplicate events by `eventId`, ignores heartbeats, abandons a connection idle for 45 seconds, and calls the new optional `on_resync:` handler (without yielding the frame) before continuing from a fresh connection. Events carry `eventId`.
|
|
44
|
+
- README: what an event-trigger function receives (the JSON payload, redaction, `triggeredAt`, and deduping on `eventId`).
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
|
|
48
|
+
- The read timeout is 120 seconds (was 30), as in the Python SDK, so a long call such as Rampart `classify` on a long input is not cut off. A client you pass in with `http_client:` keeps being set to the same value.
|
|
49
|
+
|
|
50
|
+
- `vector_search` on the select builder sends the embedding in the request body (`POST data/<collection>/search`), so real embeddings work. It cannot be combined with `text_search`.
|
|
51
|
+
- The approval policies README no longer says the builders do not send `requireApproval`.
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- `realtime.subscribe`, `metadata.subscribe` and `rollups.subscribe` no longer reconnect forever on a fresh connection. The gateway opens such a connection with an informational `event: resync` frame and then streams events on the same connection; the reader treated that frame as a lost position, so no event was delivered. A `resync` that is the first data of a connection sent with no `Last-Event-ID` and no `fromSequence` is now ignored (`on_resync` is not called and the connection is kept). A `resync` after an event, or on a connection sent with `Last-Event-ID` or `fromSequence`, is still a lost position: `on_resync` is called and the reader reconnects fresh. `audit.tail` is unchanged.
|
|
56
|
+
- `require "k9o"` no longer fails on Ruby 3.4 and later with `cannot load such file -- base64`: the vault code encodes and decodes base64 without the `base64` gem, which is no longer a default gem there and was not declared as a dependency.
|
|
57
|
+
- `audit.tail` and `audit.replay` read the gateway's real frames: the tail used to deliver no events, and a replay returned an empty list, because the decoders looked for the five audit fields at the top of the frame and took the SSE `id` for the audit event id. `rollups.subscribe` yielded the frame, not the cell.
|
|
58
|
+
- `Rampart#classify` raises `K9O_INVALID_FIELD_VALUE` for an `input` that is not a Hash, with a test; the gateway is going to refuse it with a 400.
|
|
59
|
+
- `keys.list` no longer exposes `nextCursor` (the list is not paged).
|
|
60
|
+
|
|
61
|
+
- `KError#recommendation` is always a string or `nil`. An object recommendation from the gateway (`{"action": ...}` or `{"retryAfterSec": ..., "note": ...}`) used to arrive as a Hash; it now gives its `action`, else its `note`.
|
|
62
|
+
|
|
63
|
+
## 1.4.0 — 2026-10-26
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
|
|
67
|
+
- `query(sql, params)`: one read-only SQL statement; an array binds `$1, $2, ...`, a hash binds `:name` placeholders.
|
|
68
|
+
- `search(collection, column:, q:)`: full-text search over one column, plus `text_search` and `vector_search` on `select`.
|
|
69
|
+
- `ai.generate`: text generation from a prompt (verb sugar over `compute.llms.invoke`; `model` defaults to the org's default LLM).
|
|
70
|
+
- `streams` namespace for user data streams: `create`, `list`, `get`, `delete`, `publish`, `replay` and `subscribe`.
|
|
71
|
+
`subscribe` tails live events over SSE and reconnects from the last sequence when the server closes the connection.
|
|
72
|
+
|
|
73
|
+
- `approvals` namespace for the pending-change queue: `list`, `get`, `approve`, `reject` and `bulk`.
|
|
74
|
+
- `approval_policies` namespace: `list`, `create` and `delete`.
|
|
75
|
+
- `schema.collections.list`: the project's collections with row counts and last migration, paged by cursor.
|
|
76
|
+
|
|
77
|
+
### Changed
|
|
78
|
+
|
|
79
|
+
- The README description now covers streams and realtime, and the platform overview moved to an "About Kilimanjaro" appendix.
|
|
80
|
+
- Function deploy examples use the sandbox tier.
|
|
81
|
+
|
|
82
|
+
## 1.3.0 — 2026-10-26
|
|
83
|
+
|
|
84
|
+
Every method now matches the gateway.
|
|
85
|
+
|
|
86
|
+
### Changed
|
|
87
|
+
|
|
88
|
+
- `projects.create` takes `display_name:` (and optional `slug:`, `region:`, `custody_mode:`, ...);
|
|
89
|
+
`projects.get` and `projects.update` use the projects routes.
|
|
90
|
+
- `functions.deploy` takes `name:`, `runtime:`, `tier:` (`gateway` or `sandbox`), `artifact_key:`, `version:` and `description:`.
|
|
91
|
+
Inline code is gone.
|
|
92
|
+
- `functions.invoke` sends the payload as `{payload}`.
|
|
93
|
+
- `policies.create`, `update` and `validate` take a `policy:` document (plus optional `rules:`, `editor_mode:`);
|
|
94
|
+
`policies.list` takes only `status:`.
|
|
95
|
+
- `audit.query` filters are `event_type:`, `actor_id:`, `after:`, `before:`, `limit:` and `cursor:`.
|
|
96
|
+
- Org roles, identity providers and default model use the current routes; `smtp.set` uses `password_ref:` and `from_address:`;
|
|
97
|
+
`smtp.test` takes `to:` and `subject:`.
|
|
98
|
+
- `me.api_tokens.create` takes `label:` and `scope_manifest:` (and `ttl_seconds:`); `me.sessions.revoke` and `revoke_all` use new routes.
|
|
99
|
+
- `compute.llms.invoke` settings are sent flat, and the result has `content` and `usage`.
|
|
100
|
+
- `studio.workflows.trigger` sends the context as `triggerContext`.
|
|
101
|
+
- `gate.sign_out` requires the refresh token.
|
|
102
|
+
- The API host comes from the base URL: any `<org>.api.<apex>` host works and no apex is hardcoded.
|
|
103
|
+
`https://api.k9o.io` is only the default.
|
|
104
|
+
|
|
105
|
+
### Removed
|
|
106
|
+
|
|
107
|
+
- `gate.verify_session`, `gate.hosted`, `realtime.replay` and `realtime.subscribe_poll`.
|
|
108
|
+
- `me.notifications`, `me.audit_log` and `me.data_export`.
|
|
109
|
+
- `org.groups.create`, `org.groups.delete`, `org.members.get` and `org.smtp.get`.
|
|
110
|
+
|
|
111
|
+
### Added
|
|
112
|
+
|
|
113
|
+
- `functions.upload_artifact(bytes, kind)` uploads a build and returns the `artifactKey` for `deploy`.
|
|
114
|
+
- `UrlGrammar.parse_api_host` reads the org, region and apex from any gateway host.
|
|
115
|
+
- A contract test checks every method against the gateway's API description.
|
|
116
|
+
|
|
117
|
+
## 1.2.0 — 2026-10-25
|
|
118
|
+
|
|
119
|
+
- The README now introduces the Kilimanjaro building blocks (Keep, Pulse, Gate, Kibo). No change to the public API.
|
|
120
|
+
|
|
121
|
+
## 1.1.1 — 2026-10-25
|
|
122
|
+
|
|
123
|
+
- Documentation links corrected: the documentation hub is https://docs.kilimanjaro.dev, with the website, platform API and console listed in a Links section. Package metadata points at the same places.
|
|
124
|
+
|
|
125
|
+
## 1.1.0 — 2026-10-25
|
|
126
|
+
|
|
127
|
+
- Documentation rewritten with runnable examples and expected output; internal cross-references removed from the published sources. No change to the public API.
|
|
128
|
+
- Error text for `update()` / `delete()` without an `id` filter no longer mentions a version or a roadmap.
|
|
129
|
+
|
|
130
|
+
## 1.0.0 — 2026-10-23
|
|
131
|
+
|
|
132
|
+
First public release. See the README for the full API overview.
|
data/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
data/NOTICE
ADDED