@kindgi/api 0.1.4-rc.5 → 0.1.5-rc.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.
- package/dist/agent-binding.d.ts +13 -0
- package/dist/agent-binding.d.ts.map +1 -1
- package/dist/agent-pins.d.ts.map +1 -1
- package/dist/agent-pins.js +18 -2
- package/dist/agent-pins.js.map +1 -1
- package/dist/app.d.ts +110 -17
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +163 -35
- package/dist/app.js.map +1 -1
- package/dist/block-publish.d.ts +56 -0
- package/dist/block-publish.d.ts.map +1 -0
- package/dist/block-publish.js +132 -0
- package/dist/block-publish.js.map +1 -0
- package/dist/caller.d.ts +24 -0
- package/dist/caller.d.ts.map +1 -0
- package/dist/caller.js +47 -0
- package/dist/caller.js.map +1 -0
- package/dist/capability-binding.d.ts +11 -0
- package/dist/capability-binding.d.ts.map +1 -1
- package/dist/derive-agent-version.d.ts +7 -0
- package/dist/derive-agent-version.d.ts.map +1 -1
- package/dist/derive-agent-version.js +4 -0
- package/dist/derive-agent-version.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +73 -7
- package/dist/errors.js.map +1 -1
- package/dist/eval-case-binding.d.ts +16 -4
- package/dist/eval-case-binding.d.ts.map +1 -1
- package/dist/eval-run-binding.d.ts +31 -0
- package/dist/eval-run-binding.d.ts.map +1 -1
- package/dist/eval-run-dispatcher.d.ts +7 -0
- package/dist/eval-run-dispatcher.d.ts.map +1 -1
- package/dist/eval-run-dispatcher.js.map +1 -1
- package/dist/eval-sample.d.ts +11 -0
- package/dist/eval-sample.d.ts.map +1 -0
- package/dist/eval-sample.js +34 -0
- package/dist/eval-sample.js.map +1 -0
- package/dist/eval-suite-binding.d.ts +13 -0
- package/dist/eval-suite-binding.d.ts.map +1 -1
- package/dist/eval-suite-binding.js.map +1 -1
- package/dist/flow-binding.d.ts +18 -0
- package/dist/flow-binding.d.ts.map +1 -1
- package/dist/flow-pins.d.ts.map +1 -1
- package/dist/flow-pins.js +18 -2
- package/dist/flow-pins.js.map +1 -1
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +25 -0
- package/dist/gate.js.map +1 -1
- package/dist/handler-binding.d.ts +32 -0
- package/dist/handler-binding.d.ts.map +1 -1
- package/dist/hitl-binding.d.ts +23 -0
- package/dist/hitl-binding.d.ts.map +1 -1
- package/dist/identity-directory-binding.d.ts +82 -4
- package/dist/identity-directory-binding.d.ts.map +1 -1
- package/dist/identity-provider-binding.d.ts +197 -17
- package/dist/identity-provider-binding.d.ts.map +1 -1
- package/dist/improvement-pass-binding.d.ts +196 -0
- package/dist/improvement-pass-binding.d.ts.map +1 -0
- package/dist/improvement-pass-binding.js +9 -0
- package/dist/improvement-pass-binding.js.map +1 -0
- package/dist/index.d.ts +35 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/judged-dispatcher.d.ts +25 -4
- package/dist/judged-dispatcher.d.ts.map +1 -1
- package/dist/judged-dispatcher.js +43 -6
- package/dist/judged-dispatcher.js.map +1 -1
- package/dist/judgment-binding.d.ts +25 -1
- package/dist/judgment-binding.d.ts.map +1 -1
- package/dist/mcp-endpoint-binding.d.ts +7 -0
- package/dist/mcp-endpoint-binding.d.ts.map +1 -1
- package/dist/memory-binding.d.ts +124 -17
- package/dist/memory-binding.d.ts.map +1 -1
- package/dist/memory-erasure-binding.d.ts +145 -0
- package/dist/memory-erasure-binding.d.ts.map +1 -0
- package/dist/memory-erasure-binding.js +4 -0
- package/dist/memory-erasure-binding.js.map +1 -0
- package/dist/middleware/auth.d.ts +66 -13
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +150 -50
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/authorize.d.ts +6 -0
- package/dist/middleware/authorize.d.ts.map +1 -1
- package/dist/middleware/authorize.js +113 -4
- package/dist/middleware/authorize.js.map +1 -1
- package/dist/middleware/error-mapper.d.ts +5 -0
- package/dist/middleware/error-mapper.d.ts.map +1 -1
- package/dist/middleware/error-mapper.js +14 -1
- package/dist/middleware/error-mapper.js.map +1 -1
- package/dist/middleware/idempotency.d.ts +70 -5
- package/dist/middleware/idempotency.d.ts.map +1 -1
- package/dist/middleware/idempotency.js +174 -41
- package/dist/middleware/idempotency.js.map +1 -1
- package/dist/middleware/key-project.d.ts +17 -0
- package/dist/middleware/key-project.d.ts.map +1 -0
- package/dist/middleware/key-project.js +75 -0
- package/dist/middleware/key-project.js.map +1 -0
- package/dist/middleware/principal.d.ts.map +1 -1
- package/dist/middleware/principal.js +9 -5
- package/dist/middleware/principal.js.map +1 -1
- package/dist/middleware/project-ref.d.ts.map +1 -1
- package/dist/middleware/project-ref.js +3 -0
- package/dist/middleware/project-ref.js.map +1 -1
- package/dist/openapi/generate.d.ts.map +1 -1
- package/dist/openapi/generate.js +5 -2
- package/dist/openapi/generate.js.map +1 -1
- package/dist/openapi/operations.d.ts.map +1 -1
- package/dist/openapi/operations.js +918 -139
- package/dist/openapi/operations.js.map +1 -1
- package/dist/openapi/schemas.d.ts +92 -13
- package/dist/openapi/schemas.d.ts.map +1 -1
- package/dist/openapi/schemas.js +2122 -370
- package/dist/openapi/schemas.js.map +1 -1
- package/dist/person-grants-binding.d.ts +77 -0
- package/dist/person-grants-binding.d.ts.map +1 -0
- package/dist/person-grants-binding.js +4 -0
- package/dist/person-grants-binding.js.map +1 -0
- package/dist/proposal-service.d.ts +121 -0
- package/dist/proposal-service.d.ts.map +1 -0
- package/dist/proposal-service.js +447 -0
- package/dist/proposal-service.js.map +1 -0
- package/dist/proposal-status.d.ts +60 -0
- package/dist/proposal-status.d.ts.map +1 -0
- package/dist/proposal-status.js +109 -0
- package/dist/proposal-status.js.map +1 -0
- package/dist/provider-binding.d.ts +10 -0
- package/dist/provider-binding.d.ts.map +1 -1
- package/dist/publish-refused.d.ts +18 -3
- package/dist/publish-refused.d.ts.map +1 -1
- package/dist/publish-refused.js +18 -3
- package/dist/publish-refused.js.map +1 -1
- package/dist/routes/adapters.d.ts +2 -1
- package/dist/routes/adapters.d.ts.map +1 -1
- package/dist/routes/adapters.js +3 -1
- package/dist/routes/adapters.js.map +1 -1
- package/dist/routes/agent-releases.d.ts +55 -3
- package/dist/routes/agent-releases.d.ts.map +1 -1
- package/dist/routes/agent-releases.js +85 -55
- package/dist/routes/agent-releases.js.map +1 -1
- package/dist/routes/agents.d.ts +12 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +100 -2
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/approvals.d.ts +15 -3
- package/dist/routes/approvals.d.ts.map +1 -1
- package/dist/routes/approvals.js +133 -122
- package/dist/routes/approvals.js.map +1 -1
- package/dist/routes/artifacts.d.ts +25 -3
- package/dist/routes/artifacts.d.ts.map +1 -1
- package/dist/routes/artifacts.js +116 -7
- package/dist/routes/artifacts.js.map +1 -1
- package/dist/routes/auth.d.ts +25 -1
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +655 -281
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/blocks.d.ts.map +1 -1
- package/dist/routes/blocks.js +2 -42
- package/dist/routes/blocks.js.map +1 -1
- package/dist/routes/capabilities.d.ts +2 -1
- package/dist/routes/capabilities.d.ts.map +1 -1
- package/dist/routes/capabilities.js +6 -1
- package/dist/routes/capabilities.js.map +1 -1
- package/dist/routes/compliance.d.ts +9 -10
- package/dist/routes/compliance.d.ts.map +1 -1
- package/dist/routes/compliance.js +42 -61
- package/dist/routes/compliance.js.map +1 -1
- package/dist/routes/conversations.d.ts +8 -1
- package/dist/routes/conversations.d.ts.map +1 -1
- package/dist/routes/conversations.js +87 -8
- package/dist/routes/conversations.js.map +1 -1
- package/dist/routes/cost.d.ts +7 -1
- package/dist/routes/cost.d.ts.map +1 -1
- package/dist/routes/cost.js +22 -3
- package/dist/routes/cost.js.map +1 -1
- package/dist/routes/denied.d.ts +11 -0
- package/dist/routes/denied.d.ts.map +1 -0
- package/dist/routes/denied.js +17 -0
- package/dist/routes/denied.js.map +1 -0
- package/dist/routes/deployments.d.ts +2 -1
- package/dist/routes/deployments.d.ts.map +1 -1
- package/dist/routes/deployments.js +44 -12
- package/dist/routes/deployments.js.map +1 -1
- package/dist/routes/eval-comparison.d.ts.map +1 -1
- package/dist/routes/eval-comparison.js +69 -1
- package/dist/routes/eval-comparison.js.map +1 -1
- package/dist/routes/eval-overrides.d.ts +18 -0
- package/dist/routes/eval-overrides.d.ts.map +1 -0
- package/dist/routes/eval-overrides.js +81 -0
- package/dist/routes/eval-overrides.js.map +1 -0
- package/dist/routes/eval-runs.d.ts +10 -1
- package/dist/routes/eval-runs.d.ts.map +1 -1
- package/dist/routes/eval-runs.js +63 -7
- package/dist/routes/eval-runs.js.map +1 -1
- package/dist/routes/eval-suites.d.ts.map +1 -1
- package/dist/routes/eval-suites.js +20 -1
- package/dist/routes/eval-suites.js.map +1 -1
- package/dist/routes/event-triggers.d.ts +5 -1
- package/dist/routes/event-triggers.d.ts.map +1 -1
- package/dist/routes/event-triggers.js +26 -3
- package/dist/routes/event-triggers.js.map +1 -1
- package/dist/routes/export-signing-keys.d.ts +12 -0
- package/dist/routes/export-signing-keys.d.ts.map +1 -0
- package/dist/routes/export-signing-keys.js +24 -0
- package/dist/routes/export-signing-keys.js.map +1 -0
- package/dist/routes/flows.d.ts.map +1 -1
- package/dist/routes/flows.js +9 -1
- package/dist/routes/flows.js.map +1 -1
- package/dist/routes/gate-policies.d.ts +4 -1
- package/dist/routes/gate-policies.d.ts.map +1 -1
- package/dist/routes/gate-policies.js +29 -5
- package/dist/routes/gate-policies.js.map +1 -1
- package/dist/routes/guardrails.d.ts +16 -14
- package/dist/routes/guardrails.d.ts.map +1 -1
- package/dist/routes/guardrails.js +39 -3
- package/dist/routes/guardrails.js.map +1 -1
- package/dist/routes/identity.d.ts +20 -4
- package/dist/routes/identity.d.ts.map +1 -1
- package/dist/routes/identity.js +246 -6
- package/dist/routes/identity.js.map +1 -1
- package/dist/routes/improvement-passes.d.ts +52 -0
- package/dist/routes/improvement-passes.d.ts.map +1 -0
- package/dist/routes/improvement-passes.js +449 -0
- package/dist/routes/improvement-passes.js.map +1 -0
- package/dist/routes/judged-suites.d.ts +50 -0
- package/dist/routes/judged-suites.d.ts.map +1 -1
- package/dist/routes/judged-suites.js +66 -27
- package/dist/routes/judged-suites.js.map +1 -1
- package/dist/routes/judgment-context.d.ts +18 -2
- package/dist/routes/judgment-context.d.ts.map +1 -1
- package/dist/routes/judgment-context.js +63 -5
- package/dist/routes/judgment-context.js.map +1 -1
- package/dist/routes/judgment-flow-context.d.ts.map +1 -1
- package/dist/routes/judgment-flow-context.js +14 -2
- package/dist/routes/judgment-flow-context.js.map +1 -1
- package/dist/routes/judgments.d.ts.map +1 -1
- package/dist/routes/judgments.js +8 -1
- package/dist/routes/judgments.js.map +1 -1
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +26 -1
- package/dist/routes/mcp.js.map +1 -1
- package/dist/routes/memory-access.d.ts +43 -0
- package/dist/routes/memory-access.d.ts.map +1 -0
- package/dist/routes/memory-access.js +129 -0
- package/dist/routes/memory-access.js.map +1 -0
- package/dist/routes/memory-erasures.d.ts +25 -0
- package/dist/routes/memory-erasures.d.ts.map +1 -0
- package/dist/routes/memory-erasures.js +214 -0
- package/dist/routes/memory-erasures.js.map +1 -0
- package/dist/routes/memory-parse.d.ts +38 -0
- package/dist/routes/memory-parse.d.ts.map +1 -0
- package/dist/routes/memory-parse.js +199 -0
- package/dist/routes/memory-parse.js.map +1 -0
- package/dist/routes/memory.d.ts +9 -4
- package/dist/routes/memory.d.ts.map +1 -1
- package/dist/routes/memory.js +226 -234
- package/dist/routes/memory.js.map +1 -1
- package/dist/routes/observations.d.ts +4 -1
- package/dist/routes/observations.d.ts.map +1 -1
- package/dist/routes/observations.js +8 -2
- package/dist/routes/observations.js.map +1 -1
- package/dist/routes/pagination.d.ts +7 -0
- package/dist/routes/pagination.d.ts.map +1 -1
- package/dist/routes/pagination.js +10 -0
- package/dist/routes/pagination.js.map +1 -1
- package/dist/routes/policies.d.ts +2 -1
- package/dist/routes/policies.d.ts.map +1 -1
- package/dist/routes/policies.js +3 -1
- package/dist/routes/policies.js.map +1 -1
- package/dist/routes/project-mismatch.d.ts +22 -0
- package/dist/routes/project-mismatch.d.ts.map +1 -0
- package/dist/routes/project-mismatch.js +34 -0
- package/dist/routes/project-mismatch.js.map +1 -0
- package/dist/routes/projects.d.ts +15 -4
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +100 -9
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/proposals.d.ts +25 -17
- package/dist/routes/proposals.d.ts.map +1 -1
- package/dist/routes/proposals.js +340 -507
- package/dist/routes/proposals.js.map +1 -1
- package/dist/routes/provenance.d.ts +17 -3
- package/dist/routes/provenance.d.ts.map +1 -1
- package/dist/routes/provenance.js +79 -103
- package/dist/routes/provenance.js.map +1 -1
- package/dist/routes/providers.d.ts +17 -1
- package/dist/routes/providers.d.ts.map +1 -1
- package/dist/routes/providers.js +188 -8
- package/dist/routes/providers.js.map +1 -1
- package/dist/routes/public-run-tokens.d.ts.map +1 -1
- package/dist/routes/public-run-tokens.js +3 -0
- package/dist/routes/public-run-tokens.js.map +1 -1
- package/dist/routes/runs.d.ts +10 -0
- package/dist/routes/runs.d.ts.map +1 -1
- package/dist/routes/runs.js +92 -42
- package/dist/routes/runs.js.map +1 -1
- package/dist/routes/schedules.d.ts +21 -13
- package/dist/routes/schedules.d.ts.map +1 -1
- package/dist/routes/schedules.js +416 -55
- package/dist/routes/schedules.js.map +1 -1
- package/dist/routes/segments.d.ts +2 -0
- package/dist/routes/segments.d.ts.map +1 -1
- package/dist/routes/segments.js +5 -0
- package/dist/routes/segments.js.map +1 -1
- package/dist/routes/service-accounts.d.ts +17 -0
- package/dist/routes/service-accounts.d.ts.map +1 -0
- package/dist/routes/service-accounts.js +212 -0
- package/dist/routes/service-accounts.js.map +1 -0
- package/dist/routes/sign-in-options.d.ts +50 -0
- package/dist/routes/sign-in-options.d.ts.map +1 -0
- package/dist/routes/sign-in-options.js +98 -0
- package/dist/routes/sign-in-options.js.map +1 -0
- package/dist/routes/signing-keys.d.ts +2 -1
- package/dist/routes/signing-keys.d.ts.map +1 -1
- package/dist/routes/signing-keys.js +3 -1
- package/dist/routes/signing-keys.js.map +1 -1
- package/dist/routes/tenant-access.d.ts +13 -0
- package/dist/routes/tenant-access.d.ts.map +1 -0
- package/dist/routes/tenant-access.js +26 -0
- package/dist/routes/tenant-access.js.map +1 -0
- package/dist/routes/tenant.d.ts.map +1 -1
- package/dist/routes/tenant.js +4 -0
- package/dist/routes/tenant.js.map +1 -1
- package/dist/routes/token-sign-in.d.ts +36 -0
- package/dist/routes/token-sign-in.d.ts.map +1 -0
- package/dist/routes/token-sign-in.js +101 -0
- package/dist/routes/token-sign-in.js.map +1 -0
- package/dist/routes/tokens.d.ts +15 -5
- package/dist/routes/tokens.d.ts.map +1 -1
- package/dist/routes/tokens.js +162 -43
- package/dist/routes/tokens.js.map +1 -1
- package/dist/routes/tools.d.ts.map +1 -1
- package/dist/routes/tools.js +9 -1
- package/dist/routes/tools.js.map +1 -1
- package/dist/routes/trigger-access.d.ts +29 -0
- package/dist/routes/trigger-access.d.ts.map +1 -0
- package/dist/routes/trigger-access.js +33 -0
- package/dist/routes/trigger-access.js.map +1 -0
- package/dist/routes/webhook-endpoints.d.ts +2 -1
- package/dist/routes/webhook-endpoints.d.ts.map +1 -1
- package/dist/routes/webhook-endpoints.js +11 -3
- package/dist/routes/webhook-endpoints.js.map +1 -1
- package/dist/routes/webhooks.d.ts +5 -1
- package/dist/routes/webhooks.d.ts.map +1 -1
- package/dist/routes/webhooks.js +25 -2
- package/dist/routes/webhooks.js.map +1 -1
- package/dist/run-failure.d.ts +21 -0
- package/dist/run-failure.d.ts.map +1 -0
- package/dist/run-failure.js +29 -0
- package/dist/run-failure.js.map +1 -0
- package/dist/service-account-binding.d.ts +108 -0
- package/dist/service-account-binding.d.ts.map +1 -0
- package/dist/service-account-binding.js +4 -0
- package/dist/service-account-binding.js.map +1 -0
- package/dist/session-store-binding.d.ts +61 -13
- package/dist/session-store-binding.d.ts.map +1 -1
- package/dist/signed-export.d.ts +89 -0
- package/dist/signed-export.d.ts.map +1 -0
- package/dist/signed-export.js +149 -0
- package/dist/signed-export.js.map +1 -0
- package/dist/supervisor-binding.d.ts +186 -413
- package/dist/supervisor-binding.d.ts.map +1 -1
- package/dist/testing/app-bindings.d.ts +33 -0
- package/dist/testing/app-bindings.d.ts.map +1 -0
- package/dist/testing/app-bindings.js +112 -0
- package/dist/testing/app-bindings.js.map +1 -0
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +13 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/stub-binding.d.ts +34 -0
- package/dist/testing/stub-binding.d.ts.map +1 -0
- package/dist/testing/stub-binding.js +42 -0
- package/dist/testing/stub-binding.js.map +1 -0
- package/dist/testing/trigger-registry.d.ts +21 -0
- package/dist/testing/trigger-registry.d.ts.map +1 -0
- package/dist/testing/trigger-registry.js +206 -0
- package/dist/testing/trigger-registry.js.map +1 -0
- package/dist/token-admin.d.ts +46 -8
- package/dist/token-admin.d.ts.map +1 -1
- package/dist/token-admin.js.map +1 -1
- package/dist/tool-binding.d.ts +13 -0
- package/dist/tool-binding.d.ts.map +1 -1
- package/dist/trigger-binding.d.ts +2 -2
- package/dist/trigger-binding.d.ts.map +1 -1
- package/dist/trigger-binding.js +1 -1
- package/dist/trigger-binding.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/webhook-endpoint-binding.d.ts +19 -3
- package/dist/webhook-endpoint-binding.d.ts.map +1 -1
- package/dist/webhook-endpoint-binding.js +1 -1
- package/dist/webhook-endpoint-binding.js.map +1 -1
- package/openapi.json +15286 -8653
- package/package.json +26 -22
- package/src/agent-binding.ts +14 -0
- package/src/agent-pins.ts +18 -2
- package/src/app.ts +366 -80
- package/src/block-publish.ts +181 -0
- package/src/caller.ts +62 -0
- package/src/capability-binding.ts +12 -0
- package/src/derive-agent-version.ts +9 -1
- package/src/errors.ts +73 -7
- package/src/eval-case-binding.ts +17 -1
- package/src/eval-run-binding.ts +31 -0
- package/src/eval-run-dispatcher.ts +7 -0
- package/src/eval-sample.ts +42 -0
- package/src/eval-suite-binding.ts +14 -0
- package/src/flow-binding.ts +19 -0
- package/src/flow-pins.ts +18 -2
- package/src/gate.ts +26 -0
- package/src/handler-binding.ts +36 -1
- package/src/hitl-binding.ts +24 -0
- package/src/identity-directory-binding.ts +85 -4
- package/src/identity-provider-binding.ts +216 -21
- package/src/improvement-pass-binding.ts +193 -0
- package/src/index.ts +153 -31
- package/src/judged-dispatcher.ts +78 -11
- package/src/judgment-binding.ts +25 -1
- package/src/mcp-endpoint-binding.ts +7 -0
- package/src/memory-binding.ts +121 -17
- package/src/memory-erasure-binding.ts +156 -0
- package/src/middleware/auth.ts +228 -62
- package/src/middleware/authorize.ts +139 -3
- package/src/middleware/error-mapper.ts +15 -1
- package/src/middleware/idempotency.ts +230 -43
- package/src/middleware/key-project.ts +86 -0
- package/src/middleware/principal.ts +9 -5
- package/src/middleware/project-ref.ts +3 -0
- package/src/openapi/generate.ts +11 -2
- package/src/openapi/operations.ts +1059 -142
- package/src/openapi/schemas.ts +2438 -485
- package/src/person-grants-binding.ts +76 -0
- package/src/proposal-service.ts +640 -0
- package/src/proposal-status.ts +176 -0
- package/src/provider-binding.ts +10 -0
- package/src/publish-refused.ts +38 -9
- package/src/routes/adapters.ts +4 -0
- package/src/routes/agent-releases.ts +121 -69
- package/src/routes/agents.ts +128 -1
- package/src/routes/approvals.ts +164 -154
- package/src/routes/artifacts.ts +181 -11
- package/src/routes/auth.ts +804 -336
- package/src/routes/blocks.ts +2 -53
- package/src/routes/capabilities.ts +10 -1
- package/src/routes/compliance.ts +60 -99
- package/src/routes/conversations.ts +101 -7
- package/src/routes/cost.ts +32 -3
- package/src/routes/denied.ts +28 -0
- package/src/routes/deployments.ts +62 -16
- package/src/routes/eval-comparison.ts +81 -2
- package/src/routes/eval-overrides.ts +108 -0
- package/src/routes/eval-runs.ts +86 -6
- package/src/routes/eval-suites.ts +25 -1
- package/src/routes/event-triggers.ts +27 -3
- package/src/routes/export-signing-keys.ts +31 -0
- package/src/routes/flows.ts +12 -1
- package/src/routes/gate-policies.ts +37 -6
- package/src/routes/guardrails.ts +61 -2
- package/src/routes/identity.ts +328 -10
- package/src/routes/improvement-passes.ts +541 -0
- package/src/routes/judged-suites.ts +113 -43
- package/src/routes/judgment-context.ts +76 -5
- package/src/routes/judgment-flow-context.ts +16 -2
- package/src/routes/judgments.ts +17 -3
- package/src/routes/mcp.ts +29 -1
- package/src/routes/memory-access.ts +179 -0
- package/src/routes/memory-erasures.ts +240 -0
- package/src/routes/memory-parse.ts +250 -0
- package/src/routes/memory.ts +244 -286
- package/src/routes/observations.ts +15 -2
- package/src/routes/pagination.ts +12 -0
- package/src/routes/policies.ts +7 -1
- package/src/routes/project-mismatch.ts +56 -0
- package/src/routes/projects.ts +107 -13
- package/src/routes/proposals.ts +370 -611
- package/src/routes/provenance.ts +99 -133
- package/src/routes/providers.ts +223 -8
- package/src/routes/public-run-tokens.ts +3 -0
- package/src/routes/runs.ts +119 -39
- package/src/routes/schedules.ts +472 -60
- package/src/routes/segments.ts +11 -0
- package/src/routes/service-accounts.ts +262 -0
- package/src/routes/sign-in-options.ts +168 -0
- package/src/routes/signing-keys.ts +7 -1
- package/src/routes/tenant-access.ts +37 -0
- package/src/routes/tenant.ts +6 -0
- package/src/routes/token-sign-in.ts +161 -0
- package/src/routes/tokens.ts +172 -46
- package/src/routes/tools.ts +12 -1
- package/src/routes/trigger-access.ts +72 -0
- package/src/routes/webhook-endpoints.ts +15 -3
- package/src/routes/webhooks.ts +26 -2
- package/src/run-failure.ts +42 -0
- package/src/service-account-binding.ts +113 -0
- package/src/session-store-binding.ts +65 -13
- package/src/signed-export.ts +250 -0
- package/src/supervisor-binding.ts +169 -409
- package/src/testing/app-bindings.ts +142 -0
- package/src/testing/index.ts +21 -0
- package/src/testing/stub-binding.ts +53 -0
- package/src/testing/trigger-registry.ts +259 -0
- package/src/token-admin.ts +40 -8
- package/src/tool-binding.ts +14 -0
- package/src/trigger-binding.ts +8 -1
- package/src/types.ts +16 -0
- package/src/webhook-endpoint-binding.ts +18 -3
|
@@ -25,7 +25,7 @@ const IdempotencyKeyParam = {
|
|
|
25
25
|
name: 'Idempotency-Key',
|
|
26
26
|
in: 'header',
|
|
27
27
|
required: false,
|
|
28
|
-
description:
|
|
28
|
+
description: "Caller-supplied idempotency key, scoped to the caller: the same key from someone else in the tenant is their own request (from 0.1.5). Retries with the same key return the original response byte-identical (per `docs/API-ROUTE-CONVENTIONS.md` §3.1). A retry sent while the first request still runs is answered `409 idempotency-key-in-flight` with `Retry-After`, on a runtime whose store holds keys (from 0.1.5); retry after it, and you get the first request's answer. An answer that carries a secret (a new API key or public run token, a session token, a generated signing secret) isn't kept: a retry gets `409 idempotency-key-replay-withheld`, with the first request's status and when it succeeded (from 0.1.5).",
|
|
29
29
|
schema: { type: 'string', minLength: 1 },
|
|
30
30
|
};
|
|
31
31
|
const RunIdPathParam = {
|
|
@@ -42,6 +42,13 @@ const TokenIdPathParam = {
|
|
|
42
42
|
description: 'ApiTokenId — opaque branded string (a UUID).',
|
|
43
43
|
schema: { type: 'string', format: 'uuid' },
|
|
44
44
|
};
|
|
45
|
+
const ServiceAccountIdPathParam = {
|
|
46
|
+
name: 'serviceAccountId',
|
|
47
|
+
in: 'path',
|
|
48
|
+
required: true,
|
|
49
|
+
description: 'The service account id.',
|
|
50
|
+
schema: { type: 'string' },
|
|
51
|
+
};
|
|
45
52
|
const SigningKeyIdPathParam = {
|
|
46
53
|
name: 'keyId',
|
|
47
54
|
in: 'path',
|
|
@@ -105,6 +112,13 @@ const RunEvalRunIdQueryParam = {
|
|
|
105
112
|
description: 'Only the replay runs of this eval run. Implies replays are included; cannot be combined with `replays=exclude`.',
|
|
106
113
|
schema: { type: 'string', minLength: 1 },
|
|
107
114
|
};
|
|
115
|
+
const RunTriggerIdQueryParam = {
|
|
116
|
+
name: 'triggerId',
|
|
117
|
+
in: 'query',
|
|
118
|
+
required: false,
|
|
119
|
+
description: 'Only the runs this trigger started (`Run.trigger.triggerId`).',
|
|
120
|
+
schema: { type: 'string', format: 'uuid' },
|
|
121
|
+
};
|
|
108
122
|
const LiveProjectQueryParam = {
|
|
109
123
|
name: 'projectId',
|
|
110
124
|
in: 'query',
|
|
@@ -355,11 +369,18 @@ const ObservationUntilQueryParam = {
|
|
|
355
369
|
description: 'Only the observations at or before this time (ISO 8601).',
|
|
356
370
|
schema: { type: 'string', format: 'date-time' },
|
|
357
371
|
};
|
|
372
|
+
const ErasureIdPathParam = {
|
|
373
|
+
name: 'erasureId',
|
|
374
|
+
in: 'path',
|
|
375
|
+
required: true,
|
|
376
|
+
description: 'The erasure (a UUID).',
|
|
377
|
+
schema: { type: 'string', format: 'uuid' },
|
|
378
|
+
};
|
|
358
379
|
const FactIdPathParam = {
|
|
359
380
|
name: 'factId',
|
|
360
381
|
in: 'path',
|
|
361
382
|
required: true,
|
|
362
|
-
description: '
|
|
383
|
+
description: 'The fact id (kept across revisions).',
|
|
363
384
|
schema: { type: 'string' },
|
|
364
385
|
};
|
|
365
386
|
const FactTypeQueryParam = {
|
|
@@ -376,6 +397,27 @@ const FactScopeQueryParam = {
|
|
|
376
397
|
description: 'JSON-encoded partial scope object. Every provided key must match. Example: `%7B%22projectId%22%3A%22...%22%7D`.',
|
|
377
398
|
schema: { type: 'string' },
|
|
378
399
|
};
|
|
400
|
+
const FactAsOfQueryParam = {
|
|
401
|
+
name: 'asOf',
|
|
402
|
+
in: 'query',
|
|
403
|
+
required: false,
|
|
404
|
+
description: 'Read memory as it stood at this time (ISO 8601): the revision that was current then, including one since superseded or deleted.',
|
|
405
|
+
schema: { type: 'string', format: 'date-time' },
|
|
406
|
+
};
|
|
407
|
+
const FactVersionQueryParam = {
|
|
408
|
+
name: 'version',
|
|
409
|
+
in: 'query',
|
|
410
|
+
required: false,
|
|
411
|
+
description: 'A revision number: that revision, current or not.',
|
|
412
|
+
schema: { type: 'integer', minimum: 1 },
|
|
413
|
+
};
|
|
414
|
+
const FactExpectVersionQueryParam = {
|
|
415
|
+
name: 'expectVersion',
|
|
416
|
+
in: 'query',
|
|
417
|
+
required: false,
|
|
418
|
+
description: 'Only if the current revision is still this one; otherwise `409 fact-changed` with `currentVersion`.',
|
|
419
|
+
schema: { type: 'integer', minimum: 1 },
|
|
420
|
+
};
|
|
379
421
|
// ---------------- scope triplet ----------------
|
|
380
422
|
//
|
|
381
423
|
// Shared parameters for the `?scopeKind + ?scopeId + ?inherit` filter.
|
|
@@ -404,18 +446,18 @@ const InheritQueryParam = {
|
|
|
404
446
|
description: 'Default `true`. `false` = literal-at-this-scope only (admin/audit view). Load-bearing for policy/config-scoped resources (mcp-endpoints); documented no-op for content-scoped resources (agents/flows/tools/...).',
|
|
405
447
|
schema: { type: 'boolean', default: true },
|
|
406
448
|
};
|
|
407
|
-
const
|
|
408
|
-
name: '
|
|
409
|
-
in: '
|
|
449
|
+
const ImprovementPassIdPathParam = {
|
|
450
|
+
name: 'passId',
|
|
451
|
+
in: 'path',
|
|
410
452
|
required: true,
|
|
411
|
-
description: '
|
|
412
|
-
schema: { type: 'string',
|
|
453
|
+
description: 'The improvement pass id (a UUID).',
|
|
454
|
+
schema: { type: 'string', format: 'uuid' },
|
|
413
455
|
};
|
|
414
456
|
const ProposalIdPathParam = {
|
|
415
457
|
name: 'proposalId',
|
|
416
458
|
in: 'path',
|
|
417
459
|
required: true,
|
|
418
|
-
description: '
|
|
460
|
+
description: 'The proposal id (a UUID).',
|
|
419
461
|
schema: { type: 'string', format: 'uuid' },
|
|
420
462
|
};
|
|
421
463
|
const ProvenanceRunIdQueryParam = {
|
|
@@ -443,14 +485,14 @@ const ProposalStatusQueryParam = {
|
|
|
443
485
|
name: 'status',
|
|
444
486
|
in: 'query',
|
|
445
487
|
required: false,
|
|
446
|
-
description: '
|
|
488
|
+
description: 'Only proposals with this (derived) status.',
|
|
447
489
|
schema: { $ref: '#/components/schemas/FixProposalStatus' },
|
|
448
490
|
};
|
|
449
491
|
const ProposalTierQueryParam = {
|
|
450
492
|
name: 'tier',
|
|
451
493
|
in: 'query',
|
|
452
494
|
required: false,
|
|
453
|
-
description: '
|
|
495
|
+
description: 'Only proposals of this tier.',
|
|
454
496
|
schema: { $ref: '#/components/schemas/ProposalTier' },
|
|
455
497
|
};
|
|
456
498
|
// Admin plane — capabilities + providers.
|
|
@@ -995,6 +1037,7 @@ export const OPERATIONS = [
|
|
|
995
1037
|
...CommonMutationErrors,
|
|
996
1038
|
'404': ErrorResponse('Agent or flow not found; or `projectId` names no project of this tenant (`project-not-found`).'),
|
|
997
1039
|
'422': ErrorResponse('Guardrail violation or budget exceeded.'),
|
|
1040
|
+
'409': ErrorResponse("Idempotency-Key was reused with a different body; or an erasure of the turn's person (its conversation or its `participantId`) is in progress (`erasure-in-progress`): no new turn starts for them until it completes."),
|
|
998
1041
|
'400': ErrorResponse("Malformed request body, or the body's `projectId` isn't a project id (a UUID)."),
|
|
999
1042
|
},
|
|
1000
1043
|
},
|
|
@@ -1017,6 +1060,7 @@ export const OPERATIONS = [
|
|
|
1017
1060
|
RunAgentIdQueryParam,
|
|
1018
1061
|
RunReplaysQueryParam,
|
|
1019
1062
|
RunEvalRunIdQueryParam,
|
|
1063
|
+
RunTriggerIdQueryParam,
|
|
1020
1064
|
RunIncludeQueryParam,
|
|
1021
1065
|
],
|
|
1022
1066
|
responses: {
|
|
@@ -1242,7 +1286,7 @@ export const OPERATIONS = [
|
|
|
1242
1286
|
openapiPath: '/v1/tokens',
|
|
1243
1287
|
operationId: 'tokens.mint',
|
|
1244
1288
|
summary: 'Mint an API key',
|
|
1245
|
-
description:
|
|
1289
|
+
description: "An API key acts for one principal (`for`: a person or a service account; default the caller), with that principal's grants. Its `role` is a ceiling under them and its `projectId` a limit. Returns the plaintext token exactly once. A person or a service account's key mints its own keys; only a tenant admin mints for someone else, or an `admin` key. A caller can only grant capabilities it holds, and a key limited to a project mints only keys limited to it. Only mounted when the deployment supplies a `TokenAdmin`.",
|
|
1246
1290
|
tags: ['tokens'],
|
|
1247
1291
|
security: 'bearer',
|
|
1248
1292
|
parameters: [IdempotencyKeyParam],
|
|
@@ -1250,9 +1294,10 @@ export const OPERATIONS = [
|
|
|
1250
1294
|
responses: {
|
|
1251
1295
|
'201': { description: 'Token minted.', schema: ref('MintTokenResult') },
|
|
1252
1296
|
...CommonMutationErrors,
|
|
1253
|
-
'
|
|
1297
|
+
'409': ErrorResponse("Idempotency-Key reused with a different body (`idempotency-key-body-mismatch`), or a retry of a request that succeeded: its answer carried a secret, which isn't kept (`idempotency-key-replay-withheld`, with its `status` and `at`)."),
|
|
1298
|
+
'403': ErrorResponse("Not a tenant admin where one is needed, or a capability the caller does not hold (`permission-denied`); an `admin` key for a principal that isn't a tenant admin (`role-exceeds-principal`); a key limited to a project minting for another (`key-project-mismatch`)."),
|
|
1254
1299
|
'400': ErrorResponse("Malformed request body, or the body's `projectId` isn't a project id (a UUID)."),
|
|
1255
|
-
'404': ErrorResponse("The body's `projectId` names no project of this tenant (`project-not-found`)."),
|
|
1300
|
+
'404': ErrorResponse("The body's `projectId` names no project of this tenant (`project-not-found`), or `for` names no person or service account (`principal-not-found`)."),
|
|
1256
1301
|
},
|
|
1257
1302
|
},
|
|
1258
1303
|
{
|
|
@@ -1261,15 +1306,25 @@ export const OPERATIONS = [
|
|
|
1261
1306
|
openapiPath: '/v1/tokens',
|
|
1262
1307
|
operationId: 'tokens.list',
|
|
1263
1308
|
summary: 'List API keys',
|
|
1264
|
-
description:
|
|
1309
|
+
description: "Newest first. Never returns secrets. A tenant admin sees every key (`?principal=` for one principal's); anyone else sees their own.",
|
|
1265
1310
|
tags: ['tokens'],
|
|
1266
1311
|
security: 'bearer',
|
|
1267
|
-
parameters: [
|
|
1312
|
+
parameters: [
|
|
1313
|
+
CursorQueryParam,
|
|
1314
|
+
LimitQueryParam,
|
|
1315
|
+
{
|
|
1316
|
+
name: 'principal',
|
|
1317
|
+
in: 'query',
|
|
1318
|
+
required: false,
|
|
1319
|
+
description: "Tenant admins: only this principal's keys, `user:<id>` or `service-account:<id>`.",
|
|
1320
|
+
schema: { type: 'string' },
|
|
1321
|
+
},
|
|
1322
|
+
],
|
|
1268
1323
|
responses: {
|
|
1269
1324
|
'200': { description: 'A page of keys.', schema: ref('ApiTokenPage') },
|
|
1270
1325
|
...CommonAuthErrors,
|
|
1271
|
-
'400': ErrorResponse('Malformed cursor
|
|
1272
|
-
'403': ErrorResponse('
|
|
1326
|
+
'400': ErrorResponse('Malformed cursor or `principal`.'),
|
|
1327
|
+
'403': ErrorResponse('A caller with no keys of its own that is not a tenant admin.'),
|
|
1273
1328
|
},
|
|
1274
1329
|
},
|
|
1275
1330
|
{
|
|
@@ -1278,15 +1333,15 @@ export const OPERATIONS = [
|
|
|
1278
1333
|
openapiPath: '/v1/tokens/{tokenId}',
|
|
1279
1334
|
operationId: 'tokens.get',
|
|
1280
1335
|
summary: 'Read an API key',
|
|
1281
|
-
description:
|
|
1336
|
+
description: "Never returns the secret. A tenant admin reads any key; anyone else only their own (someone else's reads as missing).",
|
|
1282
1337
|
tags: ['tokens'],
|
|
1283
1338
|
security: 'bearer',
|
|
1284
1339
|
parameters: [TokenIdPathParam],
|
|
1285
1340
|
responses: {
|
|
1286
1341
|
'200': { description: 'The key.', schema: ref('ApiToken') },
|
|
1287
1342
|
...CommonAuthErrors,
|
|
1288
|
-
'403': ErrorResponse('
|
|
1289
|
-
'404': ErrorResponse('No token with that id
|
|
1343
|
+
'403': ErrorResponse('A caller with no keys of its own that is not a tenant admin.'),
|
|
1344
|
+
'404': ErrorResponse('No token with that id that the caller may see.'),
|
|
1290
1345
|
},
|
|
1291
1346
|
},
|
|
1292
1347
|
{
|
|
@@ -1295,15 +1350,132 @@ export const OPERATIONS = [
|
|
|
1295
1350
|
openapiPath: '/v1/tokens/{tokenId}/revoke',
|
|
1296
1351
|
operationId: 'tokens.revoke',
|
|
1297
1352
|
summary: 'Revoke an API key',
|
|
1298
|
-
description: 'Takes effect on the next request.
|
|
1353
|
+
description: 'Takes effect on the next request. A tenant admin revokes any key; anyone else only their own.',
|
|
1299
1354
|
tags: ['tokens'],
|
|
1300
1355
|
security: 'bearer',
|
|
1301
1356
|
parameters: [TokenIdPathParam, IdempotencyKeyParam],
|
|
1302
1357
|
responses: {
|
|
1303
1358
|
'200': { description: 'Revoked.', schema: ref('RevokeTokenResult') },
|
|
1304
1359
|
...CommonMutationErrors,
|
|
1360
|
+
'403': ErrorResponse('A caller with no keys of its own that is not a tenant admin.'),
|
|
1361
|
+
'404': ErrorResponse('No token with that id that the caller may see.'),
|
|
1362
|
+
},
|
|
1363
|
+
},
|
|
1364
|
+
// ---------- service accounts ----------
|
|
1365
|
+
{
|
|
1366
|
+
method: 'post',
|
|
1367
|
+
honoPath: '/v1/service-accounts',
|
|
1368
|
+
openapiPath: '/v1/service-accounts',
|
|
1369
|
+
operationId: 'serviceAccounts.create',
|
|
1370
|
+
summary: 'Create a service account',
|
|
1371
|
+
description: "A named, non-human principal with its first grants, written before it is returned. It isn't a tenant member unless a grant makes it one (`{kind: 'tenant-member'}`: read the tenant's settings); give it only what its job needs. Mint its keys at `POST /v1/tokens` with `for`. Tenant admins only. Mounted when the deployment supplies a `ServiceAccountBinding`.",
|
|
1372
|
+
tags: ['service-accounts'],
|
|
1373
|
+
security: 'bearer',
|
|
1374
|
+
parameters: [IdempotencyKeyParam],
|
|
1375
|
+
requestBody: { required: true, schema: ref('CreateServiceAccountBody') },
|
|
1376
|
+
responses: {
|
|
1377
|
+
'201': { description: 'Created.', schema: ref('ServiceAccount') },
|
|
1378
|
+
...CommonMutationErrors,
|
|
1305
1379
|
'403': ErrorResponse('Not a tenant admin.'),
|
|
1306
|
-
'404': ErrorResponse('
|
|
1380
|
+
'404': ErrorResponse('A grant names no project of this tenant (`project-not-found`).'),
|
|
1381
|
+
'409': ErrorResponse('An active service account has the name (`service-account-name-taken`), or an idempotency conflict.'),
|
|
1382
|
+
},
|
|
1383
|
+
},
|
|
1384
|
+
{
|
|
1385
|
+
method: 'get',
|
|
1386
|
+
honoPath: '/v1/service-accounts',
|
|
1387
|
+
openapiPath: '/v1/service-accounts',
|
|
1388
|
+
operationId: 'serviceAccounts.list',
|
|
1389
|
+
summary: 'List service accounts',
|
|
1390
|
+
description: 'Oldest first; active only unless `?includeUnregistered=true`. Tenant admins only.',
|
|
1391
|
+
tags: ['service-accounts'],
|
|
1392
|
+
security: 'bearer',
|
|
1393
|
+
parameters: [
|
|
1394
|
+
CursorQueryParam,
|
|
1395
|
+
LimitQueryParam,
|
|
1396
|
+
{
|
|
1397
|
+
name: 'includeUnregistered',
|
|
1398
|
+
in: 'query',
|
|
1399
|
+
required: false,
|
|
1400
|
+
description: '`true`: unregistered accounts too.',
|
|
1401
|
+
schema: { type: 'string', enum: ['true', 'false'] },
|
|
1402
|
+
},
|
|
1403
|
+
],
|
|
1404
|
+
responses: {
|
|
1405
|
+
'200': { description: 'A page of service accounts.', schema: ref('ServiceAccountPage') },
|
|
1406
|
+
...CommonAuthErrors,
|
|
1407
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
1408
|
+
},
|
|
1409
|
+
},
|
|
1410
|
+
{
|
|
1411
|
+
method: 'get',
|
|
1412
|
+
honoPath: '/v1/service-accounts/:serviceAccountId',
|
|
1413
|
+
openapiPath: '/v1/service-accounts/{serviceAccountId}',
|
|
1414
|
+
operationId: 'serviceAccounts.get',
|
|
1415
|
+
summary: 'Read a service account',
|
|
1416
|
+
description: 'Unregistered ones too. Tenant admins only.',
|
|
1417
|
+
tags: ['service-accounts'],
|
|
1418
|
+
security: 'bearer',
|
|
1419
|
+
parameters: [ServiceAccountIdPathParam],
|
|
1420
|
+
responses: {
|
|
1421
|
+
'200': { description: 'The service account.', schema: ref('ServiceAccount') },
|
|
1422
|
+
...CommonAuthErrors,
|
|
1423
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
1424
|
+
'404': ErrorResponse('No such service account (`service-account-not-found`).'),
|
|
1425
|
+
},
|
|
1426
|
+
},
|
|
1427
|
+
{
|
|
1428
|
+
method: 'post',
|
|
1429
|
+
honoPath: '/v1/service-accounts/:serviceAccountId/grant',
|
|
1430
|
+
openapiPath: '/v1/service-accounts/{serviceAccountId}/grant',
|
|
1431
|
+
operationId: 'serviceAccounts.grant',
|
|
1432
|
+
summary: 'Grant a service account',
|
|
1433
|
+
description: "Tenant admin, or a role on a project (replacing the account's role there). Written before the call answers. Tenant admins only.",
|
|
1434
|
+
tags: ['service-accounts'],
|
|
1435
|
+
security: 'bearer',
|
|
1436
|
+
parameters: [ServiceAccountIdPathParam, IdempotencyKeyParam],
|
|
1437
|
+
requestBody: { required: true, schema: ref('ServiceAccountGrantBody') },
|
|
1438
|
+
responses: {
|
|
1439
|
+
'200': { description: 'The account, with its grants.', schema: ref('ServiceAccount') },
|
|
1440
|
+
...CommonMutationErrors,
|
|
1441
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
1442
|
+
'404': ErrorResponse('No such service account (`service-account-not-found`), or no such project (`project-not-found`).'),
|
|
1443
|
+
'409': ErrorResponse('The account is unregistered (`service-account-unregistered`), or an idempotency conflict.'),
|
|
1444
|
+
},
|
|
1445
|
+
},
|
|
1446
|
+
{
|
|
1447
|
+
method: 'post',
|
|
1448
|
+
honoPath: '/v1/service-accounts/:serviceAccountId/ungrant',
|
|
1449
|
+
openapiPath: '/v1/service-accounts/{serviceAccountId}/ungrant',
|
|
1450
|
+
operationId: 'serviceAccounts.ungrant',
|
|
1451
|
+
summary: 'Remove a grant from a service account',
|
|
1452
|
+
description: 'A no-op when the account does not hold it. Tenant admins only.',
|
|
1453
|
+
tags: ['service-accounts'],
|
|
1454
|
+
security: 'bearer',
|
|
1455
|
+
parameters: [ServiceAccountIdPathParam, IdempotencyKeyParam],
|
|
1456
|
+
requestBody: { required: true, schema: ref('ServiceAccountUngrantBody') },
|
|
1457
|
+
responses: {
|
|
1458
|
+
'200': { description: 'The account, with its grants.', schema: ref('ServiceAccount') },
|
|
1459
|
+
...CommonMutationErrors,
|
|
1460
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
1461
|
+
'404': ErrorResponse('No such service account (`service-account-not-found`).'),
|
|
1462
|
+
},
|
|
1463
|
+
},
|
|
1464
|
+
{
|
|
1465
|
+
method: 'post',
|
|
1466
|
+
honoPath: '/v1/service-accounts/:serviceAccountId/unregister',
|
|
1467
|
+
openapiPath: '/v1/service-accounts/{serviceAccountId}/unregister',
|
|
1468
|
+
operationId: 'serviceAccounts.unregister',
|
|
1469
|
+
summary: 'Unregister a service account',
|
|
1470
|
+
description: 'A tombstone: its grants go and its keys stop working; it stays readable. Idempotent. Tenant admins only.',
|
|
1471
|
+
tags: ['service-accounts'],
|
|
1472
|
+
security: 'bearer',
|
|
1473
|
+
parameters: [ServiceAccountIdPathParam, IdempotencyKeyParam],
|
|
1474
|
+
responses: {
|
|
1475
|
+
'200': { description: 'The unregistered account.', schema: ref('ServiceAccount') },
|
|
1476
|
+
...CommonMutationErrors,
|
|
1477
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
1478
|
+
'404': ErrorResponse('No such service account (`service-account-not-found`).'),
|
|
1307
1479
|
},
|
|
1308
1480
|
},
|
|
1309
1481
|
{
|
|
@@ -1320,6 +1492,7 @@ export const OPERATIONS = [
|
|
|
1320
1492
|
responses: {
|
|
1321
1493
|
'201': { description: 'Token minted.', schema: ref('MintPublicRunTokenResult') },
|
|
1322
1494
|
...CommonMutationErrors,
|
|
1495
|
+
'409': ErrorResponse("Idempotency-Key reused with a different body (`idempotency-key-body-mismatch`), or a retry of a request that succeeded: its answer carried a secret, which isn't kept (`idempotency-key-replay-withheld`, with its `status` and `at`)."),
|
|
1323
1496
|
'400': ErrorResponse('Malformed body, or `expiresInSeconds` above the deployment maximum.'),
|
|
1324
1497
|
'403': ErrorResponse('The caller may not read one of the runs (`permission-denied`).'),
|
|
1325
1498
|
'404': ErrorResponse('A run does not exist under this tenant (`run-not-found`).'),
|
|
@@ -1462,11 +1635,11 @@ export const OPERATIONS = [
|
|
|
1462
1635
|
openapiPath: '/v1/approvals/{approvalId}/audit-bundle',
|
|
1463
1636
|
operationId: 'approvals.auditBundle',
|
|
1464
1637
|
summary: 'Export a signed audit bundle for a decided approval',
|
|
1465
|
-
description: "
|
|
1638
|
+
description: "Signs the approval, its decision and its evidence with the deployment's export key, and records the export (an `export-signed` audit event). The same envelope as the other signed exports, so one verifier reads all three; check `publicKey` against `GET /v1/export-signing-keys`. For a decided approval only (approved, rejected, escalated, expired, withdrawn): a pending one is `409 approval-not-decided`. A deployment with no export key answers `404 signing-not-configured`.",
|
|
1466
1639
|
tags: ['approvals'],
|
|
1467
1640
|
security: 'bearer',
|
|
1468
1641
|
parameters: [ApprovalIdPathParam, IdempotencyKeyParam],
|
|
1469
|
-
requestBody: { required:
|
|
1642
|
+
requestBody: { required: false, schema: ref('ExportAuditBundleBody') },
|
|
1470
1643
|
responses: {
|
|
1471
1644
|
'200': { description: 'Signed audit bundle.', schema: ref('ExportAuditBundleResult') },
|
|
1472
1645
|
...CommonMutationErrors,
|
|
@@ -1547,7 +1720,7 @@ export const OPERATIONS = [
|
|
|
1547
1720
|
},
|
|
1548
1721
|
'201': { description: 'The derived agent version.', schema: ref('Agent') },
|
|
1549
1722
|
...CommonMutationErrors,
|
|
1550
|
-
'409': ErrorResponse("Idempotency-Key was reused with a different body, or resource-state conflict. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead."),
|
|
1723
|
+
'409': ErrorResponse("Idempotency-Key was reused with a different body, or resource-state conflict. Or `agent-project-mismatch`: the agent belongs to another project than the body's `projectId` (agents never move; the message doesn't name the project). Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead."),
|
|
1551
1724
|
'400': ErrorResponse("`validation-failed`: `from` has no pins, a swap names a block it doesn't reference, or a version that isn't published, active or the right kind (see `details.issues`); or `projectId` isn't a project id (a UUID)."),
|
|
1552
1725
|
'404': ErrorResponse('`agent-not-found`: no agent at `from`; or `projectId` names no project of this tenant (`project-not-found`).'),
|
|
1553
1726
|
},
|
|
@@ -1582,7 +1755,7 @@ export const OPERATIONS = [
|
|
|
1582
1755
|
'201': { description: 'Agent published.', schema: ref('PublishAgentResult') },
|
|
1583
1756
|
...CommonMutationErrors,
|
|
1584
1757
|
'400': ErrorResponse("Validation failed (see `details.issues`); or `projectId` isn't a project id (a UUID)."),
|
|
1585
|
-
'409': ErrorResponse("
|
|
1758
|
+
'409': ErrorResponse("`agent-already-registered`: that (id, version) is taken. Or `agent-project-mismatch`: the agent's versions live in another project (an agent belongs to the project its first version was published into and never moves; the message doesn't name the project). Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead."),
|
|
1586
1759
|
'404': ErrorResponse("The body's `projectId` names no project of this tenant (`project-not-found`)."),
|
|
1587
1760
|
},
|
|
1588
1761
|
},
|
|
@@ -1999,7 +2172,7 @@ export const OPERATIONS = [
|
|
|
1999
2172
|
'201': { description: 'Flow published.', schema: ref('PublishFlowResult') },
|
|
2000
2173
|
...CommonMutationErrors,
|
|
2001
2174
|
'400': ErrorResponse("Validation failed (see `details.issues`); or `projectId` isn't a project id (a UUID)."),
|
|
2002
|
-
'409': ErrorResponse("
|
|
2175
|
+
'409': ErrorResponse("`flow-already-registered`: that (id, version) is taken. Or `flow-project-mismatch`: the flow's versions live in another project (a flow belongs to the project its first version was published into and never moves; the message doesn't name the project). Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead."),
|
|
2003
2176
|
'404': ErrorResponse("The body's `projectId` names no project of this tenant (`project-not-found`)."),
|
|
2004
2177
|
},
|
|
2005
2178
|
},
|
|
@@ -2123,7 +2296,7 @@ export const OPERATIONS = [
|
|
|
2123
2296
|
'201': { description: 'Tool registered.', schema: ref('RegisterToolResult') },
|
|
2124
2297
|
...CommonMutationErrors,
|
|
2125
2298
|
'400': ErrorResponse("Validation failed (see `details.issues`); or `projectId` isn't a project id (a UUID)."),
|
|
2126
|
-
'409': ErrorResponse("
|
|
2299
|
+
'409': ErrorResponse("`tool-already-registered`: that (id, version) is taken. Or `tool-project-mismatch`: the tool's versions live in another project (a tool belongs to the project its first version was published into and never moves; the message doesn't name the project). Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead."),
|
|
2127
2300
|
'404': ErrorResponse("The body's `projectId` names no project of this tenant (`project-not-found`)."),
|
|
2128
2301
|
},
|
|
2129
2302
|
},
|
|
@@ -2216,6 +2389,7 @@ export const OPERATIONS = [
|
|
|
2216
2389
|
'400': ErrorResponse("Validation failed (see `details.issues`); or `projectId` isn't a project id (a UUID)."),
|
|
2217
2390
|
'409': ErrorResponse("Guardrail already registered at that id. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead."),
|
|
2218
2391
|
'404': ErrorResponse("The body's `projectId` names no project of this tenant (`project-not-found`)."),
|
|
2392
|
+
'422': ErrorResponse("`guardrail-config-invalid`: the guardrail's `config` breaks the `configSchema` of the pack check it names, which the pack service would refuse on every call. `details.issues` lists each problem, `{ path, message }` with `path` a JSON pointer into the guardrail (`/config/maxChars`); the message names the guardrail, the check and the setting. Checked when the check's deployment carries its schema."),
|
|
2219
2393
|
},
|
|
2220
2394
|
},
|
|
2221
2395
|
{
|
|
@@ -2314,6 +2488,27 @@ export const OPERATIONS = [
|
|
|
2314
2488
|
'404': ErrorResponse('No conversation with that id under this tenant.'),
|
|
2315
2489
|
},
|
|
2316
2490
|
},
|
|
2491
|
+
{
|
|
2492
|
+
method: 'post',
|
|
2493
|
+
honoPath: '/v1/conversations/:conversationId/unregister',
|
|
2494
|
+
openapiPath: '/v1/conversations/{conversationId}/unregister',
|
|
2495
|
+
operationId: 'conversations.unregister',
|
|
2496
|
+
summary: 'Unregister a conversation',
|
|
2497
|
+
description: "A tombstone: from now on no read, list or recall of earlier conversations returns it, and no message can be added. The retention sweep removes it after the tenant's grace.",
|
|
2498
|
+
tags: ['conversations'],
|
|
2499
|
+
security: 'bearer',
|
|
2500
|
+
parameters: [ConversationIdPathParam, IdempotencyKeyParam],
|
|
2501
|
+
responses: {
|
|
2502
|
+
'200': {
|
|
2503
|
+
description: 'The conversation, with `unregisteredAt`.',
|
|
2504
|
+
schema: ref('Conversation'),
|
|
2505
|
+
},
|
|
2506
|
+
...CommonMutationErrors,
|
|
2507
|
+
'400': ErrorResponse('`conversationId` is not a conversation id (a UUID).'),
|
|
2508
|
+
'404': ErrorResponse('No conversation with that id under this tenant, or it is unregistered already.'),
|
|
2509
|
+
'501': ErrorResponse("`conversation-unregister-unsupported`: this runtime can't unregister conversations."),
|
|
2510
|
+
},
|
|
2511
|
+
},
|
|
2317
2512
|
{
|
|
2318
2513
|
method: 'get',
|
|
2319
2514
|
honoPath: '/v1/conversations/:conversationId/messages',
|
|
@@ -2341,7 +2536,7 @@ export const OPERATIONS = [
|
|
|
2341
2536
|
openapiPath: '/v1/memory/facts',
|
|
2342
2537
|
operationId: 'memory.listFacts',
|
|
2343
2538
|
summary: 'List facts',
|
|
2344
|
-
description:
|
|
2539
|
+
description: "Cursor-paginated: the current revision of each fact the caller may see. That is tenant-wide facts, the projects they may read (with those projects' orgs), their own user facts, and every end user's and conversation's facts in the projects they may write; a tenant admin sees every fact. Filters: `?type=` (exact match on `Fact.type`), `?scope=` (URL-encoded JSON partial memory `Scope`), `?scopeKind + ?scopeId + ?inherit` (discriminated `PlatformScope` triplet — threaded into the binding as `platformScope`; both fields coexist), `?asOf=` (memory as it stood then). Sort order is binding-defined.",
|
|
2345
2540
|
tags: ['memory'],
|
|
2346
2541
|
security: 'bearer',
|
|
2347
2542
|
parameters: [
|
|
@@ -2352,11 +2547,12 @@ export const OPERATIONS = [
|
|
|
2352
2547
|
ScopeKindQueryParam,
|
|
2353
2548
|
ScopeIdQueryParam,
|
|
2354
2549
|
InheritQueryParam,
|
|
2550
|
+
FactAsOfQueryParam,
|
|
2355
2551
|
],
|
|
2356
2552
|
responses: {
|
|
2357
2553
|
'200': { description: 'Page of facts.', schema: ref('FactCollectionPage') },
|
|
2358
2554
|
...CommonAuthErrors,
|
|
2359
|
-
'400': ErrorResponse('Malformed query parameter (e.g. `scope` not valid JSON).'),
|
|
2555
|
+
'400': ErrorResponse('Malformed query parameter (e.g. `scope` not valid JSON, `asOf` not a time).'),
|
|
2360
2556
|
},
|
|
2361
2557
|
},
|
|
2362
2558
|
{
|
|
@@ -2365,13 +2561,32 @@ export const OPERATIONS = [
|
|
|
2365
2561
|
openapiPath: '/v1/memory/facts/{factId}',
|
|
2366
2562
|
operationId: 'memory.getFact',
|
|
2367
2563
|
summary: 'Fetch a fact',
|
|
2564
|
+
description: 'Its current revision; `?version=` reads one revision, `?asOf=` the revision current at that time. A fact the caller may not see is not found.',
|
|
2368
2565
|
tags: ['memory'],
|
|
2369
2566
|
security: 'bearer',
|
|
2370
|
-
parameters: [FactIdPathParam],
|
|
2567
|
+
parameters: [FactIdPathParam, FactVersionQueryParam, FactAsOfQueryParam],
|
|
2371
2568
|
responses: {
|
|
2372
2569
|
'200': { description: 'Fact.', schema: ref('Fact') },
|
|
2373
2570
|
...CommonAuthErrors,
|
|
2374
|
-
'
|
|
2571
|
+
'400': ErrorResponse('`version` is not a revision number, or `asOf` not a time.'),
|
|
2572
|
+
'404': ErrorResponse('No fact with that id the caller may see (or no such revision).'),
|
|
2573
|
+
},
|
|
2574
|
+
},
|
|
2575
|
+
{
|
|
2576
|
+
method: 'get',
|
|
2577
|
+
honoPath: '/v1/memory/facts/:factId/revisions',
|
|
2578
|
+
openapiPath: '/v1/memory/facts/{factId}/revisions',
|
|
2579
|
+
operationId: 'memory.listFactRevisions',
|
|
2580
|
+
summary: "List a fact's revisions",
|
|
2581
|
+
description: 'Every revision of the fact, newest first, superseded and deleted ones included: who changed it, when and why (`invalidatedBy`, `invalidatedAt`, `invalidationReason`).',
|
|
2582
|
+
tags: ['memory'],
|
|
2583
|
+
security: 'bearer',
|
|
2584
|
+
parameters: [FactIdPathParam],
|
|
2585
|
+
responses: {
|
|
2586
|
+
'200': { description: 'The revisions.', schema: ref('FactRevisionList') },
|
|
2587
|
+
...CommonAuthErrors,
|
|
2588
|
+
'404': ErrorResponse('No fact with that id the caller may see.'),
|
|
2589
|
+
'501': ErrorResponse("`memory-operation-unsupported`: this runtime's memory doesn't keep fact history."),
|
|
2375
2590
|
},
|
|
2376
2591
|
},
|
|
2377
2592
|
{
|
|
@@ -2380,7 +2595,7 @@ export const OPERATIONS = [
|
|
|
2380
2595
|
openapiPath: '/v1/memory/facts',
|
|
2381
2596
|
operationId: 'memory.writeFact',
|
|
2382
2597
|
summary: 'Write a fact',
|
|
2383
|
-
description:
|
|
2598
|
+
description: "Persists a new fact. `type` selects the retrieval policy (which indexes populate). Semantic-indexed types require an embedding provider bound on the deployment; if unavailable, the route returns `400 bad-input`. The caller needs write where the scope says: `write` on its project (an end user's or a conversation's fact included), `write` on its conversation outside a project, `admin` on its org for an org-wide fact, being that user for a user's fact, and tenant `admin` for a tenant-wide fact. The fact records who wrote it (`attributedTo`).",
|
|
2384
2599
|
tags: ['memory'],
|
|
2385
2600
|
security: 'bearer',
|
|
2386
2601
|
parameters: [IdempotencyKeyParam],
|
|
@@ -2389,6 +2604,8 @@ export const OPERATIONS = [
|
|
|
2389
2604
|
'201': { description: 'Fact written.', schema: ref('Fact') },
|
|
2390
2605
|
...CommonMutationErrors,
|
|
2391
2606
|
'400': ErrorResponse('Malformed body, or the fact type requires semantic indexing and no embedding provider is bound.'),
|
|
2607
|
+
'403': ErrorResponse("`permission-denied`: the caller may not write in the fact's scope."),
|
|
2608
|
+
'409': ErrorResponse("Idempotency-Key was reused with a different body; or an erasure of the fact's person (by scope or subject) or conversation is in progress (`erasure-in-progress`): nothing new is stored for them until it completes."),
|
|
2392
2609
|
},
|
|
2393
2610
|
},
|
|
2394
2611
|
{
|
|
@@ -2396,18 +2613,58 @@ export const OPERATIONS = [
|
|
|
2396
2613
|
honoPath: '/v1/memory/facts/:factId/supersede',
|
|
2397
2614
|
openapiPath: '/v1/memory/facts/{factId}/supersede',
|
|
2398
2615
|
operationId: 'memory.supersedeFact',
|
|
2399
|
-
summary:
|
|
2400
|
-
description: '
|
|
2616
|
+
summary: "Change a fact's content",
|
|
2617
|
+
description: 'Writes the next revision (same fact id, `version` one more) and closes the current one; the old revision stays readable with `?version=`, `?asOf=` and in the history until the retention sweep removes it. `expectVersion` refuses if someone changed it first.',
|
|
2401
2618
|
tags: ['memory'],
|
|
2402
2619
|
security: 'bearer',
|
|
2403
2620
|
parameters: [FactIdPathParam, IdempotencyKeyParam],
|
|
2621
|
+
requestBody: { required: true, schema: ref('SupersedeFactBody') },
|
|
2404
2622
|
responses: {
|
|
2405
|
-
'200': {
|
|
2406
|
-
description: 'Superseded (or already superseded).',
|
|
2407
|
-
schema: ref('SupersedeFactResult'),
|
|
2408
|
-
},
|
|
2623
|
+
'200': { description: 'The new revision.', schema: ref('Fact') },
|
|
2409
2624
|
...CommonMutationErrors,
|
|
2410
|
-
'
|
|
2625
|
+
'403': ErrorResponse("`permission-denied`: the caller may not write in the fact's scope."),
|
|
2626
|
+
'404': ErrorResponse('No fact with that id the caller may see, or it was deleted.'),
|
|
2627
|
+
'409': ErrorResponse('`fact-changed`: the current revision is not `expectVersion` (`details.currentVersion`); `legal-hold`: the fact is under legal hold.'),
|
|
2628
|
+
},
|
|
2629
|
+
},
|
|
2630
|
+
{
|
|
2631
|
+
method: 'delete',
|
|
2632
|
+
honoPath: '/v1/memory/facts/:factId',
|
|
2633
|
+
openapiPath: '/v1/memory/facts/{factId}',
|
|
2634
|
+
operationId: 'memory.deleteFact',
|
|
2635
|
+
summary: 'Delete a fact',
|
|
2636
|
+
description: 'Closes the current revision (`invalidationReason: deleted`): the fact is no longer listed, fetched or retrieved, and its history stays readable until the retention sweep removes it.',
|
|
2637
|
+
tags: ['memory'],
|
|
2638
|
+
security: 'bearer',
|
|
2639
|
+
parameters: [FactIdPathParam, FactExpectVersionQueryParam],
|
|
2640
|
+
responses: {
|
|
2641
|
+
'200': { description: 'The closed revision.', schema: ref('Fact') },
|
|
2642
|
+
...CommonAuthErrors,
|
|
2643
|
+
'400': ErrorResponse('`expectVersion` is not a revision number.'),
|
|
2644
|
+
'403': ErrorResponse("`permission-denied`: the caller may not write in the fact's scope."),
|
|
2645
|
+
'404': ErrorResponse('No fact with that id the caller may see, or it was deleted.'),
|
|
2646
|
+
'409': ErrorResponse('`fact-changed`: the current revision is not `expectVersion`; `legal-hold`: the fact is under legal hold.'),
|
|
2647
|
+
'501': ErrorResponse("`memory-operation-unsupported`: this runtime's memory can't delete facts."),
|
|
2648
|
+
},
|
|
2649
|
+
},
|
|
2650
|
+
{
|
|
2651
|
+
method: 'post',
|
|
2652
|
+
honoPath: '/v1/memory/facts/:factId/verify',
|
|
2653
|
+
openapiPath: '/v1/memory/facts/{factId}/verify',
|
|
2654
|
+
operationId: 'memory.verifyFact',
|
|
2655
|
+
summary: 'Mark a fact verified',
|
|
2656
|
+
description: 'A person who may write in its scope checked it: the next revision has `trust: verified`, `verifiedBy` and `verifiedAt`, and the same content.',
|
|
2657
|
+
tags: ['memory'],
|
|
2658
|
+
security: 'bearer',
|
|
2659
|
+
parameters: [FactIdPathParam, IdempotencyKeyParam],
|
|
2660
|
+
requestBody: { required: false, schema: ref('VerifyFactBody') },
|
|
2661
|
+
responses: {
|
|
2662
|
+
'200': { description: 'The verified revision.', schema: ref('Fact') },
|
|
2663
|
+
...CommonMutationErrors,
|
|
2664
|
+
'403': ErrorResponse("`permission-denied`: the caller may not write in the fact's scope."),
|
|
2665
|
+
'404': ErrorResponse('No fact with that id the caller may see, or it was deleted.'),
|
|
2666
|
+
'409': ErrorResponse('`fact-changed`: the current revision is not `expectVersion`; `legal-hold`: the fact is under legal hold.'),
|
|
2667
|
+
'501': ErrorResponse("`memory-operation-unsupported`: this runtime's memory can't verify facts."),
|
|
2411
2668
|
},
|
|
2412
2669
|
},
|
|
2413
2670
|
{
|
|
@@ -2416,7 +2673,7 @@ export const OPERATIONS = [
|
|
|
2416
2673
|
openapiPath: '/v1/memory/retrieve',
|
|
2417
2674
|
operationId: 'memory.retrieve',
|
|
2418
2675
|
summary: 'Retrieve facts by intent',
|
|
2419
|
-
description: '
|
|
2676
|
+
description: 'Retrieval over the facts the caller may see (as for listing), current revisions only. `mode`: `list` (newest first, no query), `keyword` (full-text), `semantic` (by meaning), or `both` (the two searches fused by rank: reciprocal rank fusion). Searching by meaning needs embeddings on the deployment (`KINDGI_MEMORY_EMBEDDINGS`); without them `semantic` and `both` answer `422 semantic-unavailable`.',
|
|
2420
2677
|
tags: ['memory'],
|
|
2421
2678
|
security: 'bearer',
|
|
2422
2679
|
parameters: [IdempotencyKeyParam],
|
|
@@ -2424,34 +2681,159 @@ export const OPERATIONS = [
|
|
|
2424
2681
|
responses: {
|
|
2425
2682
|
'200': { description: 'Retrieval results.', schema: ref('RetrieveMemoryResult') },
|
|
2426
2683
|
...CommonMutationErrors,
|
|
2427
|
-
'400': ErrorResponse('Malformed intent
|
|
2684
|
+
'400': ErrorResponse('Malformed intent.'),
|
|
2685
|
+
'422': ErrorResponse('`semantic-unavailable`: `semantic` or `both` asked to search by meaning, and the deployment has no embeddings (`KINDGI_MEMORY_EMBEDDINGS`).'),
|
|
2686
|
+
'501': ErrorResponse("`memory-operation-unsupported`: this runtime's memory can't retrieve by intent."),
|
|
2687
|
+
},
|
|
2688
|
+
},
|
|
2689
|
+
// ---------- memory erasures (a person's words) ----------
|
|
2690
|
+
{
|
|
2691
|
+
method: 'post',
|
|
2692
|
+
honoPath: '/v1/memory/erasures',
|
|
2693
|
+
openapiPath: '/v1/memory/erasures',
|
|
2694
|
+
operationId: 'memory.createErasure',
|
|
2695
|
+
summary: "Erase a person's words",
|
|
2696
|
+
description: "Starts erasing, in the background, one fact (`factId`), a person (`subject`: an app's end user `participant`, or an `external` subject facts name) or one conversation (`conversationId`): their facts, conversations (messages, recall rows), the runs that served them (input, output, journal, snapshots) and the free text they left in provenance; facts written from them go to review. Answers `202` with the erasure; follow it with `GET /v1/memory/erasures/{erasureId}`. A completed erasure keeps no identifier, only a keyed hash for a replay after a backup restore; `warnings` says when this deployment can't keep one (`erasure-unmatchable`: no erasure ledger key, `KINDGI_ERASURE_LEDGER_KEY`). Requires `admin` on the tenant.",
|
|
2697
|
+
tags: ['memory'],
|
|
2698
|
+
security: 'bearer',
|
|
2699
|
+
parameters: [IdempotencyKeyParam],
|
|
2700
|
+
requestBody: { required: true, schema: ref('CreateMemoryErasureBody') },
|
|
2701
|
+
responses: {
|
|
2702
|
+
'202': { description: 'Started.', schema: ref('MemoryErasureCreated') },
|
|
2703
|
+
...CommonMutationErrors,
|
|
2704
|
+
'400': ErrorResponse("Not exactly one of `factId`, `subject` or `conversationId`; or a `subject` of kind `user` (erasing a Kindgi user isn't offered)."),
|
|
2705
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
2706
|
+
'409': ErrorResponse('`legal-hold`: a fact it reaches is under legal hold (`details.factIds`); nothing started.'),
|
|
2428
2707
|
},
|
|
2429
2708
|
},
|
|
2430
|
-
|
|
2709
|
+
{
|
|
2710
|
+
method: 'get',
|
|
2711
|
+
honoPath: '/v1/memory/erasures',
|
|
2712
|
+
openapiPath: '/v1/memory/erasures',
|
|
2713
|
+
operationId: 'memory.listErasures',
|
|
2714
|
+
summary: 'List erasures',
|
|
2715
|
+
description: 'Cursor-paginated, newest first: each erasure, how far it got and what it cleared. A completed one shows no selector. Requires `admin` on the tenant.',
|
|
2716
|
+
tags: ['memory'],
|
|
2717
|
+
security: 'bearer',
|
|
2718
|
+
parameters: [LimitQueryParam, CursorQueryParam],
|
|
2719
|
+
responses: {
|
|
2720
|
+
'200': { description: 'Page of erasures.', schema: ref('MemoryErasurePage') },
|
|
2721
|
+
...CommonAuthErrors,
|
|
2722
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
2723
|
+
'400': ErrorResponse('`cursor` is not one this list issued.'),
|
|
2724
|
+
},
|
|
2725
|
+
},
|
|
2726
|
+
{
|
|
2727
|
+
method: 'get',
|
|
2728
|
+
honoPath: '/v1/memory/erasures/export',
|
|
2729
|
+
openapiPath: '/v1/memory/erasures/export',
|
|
2730
|
+
operationId: 'memory.exportErasures',
|
|
2731
|
+
summary: 'Export the erasure ledger',
|
|
2732
|
+
description: "The whole ledger, oldest first, content-free: each erasure's selector kind, the keyed hash of whom it erased, who asked and when. Keep it off-box: restoring a backup rolls the ledger back too, and `POST /v1/memory/erasures/replay` with it runs the erasures again. Requires `admin` on the tenant.",
|
|
2733
|
+
tags: ['memory'],
|
|
2734
|
+
security: 'bearer',
|
|
2735
|
+
responses: {
|
|
2736
|
+
'200': { description: 'The ledger.', schema: ref('MemoryErasureLedger') },
|
|
2737
|
+
...CommonAuthErrors,
|
|
2738
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
2739
|
+
},
|
|
2740
|
+
},
|
|
2741
|
+
{
|
|
2742
|
+
method: 'post',
|
|
2743
|
+
honoPath: '/v1/memory/erasures/replay',
|
|
2744
|
+
openapiPath: '/v1/memory/erasures/replay',
|
|
2745
|
+
operationId: 'memory.replayErasures',
|
|
2746
|
+
summary: 'Replay erasures after a backup restore',
|
|
2747
|
+
description: "Takes the ledger `GET /v1/memory/erasures/export` gave, puts back the rows the restore lost, and finds each erasure's person (or fact, or conversation) again by its keyed hash: those run again (`replayed`); ones nothing in the tenant matches are only restored (`restored`); ones with no keyed hash, or a key this deployment doesn't hold, are `unmatched`. Requires `admin` on the tenant.",
|
|
2748
|
+
tags: ['memory'],
|
|
2749
|
+
security: 'bearer',
|
|
2750
|
+
parameters: [IdempotencyKeyParam],
|
|
2751
|
+
requestBody: { required: true, schema: ref('ReplayMemoryErasuresBody') },
|
|
2752
|
+
responses: {
|
|
2753
|
+
'200': { description: 'What was replayed.', schema: ref('ReplayMemoryErasuresResult') },
|
|
2754
|
+
...CommonMutationErrors,
|
|
2755
|
+
'400': ErrorResponse('Not `{erasures: [...]}` as the export gave them.'),
|
|
2756
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
2757
|
+
},
|
|
2758
|
+
},
|
|
2759
|
+
{
|
|
2760
|
+
method: 'post',
|
|
2761
|
+
honoPath: '/v1/memory/erasures/:erasureId/resume',
|
|
2762
|
+
openapiPath: '/v1/memory/erasures/{erasureId}/resume',
|
|
2763
|
+
operationId: 'memory.resumeErasure',
|
|
2764
|
+
summary: 'Resume an erasure',
|
|
2765
|
+
description: "Tries an unfinished erasure again now. With `force: true`, an erasure `waiting-on-run` (a turn of the person's in a flow that serves other people) stops waiting: the run is cancelled and the erasure goes on; without it, it waits until its deadline (`waitingOn.until`). A finished erasure comes back as it is. Requires `admin` on the tenant.",
|
|
2766
|
+
tags: ['memory'],
|
|
2767
|
+
security: 'bearer',
|
|
2768
|
+
parameters: [ErasureIdPathParam, IdempotencyKeyParam],
|
|
2769
|
+
requestBody: { required: false, schema: ref('ResumeMemoryErasureBody') },
|
|
2770
|
+
responses: {
|
|
2771
|
+
'200': { description: 'The erasure.', schema: ref('MemoryErasure') },
|
|
2772
|
+
...CommonMutationErrors,
|
|
2773
|
+
'400': ErrorResponse('The body is `{force?: boolean}`.'),
|
|
2774
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
2775
|
+
'404': ErrorResponse('No such erasure in this tenant.'),
|
|
2776
|
+
},
|
|
2777
|
+
},
|
|
2778
|
+
{
|
|
2779
|
+
method: 'get',
|
|
2780
|
+
honoPath: '/v1/memory/erasures/:erasureId',
|
|
2781
|
+
openapiPath: '/v1/memory/erasures/{erasureId}',
|
|
2782
|
+
operationId: 'memory.getErasure',
|
|
2783
|
+
summary: 'Get an erasure',
|
|
2784
|
+
description: 'One erasure: its status (`pending`, `running`, `completed`, `failed`), phase, what each store cleared (`counts`), and `lastError` (a code, or `not-yet:<reason>` while it waits for a run to finish). Requires `admin` on the tenant.',
|
|
2785
|
+
tags: ['memory'],
|
|
2786
|
+
security: 'bearer',
|
|
2787
|
+
parameters: [ErasureIdPathParam],
|
|
2788
|
+
responses: {
|
|
2789
|
+
'200': { description: 'The erasure.', schema: ref('MemoryErasure') },
|
|
2790
|
+
...CommonAuthErrors,
|
|
2791
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
2792
|
+
'404': ErrorResponse('No such erasure in this tenant.'),
|
|
2793
|
+
},
|
|
2794
|
+
},
|
|
2795
|
+
// ---------- improvement proposals ----------
|
|
2431
2796
|
{
|
|
2432
2797
|
method: 'get',
|
|
2433
2798
|
honoPath: '/v1/proposals',
|
|
2434
2799
|
openapiPath: '/v1/proposals',
|
|
2435
2800
|
operationId: 'proposals.list',
|
|
2436
|
-
summary: 'List
|
|
2437
|
-
description: '
|
|
2801
|
+
summary: 'List improvement proposals',
|
|
2802
|
+
description: 'Newest first, cursor-paginated, only the proposals of agents the caller can read. Filters: `?agentId=`, `?tier=`, `?status=` (statuses are derived, so a page filtered by status can hold fewer rows than `limit`), and the live scope a proposal is for (`scopeKind`, `scopeId`, `segment`, exactly as the promotions history takes it).',
|
|
2438
2803
|
tags: ['proposals'],
|
|
2439
2804
|
security: 'bearer',
|
|
2440
2805
|
parameters: [
|
|
2441
|
-
SupervisorIdHeaderParam,
|
|
2442
2806
|
LimitQueryParam,
|
|
2443
2807
|
CursorQueryParam,
|
|
2444
2808
|
ProposalStatusQueryParam,
|
|
2445
2809
|
AgentIdQueryParam,
|
|
2446
2810
|
ProposalTierQueryParam,
|
|
2447
|
-
|
|
2811
|
+
PromotionScopeKindQueryParam,
|
|
2448
2812
|
ScopeIdQueryParam,
|
|
2449
|
-
|
|
2813
|
+
SegmentQueryParam,
|
|
2450
2814
|
],
|
|
2451
2815
|
responses: {
|
|
2452
2816
|
'200': { description: 'Page of proposals.', schema: ref('FixProposalCollectionPage') },
|
|
2453
2817
|
...CommonAuthErrors,
|
|
2454
|
-
'400': ErrorResponse('
|
|
2818
|
+
'400': ErrorResponse('A malformed query parameter.'),
|
|
2819
|
+
},
|
|
2820
|
+
},
|
|
2821
|
+
{
|
|
2822
|
+
method: 'post',
|
|
2823
|
+
honoPath: '/v1/proposals/improve',
|
|
2824
|
+
openapiPath: '/v1/proposals/improve',
|
|
2825
|
+
operationId: 'proposals.improve',
|
|
2826
|
+
summary: 'Start an improvement pass',
|
|
2827
|
+
description: "The runtime looks for better values for the version's tunable settings (keys its settings blocks' schemas mark `x-kindgi-tunable`) on the test set, within the budget, and writes its best candidate as an improvement proposal, which waits for a reviewer when requested. It answers at once with the pass, `running`. Checked first: the version is active and pins a settings block with tunable keys (`400 validation-failed`), the agent registry takes writes (`409 registry-read-only`), and the agent has a live version for the whole tenant (`409 proposal-needs-pin`). Needs `publish` on the agent. Without improvement passes in this runtime, `501 improve-unsupported`.",
|
|
2828
|
+
tags: ['proposals'],
|
|
2829
|
+
security: 'bearer',
|
|
2830
|
+
parameters: [IdempotencyKeyParam],
|
|
2831
|
+
requestBody: { required: true, schema: ref('ImproveBody') },
|
|
2832
|
+
responses: {
|
|
2833
|
+
'202': { description: 'The pass, running.', schema: ref('ImprovementPass') },
|
|
2834
|
+
...CommonMutationErrors,
|
|
2835
|
+
'404': ErrorResponse('`fromVersion` (or the version serving the scope) is not an active version.'),
|
|
2836
|
+
'501': ErrorResponse('`improve-unsupported`: this runtime runs no improvement passes.'),
|
|
2455
2837
|
},
|
|
2456
2838
|
},
|
|
2457
2839
|
{
|
|
@@ -2459,122 +2841,162 @@ export const OPERATIONS = [
|
|
|
2459
2841
|
honoPath: '/v1/proposals/:proposalId',
|
|
2460
2842
|
openapiPath: '/v1/proposals/{proposalId}',
|
|
2461
2843
|
operationId: 'proposals.get',
|
|
2462
|
-
summary: 'Fetch
|
|
2844
|
+
summary: 'Fetch an improvement proposal',
|
|
2845
|
+
description: 'Needs `read` on its agent.',
|
|
2463
2846
|
tags: ['proposals'],
|
|
2464
2847
|
security: 'bearer',
|
|
2465
|
-
parameters: [
|
|
2848
|
+
parameters: [ProposalIdPathParam],
|
|
2466
2849
|
responses: {
|
|
2467
|
-
'200': { description: '
|
|
2850
|
+
'200': { description: 'The proposal.', schema: ref('FixProposal') },
|
|
2468
2851
|
...CommonAuthErrors,
|
|
2469
|
-
'
|
|
2470
|
-
'404': ErrorResponse('No proposal visible under this supervisor with that id.'),
|
|
2852
|
+
'404': ErrorResponse('No such proposal (or none the caller can read).'),
|
|
2471
2853
|
},
|
|
2472
2854
|
},
|
|
2473
2855
|
{
|
|
2474
2856
|
method: 'post',
|
|
2475
2857
|
honoPath: '/v1/proposals',
|
|
2476
2858
|
openapiPath: '/v1/proposals',
|
|
2477
|
-
operationId: 'proposals.
|
|
2478
|
-
summary: '
|
|
2479
|
-
description: '
|
|
2859
|
+
operationId: 'proposals.create',
|
|
2860
|
+
summary: 'Propose new content for a data block',
|
|
2861
|
+
description: 'A hand-written proposal: new settings values or a new prompt template for a block `fromVersion` pins, for a live scope. Checked as publishing that block version would be (its schema carries over), and refused when it equals the pinned content. The same change from the same version for the same scope is one proposal: answered `200` with `X-Proposal-Deduped: true`. Needs `publish` on the agent.',
|
|
2480
2862
|
tags: ['proposals'],
|
|
2481
2863
|
security: 'bearer',
|
|
2482
|
-
parameters: [
|
|
2483
|
-
requestBody: { required: true, schema: ref('
|
|
2864
|
+
parameters: [IdempotencyKeyParam],
|
|
2865
|
+
requestBody: { required: true, schema: ref('CreateProposalBody') },
|
|
2484
2866
|
responses: {
|
|
2485
|
-
'201': { description: '
|
|
2867
|
+
'201': { description: 'The proposal, a `draft`.', schema: ref('FixProposal') },
|
|
2868
|
+
'200': { description: 'The same proposal, made before.', schema: ref('FixProposal') },
|
|
2486
2869
|
...CommonMutationErrors,
|
|
2870
|
+
'404': ErrorResponse("`fromVersion` isn't an active version of the agent (`agent-version-not-found`)."),
|
|
2487
2871
|
},
|
|
2488
2872
|
},
|
|
2489
2873
|
{
|
|
2490
2874
|
method: 'post',
|
|
2491
|
-
honoPath: '/v1/proposals/:proposalId/
|
|
2492
|
-
openapiPath: '/v1/proposals/{proposalId}/
|
|
2493
|
-
operationId: 'proposals.
|
|
2494
|
-
summary: '
|
|
2495
|
-
description:
|
|
2875
|
+
honoPath: '/v1/proposals/:proposalId/evaluate',
|
|
2876
|
+
openapiPath: '/v1/proposals/{proposalId}/evaluate',
|
|
2877
|
+
operationId: 'proposals.evaluate',
|
|
2878
|
+
summary: 'Compare a proposal on a test set',
|
|
2879
|
+
description: "The first evaluation publishes the block version and derives the agent version (`derivedFrom.proposalId`); they serve no scope until a promotion makes them live. Then a comparison eval run replays that version on the test set, against the recorded outputs (`baseline: 'recorded'`). Needs `publish` on the agent, and a live version of it for the whole tenant: an agent with none serves its latest version wherever nothing is pinned, so a new version would go live there at once (`409 proposal-needs-pin`). Allowed from `draft`, `evaluated`, `not-better`, `evaluation-failed`, `refused`, `superseded` and `expired`.",
|
|
2496
2880
|
tags: ['proposals'],
|
|
2497
2881
|
security: 'bearer',
|
|
2498
|
-
parameters: [
|
|
2499
|
-
requestBody: { required: true, schema: ref('
|
|
2882
|
+
parameters: [ProposalIdPathParam, IdempotencyKeyParam],
|
|
2883
|
+
requestBody: { required: true, schema: ref('EvaluateProposalBody') },
|
|
2500
2884
|
responses: {
|
|
2501
|
-
'
|
|
2885
|
+
'202': { description: 'The proposal, `evaluating`.', schema: ref('FixProposal') },
|
|
2502
2886
|
...CommonMutationErrors,
|
|
2503
|
-
'404': ErrorResponse('No proposal
|
|
2504
|
-
'
|
|
2887
|
+
'404': ErrorResponse('No such proposal, or no such test set.'),
|
|
2888
|
+
'409': ErrorResponse("`proposal-needs-pin`: the agent has no live version for the whole tenant. `proposal-invalid-state-transition`: the proposal's status doesn't allow it. `registry-read-only`: the agent registry takes no writes (under `kindgi dev`)."),
|
|
2505
2889
|
},
|
|
2506
2890
|
},
|
|
2507
2891
|
{
|
|
2508
2892
|
method: 'post',
|
|
2509
|
-
honoPath: '/v1/proposals/:proposalId/
|
|
2510
|
-
openapiPath: '/v1/proposals/{proposalId}/
|
|
2511
|
-
operationId: 'proposals.
|
|
2512
|
-
summary:
|
|
2513
|
-
description:
|
|
2893
|
+
honoPath: '/v1/proposals/:proposalId/request',
|
|
2894
|
+
openapiPath: '/v1/proposals/{proposalId}/request',
|
|
2895
|
+
operationId: 'proposals.request',
|
|
2896
|
+
summary: "Request a proposal's promotion for its scope",
|
|
2897
|
+
description: "A promotion of the candidate for the proposal's scope, with its evaluation's comparison, through the scope's gate: as `POST /v1/agents/{agentId}/promotions` answers. Needs `promote` on the agent. Allowed from `evaluated`, `not-better` (the gate decides), `refused`, `superseded` and `expired`.",
|
|
2514
2898
|
tags: ['proposals'],
|
|
2515
2899
|
security: 'bearer',
|
|
2516
|
-
parameters: [
|
|
2517
|
-
requestBody: { required: false, schema: ref('
|
|
2900
|
+
parameters: [ProposalIdPathParam, IdempotencyKeyParam],
|
|
2901
|
+
requestBody: { required: false, schema: ref('ProposalReasonBody') },
|
|
2518
2902
|
responses: {
|
|
2519
|
-
'
|
|
2520
|
-
|
|
2521
|
-
|
|
2903
|
+
'201': { description: 'Promoted: the proposal, `promoted`.', schema: ref('FixProposal') },
|
|
2904
|
+
'202': {
|
|
2905
|
+
description: 'The gate passed and an approval is open: the proposal, `in-review`.',
|
|
2906
|
+
schema: ref('FixProposal'),
|
|
2522
2907
|
},
|
|
2523
2908
|
...CommonMutationErrors,
|
|
2524
|
-
'404': ErrorResponse('No proposal
|
|
2525
|
-
'
|
|
2909
|
+
'404': ErrorResponse('No such proposal.'),
|
|
2910
|
+
'409': ErrorResponse("The proposal's status doesn't allow it."),
|
|
2911
|
+
'422': ErrorResponse('`gate-failed`: the gate refused it (the error carries the checks and `proposalId`).'),
|
|
2526
2912
|
},
|
|
2527
2913
|
},
|
|
2528
2914
|
{
|
|
2529
2915
|
method: 'post',
|
|
2530
|
-
honoPath: '/v1/proposals/:proposalId/
|
|
2531
|
-
openapiPath: '/v1/proposals/{proposalId}/
|
|
2532
|
-
operationId: 'proposals.
|
|
2533
|
-
summary: '
|
|
2534
|
-
description:
|
|
2916
|
+
honoPath: '/v1/proposals/:proposalId/rollback',
|
|
2917
|
+
openapiPath: '/v1/proposals/{proposalId}/rollback',
|
|
2918
|
+
operationId: 'proposals.rollback',
|
|
2919
|
+
summary: 'Roll back a promoted proposal',
|
|
2920
|
+
description: "The scope goes back to the version its own pin held before the proposal's promotion (or, with none, falls back to the scope above). Only while the proposal's version still serves the scope. Needs `promote` on the agent.",
|
|
2535
2921
|
tags: ['proposals'],
|
|
2536
2922
|
security: 'bearer',
|
|
2537
|
-
parameters: [
|
|
2538
|
-
requestBody: { required: false, schema: ref('
|
|
2923
|
+
parameters: [ProposalIdPathParam, IdempotencyKeyParam],
|
|
2924
|
+
requestBody: { required: false, schema: ref('ProposalReasonBody') },
|
|
2539
2925
|
responses: {
|
|
2540
|
-
'200': { description: '
|
|
2926
|
+
'200': { description: 'The proposal, `rolled-back`.', schema: ref('FixProposal') },
|
|
2541
2927
|
...CommonMutationErrors,
|
|
2542
|
-
'404': ErrorResponse('No proposal
|
|
2543
|
-
'
|
|
2928
|
+
'404': ErrorResponse('No such proposal.'),
|
|
2929
|
+
'409': ErrorResponse("It isn't promoted, or its version doesn't serve the scope anymore."),
|
|
2544
2930
|
},
|
|
2545
2931
|
},
|
|
2546
2932
|
{
|
|
2547
2933
|
method: 'post',
|
|
2548
|
-
honoPath: '/v1/proposals/:proposalId/
|
|
2549
|
-
openapiPath: '/v1/proposals/{proposalId}/
|
|
2550
|
-
operationId: 'proposals.
|
|
2551
|
-
summary: '
|
|
2552
|
-
description: '
|
|
2934
|
+
honoPath: '/v1/proposals/:proposalId/withdraw',
|
|
2935
|
+
openapiPath: '/v1/proposals/{proposalId}/withdraw',
|
|
2936
|
+
operationId: 'proposals.withdraw',
|
|
2937
|
+
summary: 'Withdraw a proposal',
|
|
2938
|
+
description: "Closes it. Not while it's in review (decide its approval instead), nor once promoted, rejected or rolled back. Needs `publish` on the agent.",
|
|
2553
2939
|
tags: ['proposals'],
|
|
2554
2940
|
security: 'bearer',
|
|
2555
|
-
parameters: [
|
|
2556
|
-
requestBody: { required: true, schema: ref('
|
|
2941
|
+
parameters: [ProposalIdPathParam, IdempotencyKeyParam],
|
|
2942
|
+
requestBody: { required: true, schema: ref('WithdrawProposalBody') },
|
|
2557
2943
|
responses: {
|
|
2558
|
-
'200': { description: '
|
|
2944
|
+
'200': { description: 'The proposal, `withdrawn`.', schema: ref('FixProposal') },
|
|
2559
2945
|
...CommonMutationErrors,
|
|
2560
|
-
'404': ErrorResponse('No proposal
|
|
2946
|
+
'404': ErrorResponse('No such proposal.'),
|
|
2947
|
+
'409': ErrorResponse("The proposal's status doesn't allow it."),
|
|
2948
|
+
},
|
|
2949
|
+
},
|
|
2950
|
+
// ---------- improvement passes ----------
|
|
2951
|
+
{
|
|
2952
|
+
method: 'get',
|
|
2953
|
+
honoPath: '/v1/improvement-passes',
|
|
2954
|
+
openapiPath: '/v1/improvement-passes',
|
|
2955
|
+
operationId: 'improvementPasses.list',
|
|
2956
|
+
summary: 'List improvement passes',
|
|
2957
|
+
description: 'Newest first, only the passes of agents the caller can read. `?agentId=` narrows them.',
|
|
2958
|
+
tags: ['proposals'],
|
|
2959
|
+
security: 'bearer',
|
|
2960
|
+
parameters: [LimitQueryParam, CursorQueryParam, AgentIdQueryParam],
|
|
2961
|
+
responses: {
|
|
2962
|
+
'200': { description: 'Page of passes.', schema: ref('ImprovementPassCollectionPage') },
|
|
2963
|
+
...CommonAuthErrors,
|
|
2964
|
+
'501': ErrorResponse('`improve-unsupported`: this runtime runs no improvement passes.'),
|
|
2965
|
+
},
|
|
2966
|
+
},
|
|
2967
|
+
{
|
|
2968
|
+
method: 'get',
|
|
2969
|
+
honoPath: '/v1/improvement-passes/:passId',
|
|
2970
|
+
openapiPath: '/v1/improvement-passes/{passId}',
|
|
2971
|
+
operationId: 'improvementPasses.get',
|
|
2972
|
+
summary: 'Fetch an improvement pass',
|
|
2973
|
+
description: 'Its status, the candidates it compared and what they cost, and once it ends, what it found. Needs `read` on its agent.',
|
|
2974
|
+
tags: ['proposals'],
|
|
2975
|
+
security: 'bearer',
|
|
2976
|
+
parameters: [ImprovementPassIdPathParam],
|
|
2977
|
+
responses: {
|
|
2978
|
+
'200': { description: 'The pass.', schema: ref('ImprovementPass') },
|
|
2979
|
+
...CommonAuthErrors,
|
|
2980
|
+
'404': ErrorResponse('No such pass (or none the caller can read).'),
|
|
2981
|
+
'501': ErrorResponse('`improve-unsupported`: this runtime runs no improvement passes.'),
|
|
2561
2982
|
},
|
|
2562
2983
|
},
|
|
2563
2984
|
{
|
|
2564
2985
|
method: 'post',
|
|
2565
|
-
honoPath: '/v1/
|
|
2566
|
-
openapiPath: '/v1/
|
|
2567
|
-
operationId: '
|
|
2568
|
-
summary: '
|
|
2569
|
-
description: '
|
|
2986
|
+
honoPath: '/v1/improvement-passes/:passId/cancel',
|
|
2987
|
+
openapiPath: '/v1/improvement-passes/{passId}/cancel',
|
|
2988
|
+
operationId: 'improvementPasses.cancel',
|
|
2989
|
+
summary: 'Cancel an improvement pass',
|
|
2990
|
+
description: 'A running pass stops and ends `cancelled`, writing no proposal. Needs `publish` on its agent.',
|
|
2570
2991
|
tags: ['proposals'],
|
|
2571
2992
|
security: 'bearer',
|
|
2572
|
-
parameters: [
|
|
2573
|
-
requestBody: { required: true, schema: ref('WithdrawProposalBody') },
|
|
2993
|
+
parameters: [ImprovementPassIdPathParam, IdempotencyKeyParam],
|
|
2574
2994
|
responses: {
|
|
2575
|
-
'200': { description: '
|
|
2995
|
+
'200': { description: 'The pass, cancelled.', schema: ref('ImprovementPass') },
|
|
2576
2996
|
...CommonMutationErrors,
|
|
2577
|
-
'404': ErrorResponse('No
|
|
2997
|
+
'404': ErrorResponse('No such pass.'),
|
|
2998
|
+
'409': ErrorResponse('`improvement-pass-finished`: it has ended already.'),
|
|
2999
|
+
'501': ErrorResponse('`improve-unsupported`: this runtime runs no improvement passes.'),
|
|
2578
3000
|
},
|
|
2579
3001
|
},
|
|
2580
3002
|
// ---------- provenance ----------
|
|
@@ -2618,17 +3040,31 @@ export const OPERATIONS = [
|
|
|
2618
3040
|
'404': ErrorResponse('No provenance record for that run under this tenant.'),
|
|
2619
3041
|
},
|
|
2620
3042
|
},
|
|
3043
|
+
{
|
|
3044
|
+
method: 'get',
|
|
3045
|
+
honoPath: '/v1/export-signing-keys',
|
|
3046
|
+
openapiPath: '/v1/export-signing-keys',
|
|
3047
|
+
operationId: 'exportSigningKeys.list',
|
|
3048
|
+
summary: 'List the keys this deployment signs exports with',
|
|
3049
|
+
description: "The public keys of the deployment's export signing key, active first: what a verifier pins. An export's embedded `publicKey` only proves its bytes weren't changed; this list says who signed them. Empty when the deployment doesn't sign exports. Any authenticated caller may read it.",
|
|
3050
|
+
tags: ['export-signing-keys'],
|
|
3051
|
+
security: 'bearer',
|
|
3052
|
+
responses: {
|
|
3053
|
+
'200': { description: 'The keys.', schema: ref('ExportSigningKeyList') },
|
|
3054
|
+
...CommonAuthErrors,
|
|
3055
|
+
},
|
|
3056
|
+
},
|
|
2621
3057
|
{
|
|
2622
3058
|
method: 'post',
|
|
2623
3059
|
honoPath: '/v1/provenance/:runId/export',
|
|
2624
3060
|
openapiPath: '/v1/provenance/{runId}/export',
|
|
2625
3061
|
operationId: 'provenance.export',
|
|
2626
3062
|
summary: 'Export a signed provenance bundle for a run',
|
|
2627
|
-
description: "
|
|
3063
|
+
description: "Signs the run's provenance (and, when asked, its messages) with the deployment's export key, and records the export (an `export-signed` audit event). The same envelope as the other signed exports; check `publicKey` against `GET /v1/export-signing-keys`. A deployment with no export key answers `404 signing-not-configured`.",
|
|
2628
3064
|
tags: ['provenance'],
|
|
2629
3065
|
security: 'bearer',
|
|
2630
3066
|
parameters: [RunIdPathParam, IdempotencyKeyParam],
|
|
2631
|
-
requestBody: { required:
|
|
3067
|
+
requestBody: { required: false, schema: ref('ExportProvenanceBody') },
|
|
2632
3068
|
responses: {
|
|
2633
3069
|
'200': { description: 'Signed bundle.', schema: ref('ExportProvenanceResult') },
|
|
2634
3070
|
...CommonMutationErrors,
|
|
@@ -2642,7 +3078,7 @@ export const OPERATIONS = [
|
|
|
2642
3078
|
openapiPath: '/v1/artifacts',
|
|
2643
3079
|
operationId: 'artifacts.list',
|
|
2644
3080
|
summary: 'List artifact metadata',
|
|
2645
|
-
description: 'Cursor-paginated. Metadata rows only (no bytes). Filters: `?ownerRunId=`, `?contentType=`, `?tag.<key>=<value>` (repeatable — every provided tag must match as AND). Sort order is binding-defined (typically `createdAt desc, blobId desc`).',
|
|
3081
|
+
description: 'Cursor-paginated. Metadata rows only (no bytes). Filters: `?ownerRunId=`, `?projectId=`, `?contentType=`, `?tag.<key>=<value>` (repeatable — every provided tag must match as AND). Sort order is binding-defined (typically `createdAt desc, blobId desc`). With authorization on, only artifacts in projects the caller can read are listed.',
|
|
2646
3082
|
tags: ['artifacts'],
|
|
2647
3083
|
security: 'bearer',
|
|
2648
3084
|
parameters: [
|
|
@@ -2662,6 +3098,13 @@ export const OPERATIONS = [
|
|
|
2662
3098
|
description: 'Filter by exact content-type match.',
|
|
2663
3099
|
schema: { type: 'string' },
|
|
2664
3100
|
},
|
|
3101
|
+
{
|
|
3102
|
+
name: 'projectId',
|
|
3103
|
+
in: 'query',
|
|
3104
|
+
required: false,
|
|
3105
|
+
description: 'Filter to the artifacts of one project.',
|
|
3106
|
+
schema: { type: 'string' },
|
|
3107
|
+
},
|
|
2665
3108
|
],
|
|
2666
3109
|
responses: {
|
|
2667
3110
|
'200': { description: 'Page of blob metadata.', schema: ref('ArtifactCollectionPage') },
|
|
@@ -2675,7 +3118,7 @@ export const OPERATIONS = [
|
|
|
2675
3118
|
openapiPath: '/v1/artifacts',
|
|
2676
3119
|
operationId: 'artifacts.upload',
|
|
2677
3120
|
summary: 'Upload an artifact',
|
|
2678
|
-
description:
|
|
3121
|
+
description: "Multipart upload. `file` part carries the bytes; other form fields carry metadata (`name`, `contentType`, `tags` (JSON), `ownerRunId`, `projectId`, `expectedHash`). Framework computes sha256 and returns it in `BlobMeta.hash`. If `expectedHash` was supplied and diverges, response is `400 blob-hash-mismatch`. Content-type sniffing is NOT performed server-side — the framework trusts the caller. The artifact belongs to its owner run's project, else `projectId`, else the tenant's default project; uploading needs `write` there. An upload over the runtime's cap (default 100 MB) is `413 artifact-too-large`.",
|
|
2679
3122
|
tags: ['artifacts'],
|
|
2680
3123
|
security: 'bearer',
|
|
2681
3124
|
parameters: [IdempotencyKeyParam],
|
|
@@ -2691,7 +3134,10 @@ export const OPERATIONS = [
|
|
|
2691
3134
|
responses: {
|
|
2692
3135
|
'201': { description: 'Upload accepted; metadata returned.', schema: ref('BlobMeta') },
|
|
2693
3136
|
...CommonMutationErrors,
|
|
2694
|
-
'400': ErrorResponse(
|
|
3137
|
+
'400': ErrorResponse("Malformed multipart body, bad tag JSON, hash mismatch, declared size mismatch, or a `projectId` that isn't the owner run's."),
|
|
3138
|
+
'403': ErrorResponse('No `write` on the project (`permission-denied`).'),
|
|
3139
|
+
'404': ErrorResponse('No such owner run (`run-not-found`).'),
|
|
3140
|
+
'413': ErrorResponse('Over the upload cap (`artifact-too-large`; `details.maxBytes` says how much).'),
|
|
2695
3141
|
},
|
|
2696
3142
|
},
|
|
2697
3143
|
{
|
|
@@ -2719,7 +3165,7 @@ export const OPERATIONS = [
|
|
|
2719
3165
|
schema: { type: 'string', format: 'binary' },
|
|
2720
3166
|
},
|
|
2721
3167
|
...CommonAuthErrors,
|
|
2722
|
-
'404': ErrorResponse(
|
|
3168
|
+
'404': ErrorResponse("No blob with that id under this tenant, or one in a project the caller can't read."),
|
|
2723
3169
|
},
|
|
2724
3170
|
},
|
|
2725
3171
|
{
|
|
@@ -2770,6 +3216,8 @@ export const OPERATIONS = [
|
|
|
2770
3216
|
responses: {
|
|
2771
3217
|
'200': { description: 'Delete acknowledged.', schema: ref('DeleteArtifactResult') },
|
|
2772
3218
|
...CommonMutationErrors,
|
|
3219
|
+
'403': ErrorResponse('No `write` on its project (`permission-denied`).'),
|
|
3220
|
+
'404': ErrorResponse("An artifact in a project the caller can't read (`blob-not-found`)."),
|
|
2773
3221
|
},
|
|
2774
3222
|
},
|
|
2775
3223
|
// ---------- observations (supervisor) ----------
|
|
@@ -2889,13 +3337,29 @@ export const OPERATIONS = [
|
|
|
2889
3337
|
'404': ErrorResponse('No provider with that id under this tenant.'),
|
|
2890
3338
|
},
|
|
2891
3339
|
},
|
|
3340
|
+
{
|
|
3341
|
+
method: 'get',
|
|
3342
|
+
honoPath: '/v1/providers/:providerId/check',
|
|
3343
|
+
openapiPath: '/v1/providers/{providerId}/check',
|
|
3344
|
+
operationId: 'providers.check',
|
|
3345
|
+
summary: "Check a provider's registration",
|
|
3346
|
+
description: "Runs the provider's adapter check over its stored registration (its `adapter_config`, its metadata, whether it names a `secret_ref`): the check `POST /v1/providers` runs before it stores one. Static: no network call, no secret read. `issues` lists what would keep the runtime from building the provider, each with a JSON-pointer `path`; an adapter this runtime doesn't have is one (`/adapter_id`). `checked` is false when this runtime has no check for the provider's adapter.",
|
|
3347
|
+
tags: ['providers'],
|
|
3348
|
+
security: 'bearer',
|
|
3349
|
+
parameters: [ProviderIdPathParam],
|
|
3350
|
+
responses: {
|
|
3351
|
+
'200': { description: 'The check.', schema: ref('ProviderCheckResult') },
|
|
3352
|
+
...CommonAuthErrors,
|
|
3353
|
+
'404': ErrorResponse('No provider with that id under this tenant.'),
|
|
3354
|
+
},
|
|
3355
|
+
},
|
|
2892
3356
|
{
|
|
2893
3357
|
method: 'post',
|
|
2894
3358
|
honoPath: '/v1/providers',
|
|
2895
3359
|
openapiPath: '/v1/providers',
|
|
2896
3360
|
operationId: 'providers.register',
|
|
2897
3361
|
summary: 'Register a model provider',
|
|
2898
|
-
description: 'Body is a full `ProviderMetadata`. Server validates shape: provider-level `id` + `region` non-empty; `models[]` non-empty with unique `name` per entry; per-model `contextWindow` positive integer; per-model `features` against the closed enum; per-model `cost` non-negative; optional per-model `p95LatencyMs` / `maxOutputTokens` well-shaped; optional `labels` within their limits — same rules as `@kindgi/capabilities.createProviderRegistry`. Secrets (API keys, endpoints) are NOT part of the wire shape; deployments store them inside the binding.',
|
|
3362
|
+
description: 'Body is a full `ProviderMetadata`. Server validates shape: provider-level `id` + `region` non-empty; `models[]` non-empty with unique `name` per entry; per-model `contextWindow` positive integer; per-model `features` against the closed enum; per-model `cost` non-negative; optional per-model `p95LatencyMs` / `maxOutputTokens` well-shaped; optional `labels` within their limits — same rules as `@kindgi/capabilities.createProviderRegistry`. Secrets (API keys, endpoints) are NOT part of the wire shape; deployments store them inside the binding. When the runtime has the adapter the body names, that adapter checks the registration first (its `adapter_config`, the metadata and the presence of `secret_ref`; static: no network, no secret read): a problem refuses it with `422 provider-config-invalid`.',
|
|
2899
3363
|
tags: ['providers'],
|
|
2900
3364
|
security: 'bearer',
|
|
2901
3365
|
parameters: [IdempotencyKeyParam],
|
|
@@ -2905,6 +3369,7 @@ export const OPERATIONS = [
|
|
|
2905
3369
|
...CommonMutationErrors,
|
|
2906
3370
|
'400': ErrorResponse('Validation failed (see `details.reason`).'),
|
|
2907
3371
|
'409': ErrorResponse('Provider already registered at that id.'),
|
|
3372
|
+
'422': ErrorResponse("`provider-config-invalid`: a `send_traceparent` that isn't a boolean, or the provider's adapter refuses the registration (its `adapter_config`, its metadata, or a missing `secret_ref`); `details.issues` lists each (`path`, a JSON pointer, and `message`), the registration's own fields first, as other validation errors do. Nothing is stored."),
|
|
2908
3373
|
},
|
|
2909
3374
|
},
|
|
2910
3375
|
{
|
|
@@ -2942,6 +3407,7 @@ export const OPERATIONS = [
|
|
|
2942
3407
|
'403': ErrorResponse('`permission-denied`: not allowed to judge this run. `judge-class-not-allowed`: the judge class is restricted (`assertableBy`) and the caller may not assert it.'),
|
|
2943
3408
|
'404': ErrorResponse('`run-not-found`.'),
|
|
2944
3409
|
'409': ErrorResponse('`run-not-finished`: the run has no output to judge yet.'),
|
|
3410
|
+
'410': ErrorResponse("`run-erased`: an erasure cleared the run's content (a person's words were removed); there's nothing to judge."),
|
|
2945
3411
|
},
|
|
2946
3412
|
},
|
|
2947
3413
|
{
|
|
@@ -3665,7 +4131,7 @@ export const OPERATIONS = [
|
|
|
3665
4131
|
'201': { description: 'Eval suite published.', schema: ref('PublishEvalSuiteResult') },
|
|
3666
4132
|
...CommonMutationErrors,
|
|
3667
4133
|
'400': ErrorResponse("Validation failed (see `details.issues`); or `projectId` isn't a project id (a UUID)."),
|
|
3668
|
-
'409': ErrorResponse(
|
|
4134
|
+
'409': ErrorResponse("`eval-suite-already-registered`: that (id, version) is taken. Or `eval-suite-project-mismatch`: the suite's versions live in another project (a suite belongs to the project its first version was published into and never moves; the message doesn't name the project)."),
|
|
3669
4135
|
'404': ErrorResponse("The body's `projectId` names no project of this tenant (`project-not-found`)."),
|
|
3670
4136
|
},
|
|
3671
4137
|
},
|
|
@@ -3675,7 +4141,7 @@ export const OPERATIONS = [
|
|
|
3675
4141
|
openapiPath: '/v1/eval-suites/{suiteId}/versions/from-judgments',
|
|
3676
4142
|
operationId: 'evalSuites.buildFromJudgments',
|
|
3677
4143
|
summary: 'Build a test set from judgments',
|
|
3678
|
-
description: "Publishes a `judged` eval suite version whose cases are copies of judged runs of one agent (optionally one version) or flow, newest first, at most 1000. Each case holds the run's input, what the turn read (`context`), the judged output, and each item's judgments summed up: yes and no counts, the weight behind yes and behind all judgments (an unclassified judgment counts 1), and the reasons. `judgeClassIds` counts only judgments of those classes; `minJudgments` leaves out runs with fewer. Needs `admin` on the project.",
|
|
4144
|
+
description: "Publishes a `judged` eval suite version whose cases are copies of judged runs of one agent (optionally one version) or flow, newest first, at most 1000. Each case holds the run's input, what the turn read (`context`), the judged output, and each item's judgments summed up: yes and no counts, the weight behind yes and behind all judgments (an unclassified judgment counts 1), and the reasons. `judgeClassIds` counts only judgments of those classes; `minJudgments` leaves out runs with fewer; `segments` keeps only runs started in that segment path or below it. Needs `admin` on the project.",
|
|
3679
4145
|
tags: ['eval-suites'],
|
|
3680
4146
|
security: 'bearer',
|
|
3681
4147
|
parameters: [EvalSuiteIdPathParam, IdempotencyKeyParam],
|
|
@@ -3685,7 +4151,7 @@ export const OPERATIONS = [
|
|
|
3685
4151
|
...CommonMutationErrors,
|
|
3686
4152
|
'400': ErrorResponse("Malformed body; or `projectId` isn't a project id (a UUID)."),
|
|
3687
4153
|
'403': ErrorResponse('`permission-denied`.'),
|
|
3688
|
-
'409': ErrorResponse(
|
|
4154
|
+
'409': ErrorResponse("`eval-suite-already-registered`: that (id, version) is taken. Or `eval-suite-project-mismatch`: the suite belongs to another project than the body's `projectId` (suites never move)."),
|
|
3689
4155
|
'501': ErrorResponse('`test-sets-not-supported`: this deployment cannot build test sets.'),
|
|
3690
4156
|
'404': ErrorResponse("The body's `projectId` names no project of this tenant (`project-not-found`)."),
|
|
3691
4157
|
},
|
|
@@ -3972,7 +4438,7 @@ export const OPERATIONS = [
|
|
|
3972
4438
|
openapiPath: '/v1/auth/providers',
|
|
3973
4439
|
operationId: 'auth.providers.list',
|
|
3974
4440
|
summary: 'List identity providers configured for the tenant',
|
|
3975
|
-
description:
|
|
4441
|
+
description: "Returns the tenant's identity providers (OIDC, SAML, OAuth 2.0), each with `signIn` when the deployment sets it. Secrets appear only as REFERENCES (`clientSecretRef`, `spSigningKeyRef`…); a plaintext secret is never on the wire.",
|
|
3976
4442
|
tags: ['auth'],
|
|
3977
4443
|
security: 'bearer',
|
|
3978
4444
|
responses: {
|
|
@@ -3983,23 +4449,150 @@ export const OPERATIONS = [
|
|
|
3983
4449
|
...CommonAuthErrors,
|
|
3984
4450
|
},
|
|
3985
4451
|
},
|
|
4452
|
+
{
|
|
4453
|
+
method: 'get',
|
|
4454
|
+
honoPath: '/v1/auth/sign-in-options',
|
|
4455
|
+
openapiPath: '/v1/auth/sign-in-options',
|
|
4456
|
+
operationId: 'auth.signInOptions',
|
|
4457
|
+
summary: 'How a person can sign in',
|
|
4458
|
+
description: 'Public: nobody is signed in yet. With `email`, the ways in for that email\'s domain: the identity providers of the one tenant the domain is verified for (an unverified domain offers none), then any the deployment offers everyone it has added (`owner: deployment`, "Continue with Google"); without, an empty list: sign-in is email first, so nothing is offered before an email. `methods` says which ways in the deployment allows: identity providers, an API token (`POST /v1/auth/token-sign-in`), and an emailed sign-in link (`emailLink`, with a captcha site key when it needs one); `identityProviders` and `apiToken` both `false` when nobody can sign in to the console. Always mounted. The answer depends only on the domain: two people at the same domain get the same answer, whether or not either has an account. Rate-limited per client (`429 rate-limit-exceeded`, with `Retry-After`).',
|
|
4459
|
+
tags: ['auth'],
|
|
4460
|
+
security: 'public',
|
|
4461
|
+
parameters: [
|
|
4462
|
+
{
|
|
4463
|
+
name: 'email',
|
|
4464
|
+
in: 'query',
|
|
4465
|
+
required: false,
|
|
4466
|
+
schema: { type: 'string', minLength: 3 },
|
|
4467
|
+
description: 'The email the person typed; only its domain is used.',
|
|
4468
|
+
},
|
|
4469
|
+
],
|
|
4470
|
+
responses: {
|
|
4471
|
+
'200': { description: 'The ways to sign in (possibly none).', schema: ref('SignInOptions') },
|
|
4472
|
+
'400': ErrorResponse('`email` is not an email address.'),
|
|
4473
|
+
'429': ErrorResponse('Too many lookups from this client.'),
|
|
4474
|
+
},
|
|
4475
|
+
},
|
|
4476
|
+
{
|
|
4477
|
+
method: 'post',
|
|
4478
|
+
honoPath: '/v1/auth/token-sign-in',
|
|
4479
|
+
openapiPath: '/v1/auth/token-sign-in',
|
|
4480
|
+
operationId: 'auth.tokenSignIn',
|
|
4481
|
+
summary: 'Sign in to the console with an API token',
|
|
4482
|
+
description: "The API token in `Authorization` is exchanged once for a browser session in the session cookie (HttpOnly; the same as a sign-in with an identity provider), so the browser never keeps the token. Only a person's full key opens a session: a service account's key, or a narrowed one (a `member` role, or one project), is refused `403 token-sign-in-not-allowed`. The session ends after its lifetime, or when the key expires if sooner. `403 token-sign-in-off` when the deployment doesn't allow it (always mounted, so a console gets that answer); `400 token-sign-in-needs-an-api-token` when the request is already signed in by a session.",
|
|
4483
|
+
tags: ['auth'],
|
|
4484
|
+
security: 'bearer',
|
|
4485
|
+
responses: {
|
|
4486
|
+
'200': {
|
|
4487
|
+
description: 'Signed in: the session cookie is set.',
|
|
4488
|
+
schema: ref('TokenSignInResult'),
|
|
4489
|
+
},
|
|
4490
|
+
...CommonAuthErrors,
|
|
4491
|
+
'400': ErrorResponse('Signed in by a session, not an API token (`token-sign-in-needs-an-api-token`).'),
|
|
4492
|
+
'403': ErrorResponse("Not allowed here (`token-sign-in-off`), or not this key (`token-sign-in-not-allowed`): a service account's, or a narrowed one."),
|
|
4493
|
+
'409': ErrorResponse("A retry with the Idempotency-Key of a sign-in that succeeded: its session was in the cookie, which isn't kept (`idempotency-key-replay-withheld`). Sign in again without the key."),
|
|
4494
|
+
},
|
|
4495
|
+
},
|
|
3986
4496
|
{
|
|
3987
4497
|
method: 'post',
|
|
3988
4498
|
honoPath: '/v1/auth/providers',
|
|
3989
4499
|
openapiPath: '/v1/auth/providers',
|
|
3990
4500
|
operationId: 'auth.providers.register',
|
|
3991
|
-
summary: 'Register
|
|
3992
|
-
description: 'Unique per tenant on `providerId`: re-registering a known provider returns `409 identity-provider-already-registered`
|
|
4501
|
+
summary: 'Register an identity provider (OIDC, SAML or OAuth 2.0)',
|
|
4502
|
+
description: 'Unique per tenant on `providerId`: re-registering a known provider returns `409 identity-provider-already-registered`; change it with `PATCH /v1/auth/providers/{providerId}`, which keeps its sign-in URLs. Secrets are given by reference (`clientSecretRef`, `spSigningKeyRef`…); a `clientSecret` (or a raw key) is refused with `400 invalid-provider-config`. The deployment may check the configuration (OIDC discovery, SAML metadata): `422 identity-provider-invalid` says what failed. The answer carries the stored provider when the deployment returns it, with `signIn`: what to give the identity provider.',
|
|
3993
4503
|
tags: ['auth'],
|
|
3994
4504
|
security: 'bearer',
|
|
3995
4505
|
parameters: [IdempotencyKeyParam],
|
|
3996
|
-
requestBody: { required: true, schema: ref('
|
|
4506
|
+
requestBody: { required: true, schema: ref('RegisterIdentityProviderBody') },
|
|
3997
4507
|
responses: {
|
|
3998
4508
|
'201': {
|
|
3999
4509
|
description: 'Provider registered.',
|
|
4000
4510
|
schema: ref('RegisterIdentityProviderResult'),
|
|
4001
4511
|
},
|
|
4002
4512
|
...CommonMutationErrors,
|
|
4513
|
+
'422': ErrorResponse('The deployment could not use the configuration (`identity-provider-invalid`).'),
|
|
4514
|
+
},
|
|
4515
|
+
},
|
|
4516
|
+
{
|
|
4517
|
+
method: 'get',
|
|
4518
|
+
honoPath: '/v1/auth/providers/:providerId',
|
|
4519
|
+
openapiPath: '/v1/auth/providers/{providerId}',
|
|
4520
|
+
operationId: 'auth.providers.get',
|
|
4521
|
+
summary: 'Get one identity provider',
|
|
4522
|
+
description: 'The provider as stored, with `signIn` when the deployment sets it. Secrets appear only as references.',
|
|
4523
|
+
tags: ['auth'],
|
|
4524
|
+
security: 'bearer',
|
|
4525
|
+
parameters: [
|
|
4526
|
+
{
|
|
4527
|
+
name: 'providerId',
|
|
4528
|
+
in: 'path',
|
|
4529
|
+
required: true,
|
|
4530
|
+
schema: { type: 'string', minLength: 1 },
|
|
4531
|
+
},
|
|
4532
|
+
],
|
|
4533
|
+
responses: {
|
|
4534
|
+
'200': { description: 'The provider.', schema: ref('GetIdentityProviderResult') },
|
|
4535
|
+
...CommonAuthErrors,
|
|
4536
|
+
'404': ErrorResponse('No identity provider registered with that id under this tenant.'),
|
|
4537
|
+
},
|
|
4538
|
+
},
|
|
4539
|
+
{
|
|
4540
|
+
method: 'get',
|
|
4541
|
+
honoPath: '/v1/auth/providers/:providerId/sign-in',
|
|
4542
|
+
openapiPath: '/v1/auth/providers/{providerId}/sign-in',
|
|
4543
|
+
operationId: 'auth.providers.signIn',
|
|
4544
|
+
summary: 'What to give the identity provider, before or after registering',
|
|
4545
|
+
description: "The redirect URI (OIDC) or the ACS URL, entity ID and metadata URL (SAML) a provider under this `providerId` gets: the same before it's registered, after, and after an unregister and a new registration. So an admin sets up the identity provider's side first, then registers with what it gives back. `kind` is required until the provider is registered. Not mounted when the deployment can't say.",
|
|
4546
|
+
tags: ['auth'],
|
|
4547
|
+
security: 'bearer',
|
|
4548
|
+
parameters: [
|
|
4549
|
+
{
|
|
4550
|
+
name: 'providerId',
|
|
4551
|
+
in: 'path',
|
|
4552
|
+
required: true,
|
|
4553
|
+
schema: { type: 'string', minLength: 1 },
|
|
4554
|
+
},
|
|
4555
|
+
{
|
|
4556
|
+
name: 'kind',
|
|
4557
|
+
in: 'query',
|
|
4558
|
+
required: false,
|
|
4559
|
+
schema: { $ref: '#/components/schemas/IdentityProviderKind' },
|
|
4560
|
+
description: "The provider's kind; default: the registered provider's.",
|
|
4561
|
+
},
|
|
4562
|
+
],
|
|
4563
|
+
responses: {
|
|
4564
|
+
'200': {
|
|
4565
|
+
description: 'What to give the identity provider.',
|
|
4566
|
+
schema: ref('IdentityProviderSignInUrls'),
|
|
4567
|
+
},
|
|
4568
|
+
...CommonAuthErrors,
|
|
4569
|
+
'400': ErrorResponse("`kind` missing for a provider that isn't registered, or a kind this deployment doesn't sign in with (`bad-input`)."),
|
|
4570
|
+
},
|
|
4571
|
+
},
|
|
4572
|
+
{
|
|
4573
|
+
method: 'patch',
|
|
4574
|
+
honoPath: '/v1/auth/providers/:providerId',
|
|
4575
|
+
openapiPath: '/v1/auth/providers/{providerId}',
|
|
4576
|
+
operationId: 'auth.providers.update',
|
|
4577
|
+
summary: 'Change an identity provider, keeping its sign-in URLs',
|
|
4578
|
+
description: "Merges the changes into the stored provider and checks the result as a registration is (`400 invalid-provider-config`; `422 identity-provider-invalid` when the deployment can't use it). The provider keeps its `signIn`, so nothing changes on the identity provider's side. Not mounted when the deployment can't update providers.",
|
|
4579
|
+
tags: ['auth'],
|
|
4580
|
+
security: 'bearer',
|
|
4581
|
+
parameters: [
|
|
4582
|
+
{
|
|
4583
|
+
name: 'providerId',
|
|
4584
|
+
in: 'path',
|
|
4585
|
+
required: true,
|
|
4586
|
+
schema: { type: 'string', minLength: 1 },
|
|
4587
|
+
},
|
|
4588
|
+
IdempotencyKeyParam,
|
|
4589
|
+
],
|
|
4590
|
+
requestBody: { required: true, schema: ref('UpdateIdentityProviderBody') },
|
|
4591
|
+
responses: {
|
|
4592
|
+
'200': { description: 'Updated.', schema: ref('UpdateIdentityProviderResult') },
|
|
4593
|
+
...CommonMutationErrors,
|
|
4594
|
+
'404': ErrorResponse('No identity provider registered with that id under this tenant.'),
|
|
4595
|
+
'422': ErrorResponse('The deployment could not use the configuration (`identity-provider-invalid`).'),
|
|
4003
4596
|
},
|
|
4004
4597
|
},
|
|
4005
4598
|
{
|
|
@@ -4086,14 +4679,15 @@ export const OPERATIONS = [
|
|
|
4086
4679
|
openapiPath: '/v1/auth/refresh',
|
|
4087
4680
|
operationId: 'auth.refresh',
|
|
4088
4681
|
summary: 'Refresh the current session token',
|
|
4089
|
-
description: 'Requires a session token (`kgi_sk_*`); bearer tokens are managed via `/v1/tokens`. When the deployment wired a `refreshToken` callback and the provider issued a refresh token, provider tokens rotate too; otherwise only the framework session token rotates. OAuth 2.1 BCP refresh-token rotation: the OLD session token is invalidated (marked rotated) — reusing it after refresh returns `401 refresh-token-invalid` so compliant clients can retry with the fresh token instead of prompting a re-auth.',
|
|
4682
|
+
description: 'Requires a session token (`kgi_sk_*`); bearer tokens are managed via `/v1/tokens`. When the deployment wired a `refreshToken` callback and the provider issued a refresh token, provider tokens rotate too; otherwise only the framework session token rotates. OAuth 2.1 BCP refresh-token rotation: the OLD session token is invalidated (marked rotated) — reusing it after refresh returns `401 refresh-token-invalid` so compliant clients can retry with the fresh token instead of prompting a re-auth. A browser session (the session cookie) is not refreshed: `400 cookie-session-not-refreshable`, so a new token never reaches page scripts; it ends at its TTL.',
|
|
4090
4683
|
tags: ['auth'],
|
|
4091
4684
|
security: 'bearer',
|
|
4092
4685
|
parameters: [IdempotencyKeyParam],
|
|
4093
4686
|
responses: {
|
|
4094
4687
|
'200': { description: 'New session token.', schema: ref('RefreshResult') },
|
|
4095
4688
|
...CommonMutationErrors,
|
|
4096
|
-
'
|
|
4689
|
+
'409': ErrorResponse("Idempotency-Key reused with a different body (`idempotency-key-body-mismatch`), or a retry of a request that succeeded: its answer carried a secret, which isn't kept (`idempotency-key-replay-withheld`, with its `status` and `at`)."),
|
|
4690
|
+
'400': ErrorResponse('Caller presented a bearer token (refresh is session-only), or a browser session (cookie).'),
|
|
4097
4691
|
'404': ErrorResponse('Session no longer exists.'),
|
|
4098
4692
|
'422': ErrorResponse('Refresh with the provider failed.'),
|
|
4099
4693
|
},
|
|
@@ -4104,7 +4698,7 @@ export const OPERATIONS = [
|
|
|
4104
4698
|
openapiPath: '/v1/auth/logout',
|
|
4105
4699
|
operationId: 'auth.logout',
|
|
4106
4700
|
summary: 'Revoke the current session',
|
|
4107
|
-
description: 'Requires a session token (`kgi_sk_*`); bearer tokens are managed via `/v1/tokens`. Idempotent — revoking an already-revoked session returns `{ revoked: false }`.',
|
|
4701
|
+
description: 'Requires a session token (`kgi_sk_*`); bearer tokens are managed via `/v1/tokens`. Idempotent — revoking an already-revoked session returns `{ revoked: false }`. A browser session (the session cookie) also gets its cookie cleared (`Set-Cookie` with `Max-Age=0`).',
|
|
4108
4702
|
tags: ['auth'],
|
|
4109
4703
|
security: 'bearer',
|
|
4110
4704
|
parameters: [IdempotencyKeyParam],
|
|
@@ -4121,7 +4715,7 @@ export const OPERATIONS = [
|
|
|
4121
4715
|
openapiPath: '/v1/identity/users',
|
|
4122
4716
|
operationId: 'identity.users.list',
|
|
4123
4717
|
summary: 'List users in the tenant',
|
|
4124
|
-
description: 'Cursor-paginated list of tenant users (sort order is binding-defined). Optional `?query=` is a prefix match on `displayName` — the natural filter shape for a "search users" surface. `primaryEmail` may be redacted per tenant policy.',
|
|
4718
|
+
description: 'Cursor-paginated list of tenant users (sort order is binding-defined), for tenant admins only. Optional `?query=` is a prefix match on `displayName` — the natural filter shape for a "search users" surface. `primaryEmail` may be redacted per tenant policy. Anyone else adds a person to a project by their email or id (`POST /v1/projects/{projectId}/memberships`).',
|
|
4125
4719
|
tags: ['identity'],
|
|
4126
4720
|
security: 'bearer',
|
|
4127
4721
|
parameters: [
|
|
@@ -4134,10 +4728,36 @@ export const OPERATIONS = [
|
|
|
4134
4728
|
description: 'Prefix match on `displayName`.',
|
|
4135
4729
|
schema: { type: 'string' },
|
|
4136
4730
|
},
|
|
4731
|
+
{
|
|
4732
|
+
name: 'includeUnregistered',
|
|
4733
|
+
in: 'query',
|
|
4734
|
+
required: false,
|
|
4735
|
+
description: 'With `true`, people who were removed (`unregisteredAt`) too.',
|
|
4736
|
+
schema: { type: 'boolean' },
|
|
4737
|
+
},
|
|
4137
4738
|
],
|
|
4138
4739
|
responses: {
|
|
4139
4740
|
'200': { description: 'Page of users.', schema: ref('UserCollectionPage') },
|
|
4140
4741
|
...CommonAuthErrors,
|
|
4742
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
4743
|
+
},
|
|
4744
|
+
},
|
|
4745
|
+
{
|
|
4746
|
+
method: 'post',
|
|
4747
|
+
honoPath: '/v1/identity/users',
|
|
4748
|
+
openapiPath: '/v1/identity/users',
|
|
4749
|
+
operationId: 'identity.users.create',
|
|
4750
|
+
summary: 'Add a person',
|
|
4751
|
+
description: "Adds a person to the tenant as a tenant member, written before it answers: they can read the tenant's settings (providers, policies, adapters, signing keys, deployments), not its projects. Give them a role to work (project or team membership, or tenant admin), then mint their first API key at `POST /v1/tokens` with `for`. Tenant admins only. Mounted when the identity directory can add people.",
|
|
4752
|
+
tags: ['identity'],
|
|
4753
|
+
security: 'bearer',
|
|
4754
|
+
parameters: [IdempotencyKeyParam],
|
|
4755
|
+
requestBody: { required: true, schema: ref('CreateUserBody') },
|
|
4756
|
+
responses: {
|
|
4757
|
+
'201': { description: 'The new person.', schema: ref('UserRecord') },
|
|
4758
|
+
...CommonMutationErrors,
|
|
4759
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
4760
|
+
'409': ErrorResponse('Another person of the tenant has the email (`identity-user-email-taken`), or an idempotency conflict.'),
|
|
4141
4761
|
},
|
|
4142
4762
|
},
|
|
4143
4763
|
{
|
|
@@ -4146,6 +4766,7 @@ export const OPERATIONS = [
|
|
|
4146
4766
|
openapiPath: '/v1/identity/users/{userId}',
|
|
4147
4767
|
operationId: 'identity.users.get',
|
|
4148
4768
|
summary: 'Get a user by id',
|
|
4769
|
+
description: 'A tenant admin, or the person themselves.',
|
|
4149
4770
|
tags: ['identity'],
|
|
4150
4771
|
security: 'bearer',
|
|
4151
4772
|
parameters: [
|
|
@@ -4154,6 +4775,7 @@ export const OPERATIONS = [
|
|
|
4154
4775
|
responses: {
|
|
4155
4776
|
'200': { description: 'User record.', schema: ref('UserRecord') },
|
|
4156
4777
|
...CommonAuthErrors,
|
|
4778
|
+
'403': ErrorResponse("Someone else's record, and not a tenant admin."),
|
|
4157
4779
|
'404': ErrorResponse('No user with that id under this tenant.'),
|
|
4158
4780
|
},
|
|
4159
4781
|
},
|
|
@@ -4163,7 +4785,7 @@ export const OPERATIONS = [
|
|
|
4163
4785
|
openapiPath: '/v1/identity/users/{userId}/sessions',
|
|
4164
4786
|
operationId: 'identity.users.listSessions',
|
|
4165
4787
|
summary: 'List active sessions for a user',
|
|
4166
|
-
description: 'Returns the wire-safe `IdentitySessionSummary` shape — provider access-token + refresh-token never cross the wire, even to admins. Unknown user id returns an empty list (call `GET /v1/identity/users/:userId` first to distinguish "no sessions" from "no user").',
|
|
4788
|
+
description: 'A tenant admin, or the person themselves. Returns the wire-safe `IdentitySessionSummary` shape — provider access-token + refresh-token never cross the wire, even to admins. Unknown user id returns an empty list (call `GET /v1/identity/users/:userId` first to distinguish "no sessions" from "no user").',
|
|
4167
4789
|
tags: ['identity'],
|
|
4168
4790
|
security: 'bearer',
|
|
4169
4791
|
parameters: [
|
|
@@ -4172,6 +4794,31 @@ export const OPERATIONS = [
|
|
|
4172
4794
|
responses: {
|
|
4173
4795
|
'200': { description: 'Page of sessions.', schema: ref('IdentitySessionCollectionPage') },
|
|
4174
4796
|
...CommonAuthErrors,
|
|
4797
|
+
'403': ErrorResponse("Someone else's sessions, and not a tenant admin."),
|
|
4798
|
+
},
|
|
4799
|
+
},
|
|
4800
|
+
{
|
|
4801
|
+
method: 'post',
|
|
4802
|
+
honoPath: '/v1/identity/users/:userId/unregister',
|
|
4803
|
+
openapiPath: '/v1/identity/users/{userId}/unregister',
|
|
4804
|
+
operationId: 'identity.users.unregister',
|
|
4805
|
+
summary: 'Remove a person',
|
|
4806
|
+
description: "Removes a person from the tenant, in one step: they're marked removed (`unregisteredAt`; their record stays, so their history still says who they were), every API key and session of theirs is revoked, and every grant and membership they hold is taken away, all before it answers. Their keys get `401` at once. Their email is free again: adding it makes a new person. Removing someone already removed changes nothing. Refused for yourself and the deployment's seed user (`identity-user-unregister-refused`), and for the only tenant admin (`last-tenant-admin`). Tenant admins only. Mounted when the identity directory can remove people.",
|
|
4807
|
+
tags: ['identity'],
|
|
4808
|
+
security: 'bearer',
|
|
4809
|
+
parameters: [
|
|
4810
|
+
{ name: 'userId', in: 'path', required: true, schema: { type: 'string', minLength: 1 } },
|
|
4811
|
+
IdempotencyKeyParam,
|
|
4812
|
+
],
|
|
4813
|
+
responses: {
|
|
4814
|
+
'200': {
|
|
4815
|
+
description: 'The removed person, and what removing them took away.',
|
|
4816
|
+
schema: ref('UnregisterUserResult'),
|
|
4817
|
+
},
|
|
4818
|
+
...CommonMutationErrors,
|
|
4819
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
4820
|
+
'404': ErrorResponse('No user with that id under this tenant (`identity-user-not-found`).'),
|
|
4821
|
+
'409': ErrorResponse('Yourself or the seed user (`identity-user-unregister-refused`, `details.reason`), the only tenant admin (`last-tenant-admin`), or an idempotency conflict.'),
|
|
4175
4822
|
},
|
|
4176
4823
|
},
|
|
4177
4824
|
{
|
|
@@ -4180,7 +4827,7 @@ export const OPERATIONS = [
|
|
|
4180
4827
|
openapiPath: '/v1/identity/users/{userId}/revoke-sessions',
|
|
4181
4828
|
operationId: 'identity.users.revokeSessions',
|
|
4182
4829
|
summary: 'Revoke every active session for a user',
|
|
4183
|
-
description: '
|
|
4830
|
+
description: "A tenant admin revokes anyone's sessions; anyone else only their own. Idempotent. Under the hood, deployments typically delegate to `SessionStoreBinding.revokeAllForUser`. Returns `{ revokedCount: 0 }` when the user was already fully signed out.",
|
|
4184
4831
|
tags: ['identity'],
|
|
4185
4832
|
security: 'bearer',
|
|
4186
4833
|
parameters: [
|
|
@@ -4190,9 +4837,76 @@ export const OPERATIONS = [
|
|
|
4190
4837
|
responses: {
|
|
4191
4838
|
'200': { description: 'Revocation outcome.', schema: ref('RevokeSessionsResult') },
|
|
4192
4839
|
...CommonMutationErrors,
|
|
4840
|
+
'403': ErrorResponse("Another person's sessions, and not a tenant admin."),
|
|
4193
4841
|
'500': ErrorResponse('Session revocation failed inside the caller-plugged binding.'),
|
|
4194
4842
|
},
|
|
4195
4843
|
},
|
|
4844
|
+
{
|
|
4845
|
+
method: 'get',
|
|
4846
|
+
honoPath: '/v1/identity/users/:userId/grants',
|
|
4847
|
+
openapiPath: '/v1/identity/users/{userId}/grants',
|
|
4848
|
+
operationId: 'identity.users.grants',
|
|
4849
|
+
summary: "Read a person's grants",
|
|
4850
|
+
description: "What the person may do, as granted directly: tenant admin, project and team roles, the reviewer roster. A tenant admin reads anyone's; anyone else only their own.",
|
|
4851
|
+
tags: ['identity'],
|
|
4852
|
+
security: 'bearer',
|
|
4853
|
+
parameters: [
|
|
4854
|
+
{ name: 'userId', in: 'path', required: true, schema: { type: 'string', minLength: 1 } },
|
|
4855
|
+
],
|
|
4856
|
+
responses: {
|
|
4857
|
+
'200': { description: "The person's grants.", schema: ref('PersonGrants') },
|
|
4858
|
+
...CommonAuthErrors,
|
|
4859
|
+
'403': ErrorResponse("Another person's grants, and not a tenant admin."),
|
|
4860
|
+
'404': ErrorResponse('No user with that id under this tenant (`identity-user-not-found`).'),
|
|
4861
|
+
'501': ErrorResponse('The runtime has no authorization store (`person-grants-unsupported`).'),
|
|
4862
|
+
},
|
|
4863
|
+
},
|
|
4864
|
+
{
|
|
4865
|
+
method: 'post',
|
|
4866
|
+
honoPath: '/v1/identity/users/:userId/grant',
|
|
4867
|
+
openapiPath: '/v1/identity/users/{userId}/grant',
|
|
4868
|
+
operationId: 'identity.users.grant',
|
|
4869
|
+
summary: 'Make a person a tenant admin',
|
|
4870
|
+
description: "Written before the call answers, so the person's next request holds it. A no-op when held. Tenant admins only.",
|
|
4871
|
+
tags: ['identity'],
|
|
4872
|
+
security: 'bearer',
|
|
4873
|
+
parameters: [
|
|
4874
|
+
{ name: 'userId', in: 'path', required: true, schema: { type: 'string', minLength: 1 } },
|
|
4875
|
+
IdempotencyKeyParam,
|
|
4876
|
+
],
|
|
4877
|
+
requestBody: { required: true, schema: ref('PersonGrantBody') },
|
|
4878
|
+
responses: {
|
|
4879
|
+
'200': { description: "The person's grants, after.", schema: ref('PersonGrants') },
|
|
4880
|
+
...CommonMutationErrors,
|
|
4881
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
4882
|
+
'404': ErrorResponse('No user with that id under this tenant (`identity-user-not-found`).'),
|
|
4883
|
+
'409': ErrorResponse('The person was removed from the tenant (`identity-user-unregistered`), or an idempotency conflict.'),
|
|
4884
|
+
'501': ErrorResponse('The runtime has no authorization store (`person-grants-unsupported`).'),
|
|
4885
|
+
},
|
|
4886
|
+
},
|
|
4887
|
+
{
|
|
4888
|
+
method: 'post',
|
|
4889
|
+
honoPath: '/v1/identity/users/:userId/ungrant',
|
|
4890
|
+
openapiPath: '/v1/identity/users/{userId}/ungrant',
|
|
4891
|
+
operationId: 'identity.users.ungrant',
|
|
4892
|
+
summary: 'Remove tenant admin from a person',
|
|
4893
|
+
description: 'A no-op when not held. Refused for the only person who is a tenant admin (`last-tenant-admin`: make someone else one first), and for the seed user, whom the runtime makes tenant admin at every boot (`seed-user-admin`: unset `KINDGI_SEED_USER_ID` and restart it first). Tenant admins only.',
|
|
4894
|
+
tags: ['identity'],
|
|
4895
|
+
security: 'bearer',
|
|
4896
|
+
parameters: [
|
|
4897
|
+
{ name: 'userId', in: 'path', required: true, schema: { type: 'string', minLength: 1 } },
|
|
4898
|
+
IdempotencyKeyParam,
|
|
4899
|
+
],
|
|
4900
|
+
requestBody: { required: true, schema: ref('PersonGrantBody') },
|
|
4901
|
+
responses: {
|
|
4902
|
+
'200': { description: "The person's grants, after.", schema: ref('PersonGrants') },
|
|
4903
|
+
...CommonMutationErrors,
|
|
4904
|
+
'403': ErrorResponse('Not a tenant admin.'),
|
|
4905
|
+
'404': ErrorResponse('No user with that id under this tenant (`identity-user-not-found`).'),
|
|
4906
|
+
'409': ErrorResponse('The only person who is a tenant admin (`last-tenant-admin`), the seed user (`seed-user-admin`), or an idempotency conflict.'),
|
|
4907
|
+
'501': ErrorResponse('The runtime has no authorization store (`person-grants-unsupported`).'),
|
|
4908
|
+
},
|
|
4909
|
+
},
|
|
4196
4910
|
{
|
|
4197
4911
|
method: 'get',
|
|
4198
4912
|
honoPath: '/v1/identity/whoami',
|
|
@@ -4226,7 +4940,7 @@ export const OPERATIONS = [
|
|
|
4226
4940
|
schema: ref('DeploymentRecord'),
|
|
4227
4941
|
},
|
|
4228
4942
|
...CommonMutationErrors,
|
|
4229
|
-
'409': ErrorResponse("Idempotency-Key was reused with a different body, or resource-state conflict. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead."),
|
|
4943
|
+
'409': ErrorResponse("Idempotency-Key was reused with a different body, or resource-state conflict. Or `tool-project-mismatch`, `agent-project-mismatch` or `flow-project-mismatch`: one of the image's tools, agents or flows belongs to another project (`details.primitive`, `details.id`; the message doesn't name the project); nothing was deployed, even when it was unchanged. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead."),
|
|
4230
4944
|
'400': ErrorResponse('Signature invalid, image unverifiable, or deployment-validation-failed with per-primitive `details[]`.'),
|
|
4231
4945
|
'403': ErrorResponse("Signer key not on the tenant's trust list."),
|
|
4232
4946
|
},
|
|
@@ -4415,11 +5129,11 @@ export const OPERATIONS = [
|
|
|
4415
5129
|
openapiPath: '/v1/compliance/evidence/export',
|
|
4416
5130
|
operationId: 'compliance.evidence.export',
|
|
4417
5131
|
summary: 'Export a signed compliance-evidence bundle',
|
|
4418
|
-
description: "
|
|
5132
|
+
description: "Signs the evidence the filter matches (exportable kinds only) with the deployment's export key, and records the export (an `export-signed` audit event). The same envelope as the other signed exports; check `publicKey` against `GET /v1/export-signing-keys`. A deployment with no export key answers `404 signing-not-configured`.",
|
|
4419
5133
|
tags: ['compliance'],
|
|
4420
5134
|
security: 'bearer',
|
|
4421
5135
|
parameters: [IdempotencyKeyParam],
|
|
4422
|
-
requestBody: { required:
|
|
5136
|
+
requestBody: { required: false, schema: ref('ExportComplianceEvidenceBody') },
|
|
4423
5137
|
responses: {
|
|
4424
5138
|
'200': {
|
|
4425
5139
|
description: 'Signed evidence bundle.',
|
|
@@ -4916,12 +5630,13 @@ export const OPERATIONS = [
|
|
|
4916
5630
|
openapiPath: '/v1/projects/default',
|
|
4917
5631
|
operationId: 'projects.getDefault',
|
|
4918
5632
|
summary: "Fetch the tenant's Default project",
|
|
4919
|
-
description: 'Returns the row where `Project.isDefault = true` (exactly one per tenant). Returns 404 `project-not-found` when no Default has been provisioned.',
|
|
5633
|
+
description: 'Returns the row where `Project.isDefault = true` (exactly one per tenant), to a caller who can read it, as `GET /v1/projects/{projectId}` checks. Returns 404 `project-not-found` when no Default has been provisioned.',
|
|
4920
5634
|
tags: ['projects'],
|
|
4921
5635
|
security: 'bearer',
|
|
4922
5636
|
responses: {
|
|
4923
5637
|
'200': { description: 'Default project.', schema: ref('Project') },
|
|
4924
5638
|
...CommonAuthErrors,
|
|
5639
|
+
'403': ErrorResponse("The caller can't read the Default project."),
|
|
4925
5640
|
'404': ErrorResponse('Tenant has no Default project.'),
|
|
4926
5641
|
},
|
|
4927
5642
|
},
|
|
@@ -5082,7 +5797,7 @@ export const OPERATIONS = [
|
|
|
5082
5797
|
openapiPath: '/v1/projects/{projectId}/memberships',
|
|
5083
5798
|
operationId: 'projects.memberships.add',
|
|
5084
5799
|
summary: 'Add a user directly to a project',
|
|
5085
|
-
description: 'Idempotent on `(projectId, userId)` — re-adding an existing member with a different role does NOT overwrite; use PATCH for role changes.',
|
|
5800
|
+
description: 'Names the person by exactly one of `userId` and `email` (matched as the runtime matches emails when it adds a person); someone who is not a person of this tenant, or was removed from it, is refused with 404 `identity-user-not-found`. Idempotent on `(projectId, userId)` — re-adding an existing member with a different role does NOT overwrite; use PATCH for role changes.',
|
|
5086
5801
|
tags: ['projects'],
|
|
5087
5802
|
security: 'bearer',
|
|
5088
5803
|
parameters: [
|
|
@@ -5102,7 +5817,7 @@ export const OPERATIONS = [
|
|
|
5102
5817
|
schema: ref('AddProjectMembershipResult'),
|
|
5103
5818
|
},
|
|
5104
5819
|
...CommonMutationErrors,
|
|
5105
|
-
'404': ErrorResponse('No project with that id under this tenant.'),
|
|
5820
|
+
'404': ErrorResponse('No project with that id under this tenant (`project-not-found`), or the person named is not a member of this tenant (`identity-user-not-found`).'),
|
|
5106
5821
|
},
|
|
5107
5822
|
},
|
|
5108
5823
|
{
|
|
@@ -5294,7 +6009,7 @@ export const OPERATIONS = [
|
|
|
5294
6009
|
openapiPath: '/v1/env/{name}',
|
|
5295
6010
|
operationId: 'env.put',
|
|
5296
6011
|
summary: 'Upsert an env entry',
|
|
5297
|
-
description:
|
|
6012
|
+
description: "Requires the `env:write` capability. Every write bumps `revision`; optional `ifRevision` guards against concurrent updates (409 `env-write-conflict`). Env values aren't secret: they're recorded with each run that uses them. A credential goes in `/v1/secrets`.",
|
|
5298
6013
|
tags: ['env'],
|
|
5299
6014
|
security: 'bearer',
|
|
5300
6015
|
parameters: [
|
|
@@ -5632,7 +6347,16 @@ export const OPERATIONS = [
|
|
|
5632
6347
|
summary: 'Fetch a cron schedule',
|
|
5633
6348
|
tags: ['schedules'],
|
|
5634
6349
|
security: 'bearer',
|
|
5635
|
-
parameters: [
|
|
6350
|
+
parameters: [
|
|
6351
|
+
TriggerIdPathParam,
|
|
6352
|
+
{
|
|
6353
|
+
name: 'upcoming',
|
|
6354
|
+
in: 'query',
|
|
6355
|
+
required: false,
|
|
6356
|
+
description: 'Include the next N occurrences (`upcoming`), 1 to 20.',
|
|
6357
|
+
schema: { type: 'integer', minimum: 1, maximum: 20 },
|
|
6358
|
+
},
|
|
6359
|
+
],
|
|
5636
6360
|
responses: {
|
|
5637
6361
|
'200': { description: 'Schedule record.', schema: ref('ScheduleRecord') },
|
|
5638
6362
|
...CommonAuthErrors,
|
|
@@ -5703,6 +6427,60 @@ export const OPERATIONS = [
|
|
|
5703
6427
|
...CommonMutationErrors,
|
|
5704
6428
|
},
|
|
5705
6429
|
},
|
|
6430
|
+
{
|
|
6431
|
+
method: 'get',
|
|
6432
|
+
honoPath: '/v1/schedules/:triggerId/fires',
|
|
6433
|
+
openapiPath: '/v1/schedules/{triggerId}/fires',
|
|
6434
|
+
operationId: 'schedules.fires',
|
|
6435
|
+
summary: "A schedule's fire history",
|
|
6436
|
+
description: 'Newest first: each occurrence (and `run-now`) the schedule fired for, and what came of it: the run it started, or why it was skipped, refused or failed.',
|
|
6437
|
+
tags: ['schedules'],
|
|
6438
|
+
security: 'bearer',
|
|
6439
|
+
parameters: [TriggerIdPathParam, LimitQueryParam, CursorQueryParam],
|
|
6440
|
+
responses: {
|
|
6441
|
+
'200': { description: 'Page of fires.', schema: ref('ScheduleFirePage') },
|
|
6442
|
+
...CommonAuthErrors,
|
|
6443
|
+
'404': ErrorResponse('No cron trigger with that id.'),
|
|
6444
|
+
'501': ErrorResponse('`trigger-operation-unsupported`: this deployment keeps no fire history.'),
|
|
6445
|
+
},
|
|
6446
|
+
},
|
|
6447
|
+
{
|
|
6448
|
+
method: 'post',
|
|
6449
|
+
honoPath: '/v1/schedules/:triggerId/run-now',
|
|
6450
|
+
openapiPath: '/v1/schedules/{triggerId}/run-now',
|
|
6451
|
+
operationId: 'schedules.runNow',
|
|
6452
|
+
summary: 'Run a schedule now',
|
|
6453
|
+
description: "One fire outside the schedule (`manual: true` in its history), starting one run as the schedule's owner. The schedule's next occurrence is unchanged.",
|
|
6454
|
+
tags: ['schedules'],
|
|
6455
|
+
security: 'bearer',
|
|
6456
|
+
parameters: [TriggerIdPathParam, IdempotencyKeyParam],
|
|
6457
|
+
responses: {
|
|
6458
|
+
'202': {
|
|
6459
|
+
description: 'The fire; its run starts in the background.',
|
|
6460
|
+
schema: ref('ScheduleFire'),
|
|
6461
|
+
},
|
|
6462
|
+
...CommonMutationErrors,
|
|
6463
|
+
'404': ErrorResponse('No cron trigger with that id.'),
|
|
6464
|
+
'501': ErrorResponse('`trigger-operation-unsupported`: this deployment has no run-now.'),
|
|
6465
|
+
},
|
|
6466
|
+
},
|
|
6467
|
+
{
|
|
6468
|
+
method: 'post',
|
|
6469
|
+
honoPath: '/v1/schedules/:triggerId/owner',
|
|
6470
|
+
openapiPath: '/v1/schedules/{triggerId}/owner',
|
|
6471
|
+
operationId: 'schedules.takeOwnership',
|
|
6472
|
+
summary: 'Take over a schedule',
|
|
6473
|
+
description: "The caller becomes the schedule's owner, so its runs act as the caller from the next fire. Needs `admin` on the schedule's project and `execute` on what it runs. For a schedule whose owner left or lost access.",
|
|
6474
|
+
tags: ['schedules'],
|
|
6475
|
+
security: 'bearer',
|
|
6476
|
+
parameters: [TriggerIdPathParam, IdempotencyKeyParam],
|
|
6477
|
+
responses: {
|
|
6478
|
+
'200': { description: 'The schedule, with its new owner.', schema: ref('ScheduleRecord') },
|
|
6479
|
+
...CommonMutationErrors,
|
|
6480
|
+
'404': ErrorResponse('No cron trigger with that id.'),
|
|
6481
|
+
'501': ErrorResponse("`trigger-operation-unsupported`: this deployment can't change a schedule's owner."),
|
|
6482
|
+
},
|
|
6483
|
+
},
|
|
5706
6484
|
// ---------- event-triggers (trigger surface) ----------
|
|
5707
6485
|
{
|
|
5708
6486
|
method: 'post',
|
|
@@ -5945,12 +6723,13 @@ export const OPERATIONS = [
|
|
|
5945
6723
|
openapiPath: '/v1/webhook-endpoints/generate-secret',
|
|
5946
6724
|
operationId: 'webhookEndpoints.generateSecret',
|
|
5947
6725
|
summary: 'Generate a webhook signing secret',
|
|
5948
|
-
description: 'Returns a new strong secret (`whsec_` + base64 of 32 random bytes). Nothing is stored: put it in your secrets, then register the endpoint with its name.',
|
|
6726
|
+
description: 'Returns a new strong secret (`whsec_` + base64 of 32 random bytes). Nothing is stored: put it in your secrets, then register the endpoint with its name. Sent with an `Idempotency-Key`, a retry gets `409 idempotency-key-replay-withheld`, not the secret again.',
|
|
5949
6727
|
tags: ['webhook-endpoints'],
|
|
5950
6728
|
security: 'bearer',
|
|
5951
6729
|
responses: {
|
|
5952
6730
|
'200': { description: 'A new secret.', schema: ref('GeneratedWebhookSecret') },
|
|
5953
6731
|
...CommonAuthErrors,
|
|
6732
|
+
'409': ErrorResponse("A retry with the Idempotency-Key of a request that succeeded: the secret isn't kept (`idempotency-key-replay-withheld`)."),
|
|
5954
6733
|
},
|
|
5955
6734
|
},
|
|
5956
6735
|
{
|