@kindgi/api 0.1.4 → 0.1.5
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/cost-binding.d.ts +19 -0
- package/dist/cost-binding.d.ts.map +1 -1
- package/dist/cost-binding.js.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 +75 -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 +9 -0
- package/dist/middleware/authorize.d.ts.map +1 -1
- package/dist/middleware/authorize.js +122 -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 +919 -140
- package/dist/openapi/operations.js.map +1 -1
- package/dist/openapi/schemas.d.ts +90 -13
- package/dist/openapi/schemas.d.ts.map +1 -1
- package/dist/openapi/schemas.js +2081 -359
- 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 +28 -3
- package/dist/publish-refused.d.ts.map +1 -1
- package/dist/publish-refused.js +24 -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 +12 -1
- package/dist/routes/cost.d.ts.map +1 -1
- package/dist/routes/cost.js +74 -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 +10 -1
- package/dist/routes/deployments.d.ts.map +1 -1
- package/dist/routes/deployments.js +171 -13
- 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 +66 -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 +28 -2
- 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 +114 -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 +110 -3
- 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/readable-projects.d.ts +26 -0
- package/dist/routes/readable-projects.d.ts.map +1 -0
- package/dist/routes/readable-projects.js +39 -0
- package/dist/routes/readable-projects.js.map +1 -0
- 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 +15387 -8789
- 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/cost-binding.ts +19 -0
- package/src/derive-agent-version.ts +9 -1
- package/src/errors.ts +75 -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 +155 -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 +1060 -143
- package/src/openapi/schemas.ts +2387 -469
- 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 +56 -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 +110 -4
- package/src/routes/denied.ts +28 -0
- package/src/routes/deployments.ts +210 -17
- package/src/routes/eval-comparison.ts +81 -2
- package/src/routes/eval-overrides.ts +108 -0
- package/src/routes/eval-runs.ts +89 -6
- package/src/routes/eval-suites.ts +32 -2
- 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 +160 -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 +142 -3
- package/src/routes/public-run-tokens.ts +3 -0
- package/src/routes/readable-projects.ts +66 -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
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* An agent candidate's `overrides`, checked when the comparison starts:
|
|
6
|
+
* each settings block must be one the version pins, its values satisfying
|
|
7
|
+
* the schema of the version it pins (model settings, for the
|
|
8
|
+
* model-settings block); a prompt template must be for the prompt block
|
|
9
|
+
* the version pins, and pass `checkDraftedTemplate` (it reads and names
|
|
10
|
+
* only what the agent has). Checked once, here, before any run exists:
|
|
11
|
+
* the replays use them as given, on resume too.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
type AgentId,
|
|
16
|
+
MODEL_SETTINGS_SCHEMA,
|
|
17
|
+
checkDraftedTemplate,
|
|
18
|
+
settingsSchemaIssues,
|
|
19
|
+
} from '@kindgi/agents';
|
|
20
|
+
import type { Semver, TenantId } from '@kindgi/types';
|
|
21
|
+
|
|
22
|
+
import type { AgentRegistryBinding } from '../agent-binding.js';
|
|
23
|
+
import type { BlockRegistryBinding } from '../block-binding.js';
|
|
24
|
+
import type { EvalOverrides } from '../eval-run-binding.js';
|
|
25
|
+
|
|
26
|
+
/** Where the check reads the agent version and its blocks. */
|
|
27
|
+
export interface SettingsOverridesCheck {
|
|
28
|
+
readonly agents: AgentRegistryBinding;
|
|
29
|
+
readonly blocks: BlockRegistryBinding;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface OverridesIssue {
|
|
33
|
+
readonly path: string;
|
|
34
|
+
readonly message: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** A JSON Pointer token: `~` and `/` escaped. */
|
|
38
|
+
const token = (id: string): string => id.replaceAll('~', '~0').replaceAll('/', '~1');
|
|
39
|
+
|
|
40
|
+
export async function checkSettingsOverrides(
|
|
41
|
+
check: SettingsOverridesCheck,
|
|
42
|
+
tenantId: TenantId,
|
|
43
|
+
candidate: { readonly agentId: string; readonly version: string },
|
|
44
|
+
overrides: EvalOverrides,
|
|
45
|
+
): Promise<OverridesIssue[]> {
|
|
46
|
+
const settings = overrides.settings ?? {};
|
|
47
|
+
const label = `${candidate.agentId} ${candidate.version}`;
|
|
48
|
+
const found = await check.agents.getVersion({
|
|
49
|
+
tenantId,
|
|
50
|
+
agentId: candidate.agentId as AgentId,
|
|
51
|
+
version: candidate.version as Semver,
|
|
52
|
+
});
|
|
53
|
+
if (found === null) {
|
|
54
|
+
return [{ path: '/agentRef/version', message: `agent ${label} isn't registered` }];
|
|
55
|
+
}
|
|
56
|
+
if (found.pins === undefined) {
|
|
57
|
+
return [
|
|
58
|
+
{
|
|
59
|
+
path: '/overrides/settings',
|
|
60
|
+
message: `${label} was published before pins: it has no pinned settings to replace`,
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
const issues: OverridesIssue[] = [];
|
|
65
|
+
for (const [id, values] of Object.entries(settings)) {
|
|
66
|
+
const path = `/overrides/settings/${token(id)}`;
|
|
67
|
+
const version = found.pins.settings[id];
|
|
68
|
+
if (version === undefined) {
|
|
69
|
+
issues.push({ path, message: `${label} doesn't pin settings block "${id}"` });
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const block = await check.blocks.getVersion({ tenantId, blockId: id, version });
|
|
73
|
+
if (block === null || block.kind !== 'settings') {
|
|
74
|
+
issues.push({ path, message: `settings block "${id}" version ${version} isn't published` });
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const schema = found.modelSettings?.id === id ? MODEL_SETTINGS_SCHEMA : block.content.schema;
|
|
78
|
+
if (schema === undefined) continue;
|
|
79
|
+
for (const issue of settingsSchemaIssues(values, schema)) {
|
|
80
|
+
issues.push({ path: `${path}${issue.path}`, message: issue.message });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (const [id, { template }] of Object.entries(overrides.prompts ?? {})) {
|
|
84
|
+
const path = `/overrides/prompts/${token(id)}`;
|
|
85
|
+
const version = found.pins.prompts[id];
|
|
86
|
+
if (version === undefined) {
|
|
87
|
+
issues.push({ path, message: `${label} doesn't pin prompt block "${id}"` });
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const block = await check.blocks.getVersion({ tenantId, blockId: id, version });
|
|
91
|
+
if (block === null || block.kind !== 'prompt') {
|
|
92
|
+
issues.push({ path, message: `prompt block "${id}" version ${version} isn't published` });
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const drafted = checkDraftedTemplate(template, {
|
|
96
|
+
current: block.content,
|
|
97
|
+
settingsBlocks: Object.keys(found.pins.settings),
|
|
98
|
+
knownIds: [
|
|
99
|
+
candidate.agentId,
|
|
100
|
+
...Object.keys(found.pins.tools),
|
|
101
|
+
...Object.keys(found.pins.prompts),
|
|
102
|
+
...Object.keys(found.pins.settings),
|
|
103
|
+
],
|
|
104
|
+
});
|
|
105
|
+
for (const issue of drafted) issues.push({ path, message: issue.message });
|
|
106
|
+
}
|
|
107
|
+
return issues;
|
|
108
|
+
}
|
package/src/routes/eval-runs.ts
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
3
|
|
|
4
4
|
import { Hono } from 'hono';
|
|
5
|
+
import type { Context } from 'hono';
|
|
5
6
|
|
|
6
7
|
import type { AgentId } from '@kindgi/agents';
|
|
8
|
+
import { type Action, ref } from '@kindgi/authz';
|
|
7
9
|
import type { Cursor, FlowId, ProjectId, RunId, Semver, TenantId, Timestamp } from '@kindgi/types';
|
|
8
10
|
|
|
9
11
|
import { statusFor, toWireError } from '../errors.js';
|
|
@@ -18,8 +20,11 @@ import {
|
|
|
18
20
|
type FlowRef,
|
|
19
21
|
} from '../eval-run-binding.js';
|
|
20
22
|
import { VERSIONS_NEED_A_FLOW } from '../judged-dispatcher.js';
|
|
23
|
+
import type { Authorizer } from '../middleware/authorize.js';
|
|
21
24
|
import type { AppEnv } from '../types.js';
|
|
25
|
+
import { deniedBy } from './denied.js';
|
|
22
26
|
import { parseComparison } from './eval-comparison.js';
|
|
27
|
+
import { type SettingsOverridesCheck, checkSettingsOverrides } from './eval-overrides.js';
|
|
23
28
|
import { type FlowVersionsCheck, checkFlowVersions } from './eval-versions.js';
|
|
24
29
|
import { clampLimit } from './pagination.js';
|
|
25
30
|
import { parseScopeParams } from './scope-params.js';
|
|
@@ -43,6 +48,13 @@ import { formatSseFrame } from './sse.js';
|
|
|
43
48
|
* The binding chooses its underlying substrate (the in-process
|
|
44
49
|
* reference keeps runs in memory; a durable binding can back them with
|
|
45
50
|
* runs and their journal); this route only sees the surface.
|
|
51
|
+
*
|
|
52
|
+
* With an authorizer (T243 A): starting a run needs `write` on the
|
|
53
|
+
* project it lands in and `execute` on what it evaluates (the agent or
|
|
54
|
+
* flow), on top of the eval-suites router's own check on the suite. An
|
|
55
|
+
* eval run is read through its suite: `read` on the suite to list, get or
|
|
56
|
+
* follow it, `write` to cancel it. A run that isn't there is still the
|
|
57
|
+
* handler's 404.
|
|
46
58
|
*/
|
|
47
59
|
export interface EvalRunsRouters {
|
|
48
60
|
readonly start: Hono<AppEnv>;
|
|
@@ -57,10 +69,12 @@ export interface EvalRunsRouters {
|
|
|
57
69
|
export function evalRunsRouters(
|
|
58
70
|
binding: EvalRunBinding,
|
|
59
71
|
versionsCheck?: FlowVersionsCheck,
|
|
72
|
+
overridesCheck?: SettingsOverridesCheck,
|
|
73
|
+
authorizer?: Authorizer,
|
|
60
74
|
): EvalRunsRouters {
|
|
61
75
|
return {
|
|
62
|
-
start: startRouter(binding, versionsCheck),
|
|
63
|
-
readback: readbackRouter(binding),
|
|
76
|
+
start: startRouter(binding, versionsCheck, overridesCheck, authorizer),
|
|
77
|
+
readback: readbackRouter(binding, authorizer),
|
|
64
78
|
};
|
|
65
79
|
}
|
|
66
80
|
|
|
@@ -91,7 +105,42 @@ async function versionsRefusal(
|
|
|
91
105
|
};
|
|
92
106
|
}
|
|
93
107
|
|
|
94
|
-
|
|
108
|
+
/** The `validation-failed` error for an agent candidate's settings `overrides` that don't fit it; `undefined` when they do. */
|
|
109
|
+
async function overridesRefusal(
|
|
110
|
+
check: SettingsOverridesCheck | undefined,
|
|
111
|
+
tenantId: TenantId,
|
|
112
|
+
start: ParsedStartBody,
|
|
113
|
+
) {
|
|
114
|
+
const overrides = start.comparison?.overrides;
|
|
115
|
+
const agentRef = start.agentRef;
|
|
116
|
+
if (overrides === undefined || agentRef?.version === undefined) return undefined;
|
|
117
|
+
if (check === undefined) {
|
|
118
|
+
return {
|
|
119
|
+
code: 'validation-failed' as const,
|
|
120
|
+
message: "This runtime can't check overrides (it serves no agent or block registry).",
|
|
121
|
+
issues: [],
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const issues = await checkSettingsOverrides(
|
|
125
|
+
check,
|
|
126
|
+
tenantId,
|
|
127
|
+
{ agentId: agentRef.agentId as unknown as string, version: agentRef.version },
|
|
128
|
+
overrides,
|
|
129
|
+
);
|
|
130
|
+
if (issues.length === 0) return undefined;
|
|
131
|
+
return {
|
|
132
|
+
code: 'validation-failed' as const,
|
|
133
|
+
message: `The overrides don't fit ${agentRef.agentId as unknown as string} ${agentRef.version} (${issues.length} issue${issues.length === 1 ? '' : 's'})`,
|
|
134
|
+
issues: issues as unknown as Record<string, unknown>[],
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function startRouter(
|
|
139
|
+
binding: EvalRunBinding,
|
|
140
|
+
versionsCheck?: FlowVersionsCheck,
|
|
141
|
+
overridesCheck?: SettingsOverridesCheck,
|
|
142
|
+
authorizer?: Authorizer,
|
|
143
|
+
): Hono<AppEnv> {
|
|
95
144
|
const r = new Hono<AppEnv>();
|
|
96
145
|
|
|
97
146
|
r.post('/:suiteId/runs', async (c) => {
|
|
@@ -119,7 +168,21 @@ function startRouter(binding: EvalRunBinding, versionsCheck?: FlowVersionsCheck)
|
|
|
119
168
|
c.status(statusFor(parsed.error.code) as never);
|
|
120
169
|
return c.json(toWireError(parsed.error, requestId));
|
|
121
170
|
}
|
|
122
|
-
const
|
|
171
|
+
const { projectId, agentRef, flowRef } = parsed.value;
|
|
172
|
+
const target =
|
|
173
|
+
agentRef !== undefined
|
|
174
|
+
? ref('agent', agentRef.agentId as unknown as string)
|
|
175
|
+
: ref('flow', flowRef?.flowId as unknown as string);
|
|
176
|
+
// Running the suite takes `execute` on it (an editor of its project, or
|
|
177
|
+
// an executor), whichever project the run lands in.
|
|
178
|
+
const refused =
|
|
179
|
+
(await deniedBy(authorizer, c, 'execute', ref('eval_suite', suiteId))) ??
|
|
180
|
+
(await deniedBy(authorizer, c, 'write', ref('project', projectId as unknown as string))) ??
|
|
181
|
+
(await deniedBy(authorizer, c, 'execute', target));
|
|
182
|
+
if (refused !== undefined) return refused;
|
|
183
|
+
const refusal =
|
|
184
|
+
(await versionsRefusal(versionsCheck, tenantId, parsed.value)) ??
|
|
185
|
+
(await overridesRefusal(overridesCheck, tenantId, parsed.value));
|
|
123
186
|
if (refusal !== undefined) {
|
|
124
187
|
c.status(statusFor(refusal.code) as never);
|
|
125
188
|
return c.json(toWireError(refusal, requestId));
|
|
@@ -206,8 +269,16 @@ function startRouter(binding: EvalRunBinding, versionsCheck?: FlowVersionsCheck)
|
|
|
206
269
|
|
|
207
270
|
// ---------- /v1/eval-runs/* (readback + cancel + SSE) ----------
|
|
208
271
|
|
|
209
|
-
function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
|
|
272
|
+
function readbackRouter(binding: EvalRunBinding, authorizer?: Authorizer): Hono<AppEnv> {
|
|
210
273
|
const r = new Hono<AppEnv>();
|
|
274
|
+
/** The refusal, if any, of `action` on the suite of the run named in the path. */
|
|
275
|
+
const onRunSuite = async (c: Context<AppEnv>, action: Action): Promise<Response | undefined> => {
|
|
276
|
+
if (authorizer === undefined) return undefined;
|
|
277
|
+
const tenantId = c.get('tenantId') as TenantId;
|
|
278
|
+
const run = await binding.get({ tenantId, runId: c.req.param('runId') as RunId });
|
|
279
|
+
if (run === null) return undefined;
|
|
280
|
+
return deniedBy(authorizer, c, action, ref('eval_suite', run.suiteId));
|
|
281
|
+
};
|
|
211
282
|
|
|
212
283
|
// ---------- GET / (list) ----------
|
|
213
284
|
r.get('/', async (c) => {
|
|
@@ -270,8 +341,14 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
|
|
|
270
341
|
...(scopeParsed.scope !== undefined && { scope: scopeParsed.scope }),
|
|
271
342
|
...(scopeParsed.inherit !== undefined && { inherit: scopeParsed.inherit }),
|
|
272
343
|
});
|
|
344
|
+
const visible =
|
|
345
|
+
authorizer === undefined
|
|
346
|
+
? page.data
|
|
347
|
+
: await authorizer.filterByCan(c, 'read', page.data, (run) =>
|
|
348
|
+
ref('eval_suite', run.suiteId),
|
|
349
|
+
);
|
|
273
350
|
return c.json({
|
|
274
|
-
data:
|
|
351
|
+
data: visible.map(serializeEvalRun),
|
|
275
352
|
hasMore: page.nextCursor !== undefined,
|
|
276
353
|
...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
|
|
277
354
|
});
|
|
@@ -279,6 +356,8 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
|
|
|
279
356
|
|
|
280
357
|
// ---------- GET /:runId ----------
|
|
281
358
|
r.get('/:runId', async (c) => {
|
|
359
|
+
const refused = await onRunSuite(c, 'read');
|
|
360
|
+
if (refused !== undefined) return refused;
|
|
282
361
|
const requestId = c.get('requestId');
|
|
283
362
|
const tenantId = c.get('tenantId') as TenantId;
|
|
284
363
|
const runId = c.req.param('runId') as RunId;
|
|
@@ -298,6 +377,8 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
|
|
|
298
377
|
|
|
299
378
|
// ---------- POST /:runId/cancel ----------
|
|
300
379
|
r.post('/:runId/cancel', async (c) => {
|
|
380
|
+
const refused = await onRunSuite(c, 'write');
|
|
381
|
+
if (refused !== undefined) return refused;
|
|
301
382
|
const requestId = c.get('requestId');
|
|
302
383
|
const tenantId = c.get('tenantId') as TenantId;
|
|
303
384
|
const runId = c.req.param('runId') as RunId;
|
|
@@ -340,6 +421,8 @@ function readbackRouter(binding: EvalRunBinding): Hono<AppEnv> {
|
|
|
340
421
|
|
|
341
422
|
// ---------- GET /:runId/events (SSE) ----------
|
|
342
423
|
r.get('/:runId/events', async (c) => {
|
|
424
|
+
const refused = await onRunSuite(c, 'read');
|
|
425
|
+
if (refused !== undefined) return refused;
|
|
343
426
|
const requestId = c.get('requestId');
|
|
344
427
|
const tenantId = c.get('tenantId') as TenantId;
|
|
345
428
|
const runId = c.req.param('runId') as RunId;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
3
|
|
|
4
4
|
import { Hono } from 'hono';
|
|
5
|
+
import { routePath } from 'hono/route';
|
|
5
6
|
|
|
6
7
|
import { type Principal, ref, tuplesForCreate } from '@kindgi/authz';
|
|
7
8
|
import type { Cursor, ProjectId, TenantId, UserId } from '@kindgi/types';
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
import type { Authorizer } from '../middleware/authorize.js';
|
|
17
18
|
import type { AppEnv } from '../types.js';
|
|
18
19
|
import { clampLimit } from './pagination.js';
|
|
20
|
+
import { projectMismatch } from './project-mismatch.js';
|
|
19
21
|
import { parseScopeParams } from './scope-params.js';
|
|
20
22
|
|
|
21
23
|
/**
|
|
@@ -75,8 +77,26 @@ export function evalSuitesRouter(
|
|
|
75
77
|
return mw(c, next);
|
|
76
78
|
});
|
|
77
79
|
r.use('/:suiteId/*', async (c, next) => {
|
|
78
|
-
const action = c.req.method === 'GET' ? 'read' : 'admin';
|
|
79
80
|
const suiteId = c.req.param('suiteId') ?? '';
|
|
81
|
+
// Starting a run (`POST /:suiteId/runs`, exactly) doesn't change the
|
|
82
|
+
// suite, and the start route checks it all itself: `execute` on the
|
|
83
|
+
// suite, `write` on the project and `execute` on the agent or flow.
|
|
84
|
+
const under = c.req.path.split('/').slice(routePath(c).split('/').length - 1);
|
|
85
|
+
if (c.req.method === 'POST' && under.length === 1 && under[0] === 'runs') return next();
|
|
86
|
+
const action = c.req.method === 'GET' ? 'read' : 'admin';
|
|
87
|
+
// A test set built from judgments under a suite id never registered
|
|
88
|
+
// (no head row) has no suite to check yet: the build checks `admin`
|
|
89
|
+
// on the project it names, the project the new suite belongs to. A
|
|
90
|
+
// tombstoned suite keeps its head row, so it's checked as an existing
|
|
91
|
+
// one. Anything else under a suite id, and a build under an existing
|
|
92
|
+
// suite, checks the suite.
|
|
93
|
+
if (
|
|
94
|
+
c.req.method === 'POST' &&
|
|
95
|
+
c.req.path.endsWith('/versions/from-judgments') &&
|
|
96
|
+
!(await binding.headExists({ tenantId: c.get('tenantId') as TenantId, suiteId }))
|
|
97
|
+
) {
|
|
98
|
+
return next();
|
|
99
|
+
}
|
|
80
100
|
const mw = authorizer.authorize(action, () => ref('eval_suite', suiteId));
|
|
81
101
|
return mw(c, next);
|
|
82
102
|
});
|
|
@@ -128,8 +148,15 @@ export function evalSuitesRouter(
|
|
|
128
148
|
...(scopeParsed.scope !== undefined && { scope: scopeParsed.scope }),
|
|
129
149
|
...(scopeParsed.inherit !== undefined && { inherit: scopeParsed.inherit }),
|
|
130
150
|
});
|
|
151
|
+
// Only what the caller may read (T243 A), as `GET …/:id` asks.
|
|
152
|
+
const visible =
|
|
153
|
+
authorizer === undefined
|
|
154
|
+
? page.data
|
|
155
|
+
: await authorizer.filterByCan(c, 'read', page.data, (a) =>
|
|
156
|
+
ref('eval_suite', a.id as unknown as string),
|
|
157
|
+
);
|
|
131
158
|
return c.json({
|
|
132
|
-
data:
|
|
159
|
+
data: visible.map(serializeEvalSuite),
|
|
133
160
|
hasMore: page.nextCursor !== undefined,
|
|
134
161
|
...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
|
|
135
162
|
});
|
|
@@ -318,6 +345,9 @@ export function evalSuitesRouter(
|
|
|
318
345
|
),
|
|
319
346
|
);
|
|
320
347
|
}
|
|
348
|
+
if (outcome.kind === 'project-mismatch') {
|
|
349
|
+
return projectMismatch(c, 'eval-suite', outcome.suiteId, outcome.projectId);
|
|
350
|
+
}
|
|
321
351
|
if (outcome.kind === 'project-not-found') {
|
|
322
352
|
// Caller supplied a `projectId` that does not resolve within
|
|
323
353
|
// this tenant. Distinct signal from `already-registered` so the
|
|
@@ -7,6 +7,7 @@ import type { Context } from 'hono';
|
|
|
7
7
|
import type { Cursor, TenantId, TriggerId } from '@kindgi/types';
|
|
8
8
|
|
|
9
9
|
import { statusFor, toWireError } from '../errors.js';
|
|
10
|
+
import type { Authorizer } from '../middleware/authorize.js';
|
|
10
11
|
import type {
|
|
11
12
|
EventTriggerRecord,
|
|
12
13
|
RegisterEventTriggerInput,
|
|
@@ -15,6 +16,7 @@ import type {
|
|
|
15
16
|
} from '../trigger-binding.js';
|
|
16
17
|
import type { AppEnv } from '../types.js';
|
|
17
18
|
import { clampLimit } from './pagination.js';
|
|
19
|
+
import { triggerAccess } from './trigger-access.js';
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* Event triggers — fire a flow run when a matching event arrives on
|
|
@@ -22,9 +24,16 @@ import { clampLimit } from './pagination.js';
|
|
|
22
24
|
*
|
|
23
25
|
* Seven routes, mirroring the schedules surface. This surface registers
|
|
24
26
|
* triggers; it does not publish events.
|
|
27
|
+
*
|
|
28
|
+
* With an authorizer (T243 A), the trigger's flow decides who may see or
|
|
29
|
+
* change it (`trigger-access.ts`).
|
|
25
30
|
*/
|
|
26
|
-
export function eventTriggersRouter(
|
|
31
|
+
export function eventTriggersRouter(
|
|
32
|
+
binding: TriggerRegistryBinding,
|
|
33
|
+
authorizer?: Authorizer,
|
|
34
|
+
): Hono<AppEnv> {
|
|
27
35
|
const r = new Hono<AppEnv>();
|
|
36
|
+
const access = triggerAccess(binding, 'event', authorizer);
|
|
28
37
|
|
|
29
38
|
// ---------- POST / (register) ----------
|
|
30
39
|
r.post('/', async (c) => {
|
|
@@ -37,11 +46,14 @@ export function eventTriggersRouter(binding: TriggerRegistryBinding): Hono<AppEn
|
|
|
37
46
|
|
|
38
47
|
const flowId = requireString(body, 'flowId');
|
|
39
48
|
const flowVersion = requireString(body, 'flowVersion');
|
|
40
|
-
const eventKind = requireString(body
|
|
49
|
+
const eventKind = requireString(body, 'config.eventKind');
|
|
41
50
|
if (flowId.kind === 'err') return bad(c, requestId, flowId.message);
|
|
42
51
|
if (flowVersion.kind === 'err') return bad(c, requestId, flowVersion.message);
|
|
43
52
|
if (eventKind.kind === 'err') return bad(c, requestId, eventKind.message);
|
|
44
53
|
|
|
54
|
+
const refused = await access.onRegister(c, flowId.value);
|
|
55
|
+
if (refused !== undefined) return refused;
|
|
56
|
+
|
|
45
57
|
const rawConfig = (body.config ?? {}) as Record<string, unknown>;
|
|
46
58
|
const registerInput: RegisterEventTriggerInput = {
|
|
47
59
|
kind: 'event',
|
|
@@ -84,7 +96,9 @@ export function eventTriggersRouter(binding: TriggerRegistryBinding): Hono<AppEn
|
|
|
84
96
|
...(statusFilter !== undefined && { status: statusFilter }),
|
|
85
97
|
});
|
|
86
98
|
return c.json({
|
|
87
|
-
data: page.data
|
|
99
|
+
data: (await access.visible(c, page.data as readonly EventTriggerRecord[])).map(
|
|
100
|
+
serializeEventTrigger,
|
|
101
|
+
),
|
|
88
102
|
hasMore: page.nextCursor !== undefined,
|
|
89
103
|
...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
|
|
90
104
|
});
|
|
@@ -95,6 +109,8 @@ export function eventTriggersRouter(binding: TriggerRegistryBinding): Hono<AppEn
|
|
|
95
109
|
const requestId = c.get('requestId');
|
|
96
110
|
const tenantId = c.get('tenantId') as TenantId;
|
|
97
111
|
const triggerId = c.req.param('triggerId') as TriggerId;
|
|
112
|
+
const refused = await access.onTrigger(c, triggerId, ['read']);
|
|
113
|
+
if (refused !== undefined) return refused;
|
|
98
114
|
|
|
99
115
|
const rec = await binding.get({ tenantId, triggerId });
|
|
100
116
|
if (rec === null || rec.kind !== 'event') return notFound(c, requestId, triggerId);
|
|
@@ -106,6 +122,8 @@ export function eventTriggersRouter(binding: TriggerRegistryBinding): Hono<AppEn
|
|
|
106
122
|
const requestId = c.get('requestId');
|
|
107
123
|
const tenantId = c.get('tenantId') as TenantId;
|
|
108
124
|
const triggerId = c.req.param('triggerId') as TriggerId;
|
|
125
|
+
const refused = await access.onTrigger(c, triggerId, ['write', 'execute']);
|
|
126
|
+
if (refused !== undefined) return refused;
|
|
109
127
|
|
|
110
128
|
const parsed = await parseJsonObject(c, requestId);
|
|
111
129
|
if (parsed.kind === 'err') return parsed.response;
|
|
@@ -149,6 +167,8 @@ export function eventTriggersRouter(binding: TriggerRegistryBinding): Hono<AppEn
|
|
|
149
167
|
const requestId = c.get('requestId');
|
|
150
168
|
const tenantId = c.get('tenantId') as TenantId;
|
|
151
169
|
const triggerId = c.req.param('triggerId') as TriggerId;
|
|
170
|
+
const refused = await access.onTrigger(c, triggerId, ['write']);
|
|
171
|
+
if (refused !== undefined) return refused;
|
|
152
172
|
const result = await binding.pause({ tenantId, triggerId });
|
|
153
173
|
if (result.kind === 'err') return lifecycleError(c, requestId, result.error, triggerId);
|
|
154
174
|
return c.json(serializeEventTrigger(result.value as EventTriggerRecord));
|
|
@@ -159,6 +179,8 @@ export function eventTriggersRouter(binding: TriggerRegistryBinding): Hono<AppEn
|
|
|
159
179
|
const requestId = c.get('requestId');
|
|
160
180
|
const tenantId = c.get('tenantId') as TenantId;
|
|
161
181
|
const triggerId = c.req.param('triggerId') as TriggerId;
|
|
182
|
+
const refused = await access.onTrigger(c, triggerId, ['write']);
|
|
183
|
+
if (refused !== undefined) return refused;
|
|
162
184
|
const result = await binding.resume({ tenantId, triggerId });
|
|
163
185
|
if (result.kind === 'err') return lifecycleError(c, requestId, result.error, triggerId);
|
|
164
186
|
return c.json(serializeEventTrigger(result.value as EventTriggerRecord));
|
|
@@ -168,6 +190,8 @@ export function eventTriggersRouter(binding: TriggerRegistryBinding): Hono<AppEn
|
|
|
168
190
|
r.post('/:triggerId/unregister', async (c) => {
|
|
169
191
|
const tenantId = c.get('tenantId') as TenantId;
|
|
170
192
|
const triggerId = c.req.param('triggerId') as TriggerId;
|
|
193
|
+
const refused = await access.onTrigger(c, triggerId, ['write']);
|
|
194
|
+
if (refused !== undefined) return refused;
|
|
171
195
|
const outcome = await binding.unregister({ tenantId, triggerId });
|
|
172
196
|
return c.json({
|
|
173
197
|
eventTriggerId: triggerId as unknown as string,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
|
|
4
|
+
import { Hono } from 'hono';
|
|
5
|
+
|
|
6
|
+
import type { ExportSigningBinding } from '@kindgi/crypto';
|
|
7
|
+
|
|
8
|
+
import type { AppEnv } from '../types.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* `GET /v1/export-signing-keys`: the public keys this deployment signs
|
|
12
|
+
* its exports with, active first. A verifier pins them: an export's own
|
|
13
|
+
* embedded `publicKey` only proves it wasn't changed, these say who
|
|
14
|
+
* signed it. Empty when the deployment doesn't sign exports. Any
|
|
15
|
+
* authenticated caller may read them; they're public keys.
|
|
16
|
+
*/
|
|
17
|
+
export function exportSigningKeysRouter(signer: ExportSigningBinding | undefined): Hono<AppEnv> {
|
|
18
|
+
const r = new Hono<AppEnv>();
|
|
19
|
+
r.get('/', (c) =>
|
|
20
|
+
c.json({
|
|
21
|
+
data: (signer?.listKeys() ?? []).map((key, index) => ({
|
|
22
|
+
keyId: key.keyId,
|
|
23
|
+
algorithm: key.algorithm,
|
|
24
|
+
publicKeyPem: key.publicKeyPem,
|
|
25
|
+
fingerprint: key.fingerprint,
|
|
26
|
+
active: index === 0,
|
|
27
|
+
})),
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
return r;
|
|
31
|
+
}
|
package/src/routes/flows.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { refuseWritesWhenReadOnly } from '../registry-read-only.js';
|
|
|
18
18
|
import type { ToolRegistryBinding } from '../tool-binding.js';
|
|
19
19
|
import type { AppEnv } from '../types.js';
|
|
20
20
|
import { clampLimit } from './pagination.js';
|
|
21
|
+
import { projectMismatch } from './project-mismatch.js';
|
|
21
22
|
import { parseScopeParams } from './scope-params.js';
|
|
22
23
|
|
|
23
24
|
/**
|
|
@@ -132,8 +133,15 @@ export function flowsRouter(
|
|
|
132
133
|
...(scopeParsed.scope !== undefined && { scope: scopeParsed.scope }),
|
|
133
134
|
...(scopeParsed.inherit !== undefined && { inherit: scopeParsed.inherit }),
|
|
134
135
|
});
|
|
136
|
+
// Only what the caller may read (T243 A), as `GET …/:id` asks.
|
|
137
|
+
const visible =
|
|
138
|
+
authorizer === undefined
|
|
139
|
+
? page.data
|
|
140
|
+
: await authorizer.filterByCan(c, 'read', page.data, (a) =>
|
|
141
|
+
ref('flow', a.id as unknown as string),
|
|
142
|
+
);
|
|
135
143
|
return c.json({
|
|
136
|
-
data:
|
|
144
|
+
data: visible.map(serializeGraph),
|
|
137
145
|
hasMore: page.nextCursor !== undefined,
|
|
138
146
|
...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
|
|
139
147
|
});
|
|
@@ -334,6 +342,9 @@ export function flowsRouter(
|
|
|
334
342
|
),
|
|
335
343
|
);
|
|
336
344
|
}
|
|
345
|
+
if (outcome.kind === 'project-mismatch') {
|
|
346
|
+
return projectMismatch(c, 'flow', outcome.flowId as unknown as string, outcome.projectId);
|
|
347
|
+
}
|
|
337
348
|
if (outcome.kind === 'project-not-found') {
|
|
338
349
|
// Caller supplied a `projectId` that does not resolve within
|
|
339
350
|
// this tenant. Distinct signal from `already-registered` so the
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { type Context, Hono } from 'hono';
|
|
5
5
|
|
|
6
6
|
import { ref } from '@kindgi/authz';
|
|
7
|
-
import type { Cursor, TenantId } from '@kindgi/types';
|
|
7
|
+
import type { Cursor, LiveScope, TenantId } from '@kindgi/types';
|
|
8
8
|
|
|
9
9
|
import { statusFor, toWireError } from '../errors.js';
|
|
10
10
|
import type { GatePolicyBinding, GatePolicyError } from '../gate-policy-binding.js';
|
|
@@ -30,7 +30,10 @@ const ID_RE = /^[a-z0-9][a-z0-9._-]{0,127}$/;
|
|
|
30
30
|
* POST /:policyId/versions/:version/unregister|reinstate
|
|
31
31
|
*
|
|
32
32
|
* Writes need `admin` on the tenant: whoever may promote mustn't be able
|
|
33
|
-
* to loosen the gate on their own promotion.
|
|
33
|
+
* to loosen the gate on their own promotion. Reads need `read` on the
|
|
34
|
+
* policy's scope (a segment's: its project), as judge classes do: one the
|
|
35
|
+
* caller can't read answers 404, as if it weren't there, and the list
|
|
36
|
+
* shows only those they can.
|
|
34
37
|
*/
|
|
35
38
|
export function gatePoliciesRouter(
|
|
36
39
|
binding: GatePolicyBinding,
|
|
@@ -46,6 +49,11 @@ export function gatePoliciesRouter(
|
|
|
46
49
|
});
|
|
47
50
|
}
|
|
48
51
|
|
|
52
|
+
/** Whether the caller may read a policy: `read` on its scope. */
|
|
53
|
+
const canRead = async (c: Ctx, policy: { readonly scope: LiveScope }): Promise<boolean> =>
|
|
54
|
+
authorizer === undefined ||
|
|
55
|
+
authorizer.can(c, 'read', scopeRef(c.get('tenantId') as TenantId, policy.scope));
|
|
56
|
+
|
|
49
57
|
r.get('/', async (c) => {
|
|
50
58
|
const requestId = c.get('requestId');
|
|
51
59
|
const scope = scopeFromQuery((n) => c.req.query(n), c.req.queries('segment') ?? []);
|
|
@@ -59,8 +67,14 @@ export function gatePoliciesRouter(
|
|
|
59
67
|
...(scope.scope !== undefined && { scope: scope.scope }),
|
|
60
68
|
...(cursor !== undefined && cursor.length > 0 && { cursor: cursor as Cursor }),
|
|
61
69
|
});
|
|
70
|
+
const visible =
|
|
71
|
+
authorizer === undefined
|
|
72
|
+
? page.data
|
|
73
|
+
: await authorizer.filterByCan(c, 'read', page.data, (p) =>
|
|
74
|
+
scopeRef(c.get('tenantId') as TenantId, p.scope),
|
|
75
|
+
);
|
|
62
76
|
return c.json({
|
|
63
|
-
data:
|
|
77
|
+
data: visible.map(serializeGatePolicy),
|
|
64
78
|
hasMore: page.nextCursor !== undefined,
|
|
65
79
|
...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
|
|
66
80
|
});
|
|
@@ -71,7 +85,7 @@ export function gatePoliciesRouter(
|
|
|
71
85
|
tenantId: c.get('tenantId') as TenantId,
|
|
72
86
|
id: c.req.param('policyId'),
|
|
73
87
|
});
|
|
74
|
-
if (found === null) return notFound(c, c.req.param('policyId'));
|
|
88
|
+
if (found === null || !(await canRead(c, found))) return notFound(c, c.req.param('policyId'));
|
|
75
89
|
return c.json(serializeGatePolicy(found));
|
|
76
90
|
});
|
|
77
91
|
|
|
@@ -80,7 +94,11 @@ export function gatePoliciesRouter(
|
|
|
80
94
|
tenantId: c.get('tenantId') as TenantId,
|
|
81
95
|
id: c.req.param('policyId'),
|
|
82
96
|
});
|
|
83
|
-
|
|
97
|
+
// A policy's versions share its scope (`gate-policy-scope-changed`).
|
|
98
|
+
const first = versions[0];
|
|
99
|
+
if (first === undefined || !(await canRead(c, first))) {
|
|
100
|
+
return notFound(c, c.req.param('policyId'));
|
|
101
|
+
}
|
|
84
102
|
return c.json({ data: versions.map(serializeGatePolicy), hasMore: false });
|
|
85
103
|
});
|
|
86
104
|
|
|
@@ -90,7 +108,7 @@ export function gatePoliciesRouter(
|
|
|
90
108
|
id: c.req.param('policyId'),
|
|
91
109
|
version: c.req.param('version'),
|
|
92
110
|
});
|
|
93
|
-
if (found === null) {
|
|
111
|
+
if (found === null || !(await canRead(c, found))) {
|
|
94
112
|
return notFound(c, c.req.param('policyId'), c.req.param('version'));
|
|
95
113
|
}
|
|
96
114
|
return c.json(serializeGatePolicy(found));
|
|
@@ -144,6 +162,19 @@ export function gatePoliciesRouter(
|
|
|
144
162
|
|
|
145
163
|
type Ctx = Context<AppEnv>;
|
|
146
164
|
|
|
165
|
+
/** The resource a gate policy's scope is: what reading it needs `read` on. */
|
|
166
|
+
function scopeRef(tenantId: TenantId, scope: LiveScope) {
|
|
167
|
+
switch (scope.kind) {
|
|
168
|
+
case 'tenant':
|
|
169
|
+
return ref('tenant', tenantId as unknown as string);
|
|
170
|
+
case 'org':
|
|
171
|
+
return ref('org', scope.orgId as unknown as string);
|
|
172
|
+
case 'project':
|
|
173
|
+
case 'segment':
|
|
174
|
+
return ref('project', scope.projectId as unknown as string);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
147
178
|
function badInput(c: Ctx, requestId: string, message: string) {
|
|
148
179
|
c.status(statusFor('bad-input') as never);
|
|
149
180
|
return c.json(toWireError({ code: 'bad-input', message }, requestId));
|