@pikku/core 0.12.143 → 0.12.145
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/analytics/analytics.d.ts +14 -0
- package/dist/analytics/analytics.js +14 -0
- package/dist/analytics/analytics.types.d.ts +1 -0
- package/dist/analytics/anonymous-analytics-identity.d.ts +1 -0
- package/dist/analytics/cookie-analytics-identity.d.ts +1 -0
- package/dist/analytics/mint-cookie.d.ts +1 -0
- package/dist/{wirings/channel/channel-middleware-runner.d.ts → channel-middleware-runner.d.ts} +17 -3
- package/dist/{wirings/channel/channel-middleware-runner.js → channel-middleware-runner.js} +24 -8
- package/dist/classification/data-classification.d.ts +13 -0
- package/dist/classification/secret-value.d.ts +7 -0
- package/dist/classification/secret-value.js +7 -0
- package/dist/crypto-utils.d.ts +93 -0
- package/dist/crypto-utils.js +92 -0
- package/dist/dev/hot-reload.d.ts +16 -0
- package/dist/dev/hot-reload.js +16 -1
- package/dist/dev/module-runner.js +7 -3
- package/dist/dev/reload-meta.js +1 -1
- package/dist/errors/error-handler.d.ts +9 -0
- package/dist/errors/error-handler.js +8 -0
- package/dist/errors/errors.d.ts +219 -0
- package/dist/errors/errors.js +227 -0
- package/dist/errors/serialized-error.d.ts +4 -0
- package/dist/function/abort-scope.d.ts +5 -0
- package/dist/function/function-meta.types.d.ts +20 -0
- package/dist/function/function-runner.d.ts +41 -0
- package/dist/function/function-runner.js +57 -11
- package/dist/function/functions.types.d.ts +59 -0
- package/dist/function/functions.types.js +23 -0
- package/dist/function/list.types.d.ts +4 -0
- package/dist/lifecycle.d.ts +12 -1
- package/dist/lifecycle.js +12 -1
- package/dist/middleware/addon-scope-cap.d.ts +4 -0
- package/dist/middleware/addon-scope-cap.js +7 -3
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.js +5 -13
- package/dist/middleware/auth-cookie.js +3 -3
- package/dist/middleware/middleware-factories.d.ts +17 -0
- package/dist/middleware/middleware-factories.js +17 -0
- package/dist/middleware/middleware.types.d.ts +23 -0
- package/dist/middleware/remote-auth.d.ts +15 -0
- package/dist/middleware/remote-auth.js +18 -3
- package/dist/middleware/remote-jobs-secret.js +2 -10
- package/dist/middleware-runner.d.ts +7 -0
- package/dist/middleware-runner.js +23 -7
- package/dist/permissions.d.ts +13 -0
- package/dist/permissions.js +13 -0
- package/dist/pikku-state.d.ts +49 -0
- package/dist/pikku-state.js +49 -0
- package/dist/remote.js +20 -5
- package/dist/schema.d.ts +36 -0
- package/dist/schema.js +36 -0
- package/dist/services/agent-run-state-service.d.ts +8 -0
- package/dist/services/agent-runner-service.d.ts +24 -0
- package/dist/services/agent-storage-service.d.ts +8 -0
- package/dist/services/ai-embedding-service.d.ts +4 -0
- package/dist/services/audit-service.d.ts +48 -0
- package/dist/services/audit-service.js +22 -0
- package/dist/services/content-service.d.ts +34 -0
- package/dist/services/credential-wire-service.d.ts +9 -0
- package/dist/services/credential-wire-service.js +9 -0
- package/dist/services/deployment-service.d.ts +14 -0
- package/dist/services/email-service.d.ts +20 -0
- package/dist/services/email-template.d.ts +24 -0
- package/dist/services/email-template.js +12 -0
- package/dist/services/file-scenario-run-store.d.ts +5 -0
- package/dist/services/file-scenario-run-store.js +4 -0
- package/dist/services/gateway-service.d.ts +5 -0
- package/dist/services/in-memory-agent-run-state-service.d.ts +5 -0
- package/dist/services/in-memory-agent-run-state-service.js +5 -0
- package/dist/services/in-memory-lease-service.d.ts +5 -0
- package/dist/services/in-memory-lease-service.js +5 -0
- package/dist/services/in-memory-session-store.d.ts +4 -0
- package/dist/services/in-memory-session-store.js +4 -0
- package/dist/services/incoming-webhook-queue.d.ts +2 -0
- package/dist/services/incoming-webhook-queue.js +2 -0
- package/dist/services/incoming-webhook-service.d.ts +9 -1
- package/dist/services/incoming-webhook-service.js +1 -1
- package/dist/services/index.d.ts +1 -5
- package/dist/services/index.js +1 -5
- package/dist/services/jwt-service.d.ts +8 -0
- package/dist/services/lease-service.d.ts +5 -0
- package/dist/services/lease-service.js +1 -0
- package/dist/services/local-content-request-handler.d.ts +20 -0
- package/dist/services/local-content-request-handler.js +11 -0
- package/dist/services/local-content.d.ts +45 -0
- package/dist/services/local-content.js +35 -0
- package/dist/services/local-credential-service.d.ts +5 -0
- package/dist/services/local-credential-service.js +5 -0
- package/dist/services/local-email-service.d.ts +7 -0
- package/dist/services/local-email-service.js +7 -0
- package/dist/services/local-secrets.d.ts +8 -0
- package/dist/services/local-secrets.js +8 -0
- package/dist/services/local-variables.d.ts +6 -0
- package/dist/services/local-variables.js +6 -0
- package/dist/services/logger.d.ts +4 -0
- package/dist/services/logger.js +4 -0
- package/dist/services/meta-service.d.ts +38 -0
- package/dist/services/meta-service.js +6 -0
- package/dist/services/queue-webhook-service.d.ts +19 -0
- package/dist/services/queue-webhook-service.js +19 -0
- package/dist/services/remote-jobs.d.ts +8 -13
- package/dist/services/remote-jobs.js +3 -54
- package/dist/services/scenario-cookie-jar.d.ts +4 -0
- package/dist/services/scheduler-service.d.ts +13 -0
- package/dist/services/scheduler-service.js +8 -0
- package/dist/services/schema-service.d.ts +9 -0
- package/dist/services/scope-service.d.ts +10 -0
- package/dist/services/scoped-secret-service.d.ts +5 -0
- package/dist/services/scoped-secret-service.js +5 -0
- package/dist/services/secret-host-binding.d.ts +5 -0
- package/dist/services/secret-host-binding.js +5 -0
- package/dist/services/secret-service.d.ts +19 -1
- package/dist/services/secretless.d.ts +6 -0
- package/dist/services/secretless.js +6 -0
- package/dist/services/session-store.d.ts +5 -0
- package/dist/services/stub-tracker.d.ts +1 -0
- package/dist/services/temporary-file-service.d.ts +9 -0
- package/dist/services/temporary-file-service.js +9 -0
- package/dist/services/trigger-service.d.ts +4 -0
- package/dist/services/trigger-source-store.d.ts +13 -0
- package/dist/services/trigger-source-store.js +7 -0
- package/dist/services/typed-credential-service.d.ts +6 -0
- package/dist/services/typed-credential-service.js +5 -0
- package/dist/services/typed-secret-service.d.ts +12 -0
- package/dist/services/typed-secret-service.js +11 -0
- package/dist/services/typed-variables-service.d.ts +1 -0
- package/dist/services/user-session-service.d.ts +31 -1
- package/dist/services/user-session-service.js +29 -3
- package/dist/services/v8-coverage-service.d.ts +27 -0
- package/dist/services/v8-coverage-service.js +5 -0
- package/dist/services/variables-service.d.ts +8 -0
- package/dist/services/virtual-user-sign-in.d.ts +1 -0
- package/dist/services/virtual-user-statement.d.ts +8 -0
- package/dist/services/virtual-user-statement.js +4 -0
- package/dist/services/webhook-service.d.ts +25 -0
- package/dist/services/webhook-service.js +15 -0
- package/dist/services/workflow-service.d.ts +6 -0
- package/dist/test-utils.js +1 -1
- package/dist/testing/service-tests.d.ts +4 -0
- package/dist/time-utils.d.ts +15 -0
- package/dist/time-utils.js +14 -0
- package/dist/types/core.types.d.ts +80 -0
- package/dist/types/state.types.d.ts +4 -0
- package/dist/utils/hmac.d.ts +3 -0
- package/dist/utils/safe-fetch.d.ts +14 -0
- package/dist/utils/safe-fetch.js +13 -0
- package/dist/utils/stable-stringify.d.ts +11 -0
- package/dist/utils/stable-stringify.js +33 -0
- package/dist/utils.d.ts +28 -0
- package/dist/utils.js +22 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.js +7 -0
- package/dist/wirings/addon/define-screens.d.ts +2 -0
- package/dist/wirings/addon/remote-addon-auth.d.ts +9 -0
- package/dist/wirings/addon/remote-addon-auth.js +5 -0
- package/dist/wirings/addon/wire-addon.d.ts +4 -0
- package/dist/wirings/addon/wire-remote-addon.d.ts +1 -0
- package/dist/wirings/agent/agent-agui.d.ts +14 -5
- package/dist/wirings/agent/agent-agui.js +17 -6
- package/dist/wirings/agent/agent-helpers.d.ts +61 -1
- package/dist/wirings/agent/agent-helpers.js +62 -2
- package/dist/wirings/agent/agent-interrupt.d.ts +5 -0
- package/dist/wirings/agent/agent-output.d.ts +20 -0
- package/dist/wirings/agent/agent-output.js +69 -0
- package/dist/wirings/agent/agent-prepare.d.ts +41 -0
- package/dist/wirings/agent/agent-prepare.js +38 -2
- package/dist/wirings/agent/agent-registry.d.ts +8 -0
- package/dist/wirings/agent/agent-registry.js +10 -4
- package/dist/wirings/agent/agent-runner.d.ts +33 -0
- package/dist/wirings/agent/agent-runner.js +40 -7
- package/dist/wirings/agent/agent-stream.d.ts +30 -0
- package/dist/wirings/agent/agent-stream.js +33 -11
- package/dist/wirings/agent/agent.types.d.ts +43 -0
- package/dist/wirings/agent/voice-input.d.ts +12 -0
- package/dist/wirings/agent/voice-input.js +12 -0
- package/dist/wirings/agent/voice-output.d.ts +14 -0
- package/dist/wirings/agent/voice-output.js +10 -0
- package/dist/wirings/agent-scorer/agent-scorer-judge.js +1 -2
- package/dist/wirings/agent-scorer/agent-scorer-registry.d.ts +10 -0
- package/dist/wirings/agent-scorer/agent-scorer-registry.js +10 -0
- package/dist/wirings/agent-scorer/agent-scorer-snapshots.d.ts +1 -0
- package/dist/wirings/agent-scorer/agent-scorer-snapshots.js +1 -0
- package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +7 -0
- package/dist/wirings/channel/channel-common.js +1 -1
- package/dist/wirings/channel/channel-rpc.types.d.ts +5 -0
- package/dist/wirings/channel/channel-runner.d.ts +22 -0
- package/dist/wirings/channel/channel-runner.js +22 -0
- package/dist/wirings/channel/channel-store.d.ts +8 -0
- package/dist/wirings/channel/channel-store.js +7 -0
- package/dist/wirings/channel/channel.types.d.ts +18 -0
- package/dist/wirings/channel/define-channel-routes.d.ts +5 -0
- package/dist/wirings/channel/define-channel-routes.js +5 -0
- package/dist/wirings/channel/eventhub-service.d.ts +9 -0
- package/dist/wirings/channel/eventhub-store.d.ts +1 -0
- package/dist/wirings/channel/eventhub-store.js +1 -0
- package/dist/wirings/channel/index.d.ts +1 -1
- package/dist/wirings/channel/index.js +1 -1
- package/dist/wirings/channel/local/local-channel-handler.d.ts +1 -0
- package/dist/wirings/channel/local/local-channel-handler.js +1 -0
- package/dist/wirings/channel/local/local-channel-runner.d.ts +13 -0
- package/dist/wirings/channel/local/local-channel-runner.js +13 -0
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +1 -0
- package/dist/wirings/channel/local/local-eventhub-service.js +1 -0
- package/dist/wirings/channel/log-channels.d.ts +1 -0
- package/dist/wirings/channel/log-channels.js +1 -0
- package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +5 -0
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +5 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +32 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +31 -0
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +8 -0
- package/dist/wirings/cli/channel/cli-channel-runner.js +8 -0
- package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +1 -0
- package/dist/wirings/cli/cli-runner.d.ts +43 -0
- package/dist/wirings/cli/cli-runner.js +43 -0
- package/dist/wirings/cli/cli.types.d.ts +4 -0
- package/dist/wirings/cli/command-parser.d.ts +13 -0
- package/dist/wirings/cli/command-parser.js +16 -0
- package/dist/wirings/credential/credential-overrides.d.ts +1 -0
- package/dist/wirings/credential/credential.types.d.ts +7 -0
- package/dist/wirings/credential/validate-credential-definitions.d.ts +7 -0
- package/dist/wirings/credential/validate-credential-definitions.js +7 -0
- package/dist/wirings/flag/cached-flag-source.d.ts +1 -0
- package/dist/wirings/flag/flag.types.d.ts +3 -0
- package/dist/wirings/gateway/gateway-runner.d.ts +23 -0
- package/dist/wirings/gateway/gateway-runner.js +23 -0
- package/dist/wirings/gateway/gateway.types.d.ts +3 -0
- package/dist/wirings/gateway/local-gateway-service.d.ts +10 -0
- package/dist/{services → wirings/gateway}/local-gateway-service.js +6 -2
- package/dist/wirings/http/http-routes.d.ts +21 -0
- package/dist/wirings/http/http-routes.js +11 -0
- package/dist/wirings/http/http-runner.d.ts +71 -0
- package/dist/wirings/http/http-runner.js +73 -5
- package/dist/wirings/http/http.types.d.ts +27 -0
- package/dist/wirings/http/index.d.ts +1 -0
- package/dist/wirings/http/index.js +1 -0
- package/dist/wirings/http/log-http-routes.d.ts +1 -0
- package/dist/wirings/http/log-http-routes.js +1 -0
- package/dist/wirings/http/merge-request-data.d.ts +12 -0
- package/dist/wirings/http/merge-request-data.js +42 -0
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-request.js +3 -32
- package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-response.js +1 -0
- package/dist/wirings/http/routers/http-router.d.ts +6 -0
- package/dist/wirings/http/routers/http-router.js +6 -0
- package/dist/wirings/http/web-request.d.ts +17 -0
- package/dist/wirings/http/web-request.js +17 -0
- package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +7 -0
- package/dist/wirings/mcp/mcp-endpoint-registry.js +7 -0
- package/dist/wirings/mcp/mcp-runner.d.ts +63 -0
- package/dist/wirings/mcp/mcp-runner.js +62 -0
- package/dist/wirings/mcp/mcp.types.d.ts +12 -0
- package/dist/wirings/node/node.types.d.ts +4 -0
- package/dist/wirings/oauth2/oauth2.types.d.ts +2 -0
- package/dist/{services → wirings/queue}/in-memory-queue-service.d.ts +9 -1
- package/dist/{services → wirings/queue}/in-memory-queue-service.js +9 -1
- package/dist/wirings/queue/index.d.ts +1 -0
- package/dist/wirings/queue/index.js +1 -0
- package/dist/wirings/queue/queue-identity.js +2 -14
- package/dist/wirings/queue/queue-runner.d.ts +37 -0
- package/dist/wirings/queue/queue-runner.js +37 -0
- package/dist/wirings/queue/queue.types.d.ts +35 -0
- package/dist/wirings/queue/register-queue-helper.d.ts +12 -0
- package/dist/wirings/queue/register-queue-helper.js +11 -0
- package/dist/wirings/queue/remote-queue-job.d.ts +11 -0
- package/dist/wirings/queue/remote-queue-job.js +41 -0
- package/dist/wirings/queue/validate-worker-config.d.ts +1 -0
- package/dist/wirings/role/role.types.d.ts +3 -0
- package/dist/wirings/rpc/rpc-runner.d.ts +24 -0
- package/dist/wirings/rpc/rpc-runner.js +37 -2
- package/dist/wirings/rpc/rpc-types.d.ts +2 -0
- package/dist/wirings/scheduler/index.d.ts +1 -0
- package/dist/wirings/scheduler/index.js +1 -0
- package/dist/wirings/scheduler/log-schedulers.d.ts +1 -0
- package/dist/wirings/scheduler/log-schedulers.js +1 -0
- package/dist/wirings/scheduler/remote-scheduled-job.d.ts +11 -0
- package/dist/wirings/scheduler/remote-scheduled-job.js +20 -0
- package/dist/wirings/scheduler/scheduler-runner.d.ts +29 -0
- package/dist/wirings/scheduler/scheduler-runner.js +28 -0
- package/dist/wirings/scheduler/scheduler.types.d.ts +3 -0
- package/dist/wirings/scope/scope.types.d.ts +5 -0
- package/dist/wirings/secret/index.d.ts +2 -2
- package/dist/wirings/secret/index.js +1 -1
- package/dist/wirings/secret/secret.types.d.ts +26 -1
- package/dist/wirings/secret/secret.types.js +1 -0
- package/dist/wirings/secret/validate-secret-definitions.d.ts +8 -0
- package/dist/wirings/secret/validate-secret-definitions.js +15 -0
- package/dist/wirings/trigger/in-memory-trigger-service.d.ts +11 -0
- package/dist/{services → wirings/trigger}/in-memory-trigger-service.js +10 -3
- package/dist/wirings/trigger/index.d.ts +1 -1
- package/dist/wirings/trigger/pikku-trigger-service.d.ts +8 -3
- package/dist/wirings/trigger/pikku-trigger-service.js +14 -3
- package/dist/wirings/trigger/trigger-runner.d.ts +27 -2
- package/dist/wirings/trigger/trigger-runner.js +35 -2
- package/dist/wirings/trigger/trigger.types.d.ts +26 -4
- package/dist/wirings/trigger/webhook-source-runner.d.ts +24 -0
- package/dist/wirings/trigger/webhook-source-runner.js +19 -0
- package/dist/wirings/trigger/webhook-source.types.d.ts +12 -2
- package/dist/wirings/trigger/webhook-source.types.js +1 -1
- package/dist/wirings/variable/validate-variable-definitions.d.ts +7 -0
- package/dist/wirings/variable/validate-variable-definitions.js +7 -0
- package/dist/wirings/variable/variable.types.d.ts +7 -0
- package/dist/wirings/virtual-user/conversation/conversation.types.d.ts +5 -0
- package/dist/wirings/virtual-user/conversation/run-conversation.d.ts +6 -0
- package/dist/wirings/virtual-user/conversation/run-conversation.js +1 -1
- package/dist/{services → wirings/virtual-user}/http-virtual-users.d.ts +4 -3
- package/dist/{services → wirings/virtual-user}/http-virtual-users.js +6 -6
- package/dist/wirings/virtual-user/index.d.ts +1 -1
- package/dist/wirings/virtual-user/index.js +1 -1
- package/dist/wirings/virtual-user/run-virtual-user.d.ts +2 -1
- package/dist/wirings/virtual-user/run-virtual-user.js +1 -14
- package/dist/wirings/virtual-user/virtual-user-declaration.types.d.ts +4 -0
- package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +10 -1
- package/dist/wirings/virtual-user/virtual-user-scaffold.js +5 -0
- package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +5 -0
- package/dist/wirings/virtual-user/virtual-user-schedule.js +1 -0
- package/dist/wirings/virtual-user/virtual-user-target.d.ts +1 -0
- package/dist/wirings/webhook/define-outgoing-webhook.d.ts +20 -0
- package/dist/wirings/webhook/define-outgoing-webhook.js +9 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +8 -4
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +7 -0
- package/dist/wirings/workflow/dsl/workflow-runner.js +7 -0
- package/dist/wirings/workflow/feature.d.ts +12 -0
- package/dist/wirings/workflow/feature.js +12 -0
- package/dist/wirings/workflow/graph/graph-node.d.ts +5 -0
- package/dist/wirings/workflow/graph/graph-node.js +5 -0
- package/dist/wirings/workflow/graph/template.d.ts +6 -0
- package/dist/wirings/workflow/graph/template.js +5 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +12 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.js +10 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +11 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.js +1 -0
- package/dist/{services → wirings/workflow}/in-memory-workflow-service.d.ts +8 -3
- package/dist/{services → wirings/workflow}/in-memory-workflow-service.js +9 -4
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +1 -1
- package/dist/wirings/workflow/pikku-scenario-service.js +2 -2
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +1 -0
- package/dist/wirings/workflow/pikku-workflow-service.js +1 -0
- package/dist/wirings/workflow/run-timeline.d.ts +21 -0
- package/dist/wirings/workflow/run-timeline.js +15 -7
- package/dist/wirings/workflow/scenario-coverage.d.ts +1 -0
- package/dist/wirings/workflow/scenario-poll.d.ts +1 -0
- package/dist/wirings/workflow/scenario-prose.d.ts +6 -0
- package/dist/wirings/workflow/scenario-prose.js +6 -0
- package/dist/wirings/workflow/scenario-run.types.d.ts +3 -0
- package/dist/wirings/workflow/scenario-step.types.d.ts +1 -0
- package/dist/wirings/workflow/scenario-step.types.js +1 -0
- package/dist/wirings/workflow/scenario-surface.js +1 -13
- package/dist/wirings/workflow/scenario.types.d.ts +6 -0
- package/dist/wirings/workflow/workflow-approval-policy.d.ts +6 -0
- package/dist/wirings/workflow/workflow-approval-policy.js +6 -0
- package/dist/wirings/workflow/workflow-constants.d.ts +7 -1
- package/dist/wirings/workflow/workflow-constants.js +10 -1
- package/dist/wirings/workflow/workflow-errors.d.ts +13 -0
- package/dist/wirings/workflow/workflow-errors.js +13 -0
- package/dist/wirings/workflow/workflow-invocation-id.d.ts +4 -0
- package/dist/wirings/workflow/workflow-invocation-id.js +4 -0
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +3 -0
- package/dist/wirings/workflow/workflow-run-ownership.d.ts +1 -0
- package/dist/wirings/workflow/workflow-run-ownership.js +1 -0
- package/dist/wirings/workflow/workflow-status-stream.d.ts +1 -0
- package/dist/wirings/workflow/workflow-unwind-plan.js +2 -7
- package/dist/wirings/workflow/workflow.types.d.ts +40 -0
- package/package.json +26 -9
- package/CHANGELOG.md +0 -6978
- package/dist/services/in-memory-trigger-service.d.ts +0 -4
- package/dist/services/local-gateway-service.d.ts +0 -6
- package/dist/utils/hash.d.ts +0 -2
- package/dist/utils/hash.js +0 -23
- package/knowledge/decisions/index.md +0 -19
- package/knowledge/decisions/internals/a-credential-name-declared-twice-must-agree-on-schema-and-type.md +0 -29
- package/knowledge/decisions/internals/a-grant-can-name-a-scope-declared-without-its-addon.md +0 -29
- package/knowledge/decisions/internals/a-held-run-is-woken-later-not-retried.md +0 -28
- package/knowledge/decisions/internals/a-latency-budget-is-asserted-by-its-cause.md +0 -32
- package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-agentrunstate-too.md +0 -22
- package/knowledge/decisions/internals/a-reset-suite-makes-the-dev-seed-the-fixture.md +0 -50
- package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +0 -20
- package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +0 -21
- package/knowledge/decisions/internals/a-scheduled-task-writes-its-caller-session-before-it-runs.md +0 -22
- package/knowledge/decisions/internals/a-secret-set-in-memory-shadows-the-variable-of-the-same-name.md +0 -28
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +0 -49
- package/knowledge/decisions/internals/a-virtual-user-acts-through-invokeraw-so-a-refusal-is-data.md +0 -32
- package/knowledge/decisions/internals/a-virtual-user-cadence-is-a-row-not-a-timer.md +0 -66
- package/knowledge/decisions/internals/a-virtual-user-converse-signs-in-before-its-first-turn.md +0 -24
- package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +0 -21
- package/knowledge/decisions/internals/a-virtual-user-email-is-computed-with-the-run-id-as-a-sub-address.md +0 -34
- package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-but-it-needs-a-trigger.md +0 -65
- package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +0 -49
- package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +0 -45
- package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +0 -26
- package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +0 -32
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +0 -33
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +0 -28
- package/knowledge/decisions/internals/agent-agui-bridge-obeys-the-client-ordering-contract.md +0 -29
- package/knowledge/decisions/internals/agent-audio-chunks-carry-the-format-the-provider-returned.md +0 -20
- package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +0 -21
- package/knowledge/decisions/internals/agent-credential-suspensions-hide-the-tool-result.md +0 -26
- package/knowledge/decisions/internals/agent-delegate-and-supervise-hide-different-text.md +0 -26
- package/knowledge/decisions/internals/agent-llm-tool-arguments-have-nulls-stripped.md +0 -23
- package/knowledge/decisions/internals/agent-model-config-stays-a-single-resolution-seam.md +0 -25
- package/knowledge/decisions/internals/agent-onerror-hooks-cannot-change-the-failure.md +0 -22
- package/knowledge/decisions/internals/agent-runner-methods-must-keep-their-receiver.md +0 -22
- package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +0 -22
- package/knowledge/decisions/internals/agent-stream-persistence-is-best-effort.md +0 -27
- package/knowledge/decisions/internals/agent-sub-agents-inherit-the-parent-context-block.md +0 -26
- package/knowledge/decisions/internals/agent-tool-execute-failures-are-logged-unconditionally.md +0 -25
- package/knowledge/decisions/internals/agent-voice-input-transcribes-audio-parts-in-place.md +0 -22
- package/knowledge/decisions/internals/agent-working-memory-is-persisted-only-when-valid.md +0 -25
- package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +0 -39
- package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +0 -23
- package/knowledge/decisions/internals/an-agent-is-offered-under-its-registry-key-and-only-within-the-virtual-users-scopes.md +0 -27
- package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +0 -25
- package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +0 -22
- package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +0 -20
- package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +0 -22
- package/knowledge/decisions/internals/an-oauth2-credential-implies-an-optional-app-secret.md +0 -26
- package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +0 -66
- package/knowledge/decisions/internals/analytics-identity-resolvers-run-in-declared-order.md +0 -22
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +0 -30
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +0 -31
- package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +0 -33
- package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +0 -29
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +0 -28
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +0 -27
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +0 -28
- package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +0 -34
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +0 -29
- package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +0 -84
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +0 -41
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +0 -44
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +0 -39
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +0 -42
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +0 -39
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +0 -43
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +0 -38
- package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +0 -44
- package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +0 -27
- package/knowledge/decisions/internals/feature-flag-declarations-refuse-an-empty-anyof-and-conflicting-scopes.md +0 -22
- package/knowledge/decisions/internals/feature-flags-fail-open-and-never-enforce-access.md +0 -28
- package/knowledge/decisions/internals/flag-sync-rewrites-only-the-declared-text.md +0 -24
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +0 -32
- package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +0 -43
- package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +0 -28
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +0 -31
- package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +0 -26
- package/knowledge/decisions/internals/global-middleware-resolves-from-the-root-namespace-too.md +0 -32
- package/knowledge/decisions/internals/hot-reload-reads-the-changed-source-never-a-compiled-copy.md +0 -38
- package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +0 -26
- package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +0 -32
- package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +0 -28
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +0 -30
- package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +0 -26
- package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +0 -28
- package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +0 -32
- package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +0 -26
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +0 -25
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +0 -26
- package/knowledge/decisions/internals/index.md +0 -182
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +0 -25
- package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +0 -26
- package/knowledge/decisions/internals/mcp-wire-names-are-assigned-over-the-whole-registry.md +0 -39
- package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +0 -24
- package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +0 -53
- package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +0 -21
- package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +0 -28
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +0 -27
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +0 -31
- package/knowledge/decisions/internals/role-names-cannot-contain-the-scope-separator.md +0 -30
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +0 -32
- package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +0 -31
- package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +0 -24
- package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +0 -26
- package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +0 -27
- package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +0 -48
- package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +0 -30
- package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +0 -28
- package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +0 -34
- package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +0 -24
- package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +0 -26
- package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +0 -43
- package/knowledge/decisions/internals/the-core-scope-validator-refuses-separator-wildcard-and-empty-segments.md +0 -22
- package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +0 -30
- package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +0 -83
- package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +0 -29
- package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +0 -27
- package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +0 -40
- package/knowledge/decisions/internals/the-mcp-handshake-is-challenged-only-when-every-target-is-gated.md +0 -29
- package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +0 -40
- package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +0 -40
- package/knowledge/decisions/internals/the-pikku-user-id-resolves-in-a-fixed-order.md +0 -24
- package/knowledge/decisions/internals/the-runner-resolves-wire-services-itself.md +0 -31
- package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +0 -26
- package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +0 -25
- package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +0 -21
- package/knowledge/decisions/internals/the-virtual-user-prompt-says-json-because-of-json-object-mode.md +0 -22
- package/knowledge/decisions/internals/the-virtual-user-runtime-is-exported-from-the-virtual-user-entry-point.md +0 -28
- package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +0 -22
- package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +0 -25
- package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +0 -33
- package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +0 -26
- package/knowledge/decisions/internals/validate-checks-virtual-users-through-a-shared-module.md +0 -43
- package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +0 -115
- package/knowledge/decisions/internals/virtual-user-conversation-drives-the-target-through-a-transport-seam.md +0 -24
- package/knowledge/decisions/internals/virtual-user-conversation-verdicts-are-llm-self-evaluations.md +0 -25
- package/knowledge/decisions/internals/virtual-user-conversations-seed-a-hidden-kickoff-message.md +0 -23
- package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +0 -21
- package/knowledge/decisions/internals/virtual-users-are-declared-in-one-definevirtualusers-call-per-codebase.md +0 -30
- package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +0 -24
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +0 -26
- package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +0 -25
- package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +0 -58
- package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +0 -35
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +0 -34
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +0 -42
- package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +0 -38
- package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +0 -29
- package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +0 -42
- package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +0 -25
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +0 -29
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +0 -43
- package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +0 -29
- package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +0 -42
- package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +0 -33
- package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +0 -32
- package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +0 -31
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +0 -39
- package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +0 -29
- package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +0 -33
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +0 -37
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +0 -54
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +0 -43
- package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +0 -32
- package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +0 -18
- package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +0 -34
- package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +0 -29
- package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +0 -33
- package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +0 -34
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +0 -34
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +0 -38
- package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +0 -30
- package/knowledge/decisions/security/a-bearer-token-checked-against-a-secret-reads-it-per-request.md +0 -26
- package/knowledge/decisions/security/a-call-without-a-session-raises-missing-session-not-forbidden.md +0 -20
- package/knowledge/decisions/security/a-caller-cookie-wins-over-the-jar-for-the-same-name.md +0 -23
- package/knowledge/decisions/security/a-channel-lifecycle-acts-as-the-socket-upgrade-session.md +0 -16
- package/knowledge/decisions/security/a-channel-requires-a-session-unless-it-says-auth-false.md +0 -26
- package/knowledge/decisions/security/a-credential-read-path-follows-its-declared-type-not-absence.md +0 -32
- package/knowledge/decisions/security/a-credential-type-is-a-literal-the-inspector-checks-at-declaration.md +0 -27
- package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +0 -28
- package/knowledge/decisions/security/a-first-party-cookie-is-written-only-after-its-purposes-consent.md +0 -33
- package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +0 -37
- package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +0 -33
- package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +0 -33
- package/knowledge/decisions/security/a-public-function-says-so-with-auth-false.md +0 -34
- package/knowledge/decisions/security/a-readonly-session-reaches-only-readonly-functions.md +0 -25
- package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +0 -52
- package/knowledge/decisions/security/a-scheduled-virtual-user-run-needs-no-admin-at-run-time.md +0 -27
- package/knowledge/decisions/security/a-scoped-credential-view-is-limited-to-declared-names.md +0 -26
- package/knowledge/decisions/security/a-scoped-secret-view-reads-only-declared-keys-and-never-writes.md +0 -25
- package/knowledge/decisions/security/a-secret-is-sent-only-to-the-hosts-it-declares.md +0 -29
- package/knowledge/decisions/security/a-step-can-name-an-identity-no-virtual-user-holds-through-per-call-headers.md +0 -25
- package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +0 -37
- package/knowledge/decisions/security/a-stopped-run-by-id-skips-the-ownership-check.md +0 -24
- package/knowledge/decisions/security/a-vault-secret-redacts-on-serialization-and-throws-on-coercion.md +0 -29
- package/knowledge/decisions/security/a-virtual-user-catalogue-entry-is-filtered-by-scope-and-approval-is-denied-by-default.md +0 -30
- package/knowledge/decisions/security/a-virtual-user-environment-fails-closed.md +0 -38
- package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +0 -27
- package/knowledge/decisions/security/a-virtual-user-never-runs-against-production.md +0 -23
- package/knowledge/decisions/security/a-virtual-user-reads-its-roles-from-the-apps-own-rpc-before-better-auth.md +0 -27
- package/knowledge/decisions/security/a-virtual-user-run-treats-an-unresolved-environment-as-production.md +0 -41
- package/knowledge/decisions/security/a-virtual-user-scopes-are-expanded-from-its-roles-once-at-run-preparation.md +0 -25
- package/knowledge/decisions/security/a-virtual-user-whose-roles-drift-from-the-declaration-refuses-to-run.md +0 -32
- package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +0 -50
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +0 -43
- package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +0 -52
- package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +0 -46
- package/knowledge/decisions/security/addon-screen-scopes-hide-and-do-not-enforce.md +0 -20
- package/knowledge/decisions/security/agent-approval-forwarding-requires-a-symbol-brand.md +0 -27
- package/knowledge/decisions/security/agent-credential-requests-are-symbol-branded.md +0 -37
- package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +0 -31
- package/knowledge/decisions/security/agent-ownership-failures-never-echo-the-resource.md +0 -23
- package/knowledge/decisions/security/agent-resume-re-runs-the-authorization-gate.md +0 -22
- package/knowledge/decisions/security/agent-sessionless-deployments-have-no-thread-ownership.md +0 -39
- package/knowledge/decisions/security/agent-thread-ownership-composes-the-session-principal.md +0 -30
- package/knowledge/decisions/security/agent-tool-filtering-reads-the-live-function-config.md +0 -24
- package/knowledge/decisions/security/an-addon-header-can-only-narrow-the-session.md +0 -26
- package/knowledge/decisions/security/an-addon-instance-reads-only-the-secrets-and-credentials-it-is-named.md +0 -33
- package/knowledge/decisions/security/an-addon-may-reach-only-itself-and-the-addons-it-uses.md +0 -16
- package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +0 -33
- package/knowledge/decisions/security/an-api-key-is-jwt-decoded-into-the-session.md +0 -26
- package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +0 -59
- package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +0 -30
- package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +0 -52
- package/knowledge/decisions/security/an-external-virtual-user-caller-presents-one-signed-statement.md +0 -38
- package/knowledge/decisions/security/an-inbound-webhook-source-dispatches-only-verified-requests.md +0 -31
- package/knowledge/decisions/security/an-mcp-call-with-no-http-request-stays-anonymous.md +0 -18
- package/knowledge/decisions/security/an-mcp-refusal-is-decided-before-dispatch.md +0 -48
- package/knowledge/decisions/security/an-oauth2-credential-is-read-by-its-account-row.md +0 -40
- package/knowledge/decisions/security/an-omitted-user-id-addresses-the-platform-credential.md +0 -32
- package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +0 -24
- package/knowledge/decisions/security/analytics-identity-is-stamped-from-the-session-not-the-event.md +0 -24
- package/knowledge/decisions/security/app-access-is-a-scope-tree-synthesised-from-virtual-users.md +0 -26
- package/knowledge/decisions/security/approval-policy-decides-who-answers-a-tool-call.md +0 -27
- package/knowledge/decisions/security/auth-false-on-a-session-function-warns-and-still-requires-one.md +0 -25
- package/knowledge/decisions/security/bearer-token-hashes-are-unpeppered-sha256.md +0 -18
- package/knowledge/decisions/security/consent-is-read-from-a-cookie-and-a-recognised-denial-counts-as-refusal.md +0 -29
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +0 -84
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +0 -39
- package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +0 -37
- package/knowledge/decisions/security/cors-defaults-to-any-origin-and-refuses-the-wildcard-with-credentials.md +0 -22
- package/knowledge/decisions/security/credential-backends-share-one-conformance-suite-for-per-user-isolation.md +0 -29
- package/knowledge/decisions/security/each-stage-has-one-virtual-user-key-pair.md +0 -27
- package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +0 -41
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +0 -30
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +0 -40
- package/knowledge/decisions/security/hmac-verification-fails-closed-on-empty-inputs.md +0 -25
- package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +0 -33
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +0 -46
- package/knowledge/decisions/security/index.md +0 -135
- package/knowledge/decisions/security/local-content-refuses-private-buckets-under-the-public-segment.md +0 -21
- package/knowledge/decisions/security/mail-is-allowlisted-before-a-virtual-user-run-sees-it.md +0 -38
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +0 -27
- package/knowledge/decisions/security/mcp-resources-tools-and-prompts-take-sessionless-functions.md +0 -18
- package/knowledge/decisions/security/origin-locked-routes-match-the-origin-exactly.md +0 -22
- package/knowledge/decisions/security/oss-auth-works-without-pikku-studio-cloud.md +0 -26
- package/knowledge/decisions/security/outbound-webhooks-use-an-allowlist-when-configured.md +0 -24
- package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +0 -40
- package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +0 -31
- package/knowledge/decisions/security/pikku-carries-virtual-user-scopes-as-data-and-the-app-grants-them.md +0 -35
- package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +0 -69
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +0 -39
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +0 -34
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +0 -55
- package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +0 -30
- package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +0 -28
- package/knowledge/decisions/security/scoped-content-access-is-a-root-folder-with-longest-prefix-grants.md +0 -31
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +0 -34
- package/knowledge/decisions/security/services-without-secrets-get-a-throwing-secrets-accessor.md +0 -22
- package/knowledge/decisions/security/shared-guards-refuse-to-mutate-or-shadow-a-system-role.md +0 -34
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +0 -37
- package/knowledge/decisions/security/signed-uploads-are-verified-by-the-same-check-as-signed-reads.md +0 -26
- package/knowledge/decisions/security/system-role-scopes-must-be-declared-with-define-scope.md +0 -24
- package/knowledge/decisions/security/system-roles-are-additive-and-immutable.md +0 -16
- package/knowledge/decisions/security/the-channel-rpc-does-not-send-the-callers-session.md +0 -21
- package/knowledge/decisions/security/the-remote-jobs-inbox-fails-closed-without-a-secret.md +0 -24
- package/knowledge/decisions/security/the-remote-rpc-gate-fails-closed-and-binds-the-token-to-its-function.md +0 -34
- package/knowledge/decisions/security/the-workflow-status-stream-rechecks-ownership-on-every-poll.md +0 -16
- package/knowledge/decisions/security/two-credentials-on-one-key-must-share-a-read-mode.md +0 -29
- package/knowledge/decisions/security/verified-bearer-claims-are-pass-through-data-that-core-never-fills.md +0 -23
- package/knowledge/decisions/security/virtual-user-catalogue-excludes-the-machinery-that-runs-virtual-users.md +0 -25
- package/knowledge/decisions/security/virtual-user-conversation-missing-approval-decisions-default-to-denied.md +0 -22
- package/knowledge/decisions/security/virtual-user-run-records-are-gated-behind-a-read-scope.md +0 -18
- package/knowledge/decisions/security/virtual-user-sign-in-does-not-exist-in-production.md +0 -25
- package/knowledge/decisions/security/virtual-user-sign-in-has-one-door.md +0 -42
- package/knowledge/decisions/security/virtual-user-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +0 -29
- package/knowledge/decisions/security/virtual-user-sign-in-only-works-for-virtual-user-flagged-users.md +0 -29
- package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +0 -25
- package/knowledge/decisions/security/wire-addon-expose-selects-the-rpc-surface.md +0 -51
- package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +0 -40
- package/knowledge/decisions/security/workflow-helper-functions-are-sessionless-by-declaration.md +0 -18
- package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +0 -32
- package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-virtual-user-and-per-scenario.md +0 -32
- package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +0 -31
- package/knowledge/decisions/security/workflow-virtual-user-steps-always-use-the-real-transport.md +0 -34
- package/knowledge/decisions/security/writing-a-virtual-user-schedule-is-gated-by-its-own-scope.md +0 -18
- package/knowledge/index.md +0 -24
- package/knowledge/questions/a-bearer-jwt-with-no-identity-becomes-a-session.md +0 -24
- package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +0 -35
- package/knowledge/questions/dev-quick-login-as-impersonation.md +0 -25
- package/knowledge/questions/does-a-delayed-rpc-run-as-the-session-it-was-scheduled-with.md +0 -26
- package/knowledge/questions/does-a-user-id-with-a-colon-read-another-users-credentials.md +0 -27
- package/knowledge/questions/does-a-wirecli-command-need-a-session-by-default.md +0 -26
- package/knowledge/questions/does-an-adversarial-in-scope-success-count-as-a-finding.md +0 -26
- package/knowledge/questions/does-approve-step-need-the-run-owners-session-or-the-gates-approvers.md +0 -34
- package/knowledge/questions/does-cors-origin-true-reflect-any-origin-with-credentials.md +0 -20
- package/knowledge/questions/does-skip-user-session-do-anything-on-a-channel.md +0 -24
- package/knowledge/questions/does-the-store-session-match-the-other-two.md +0 -19
- package/knowledge/questions/index.md +0 -41
- package/knowledge/questions/is-the-agent-score-worker-reachable-without-a-session.md +0 -21
- package/knowledge/questions/live-scheduled-tests-may-write.md +0 -19
- package/knowledge/questions/provision-virtual-users-has-no-caller-in-this-repo.md +0 -23
- package/knowledge/questions/remote-secret-refuses-requests-without-a-remote-token-on-every-path.md +0 -32
- package/knowledge/questions/should-a-middleware-set-session-persist-to-the-store.md +0 -25
- package/knowledge/questions/should-a-scoped-secret-view-throw-from-has-secret-for-a-disallowed-key.md +0 -23
- package/knowledge/questions/should-a-wrong-bearer-token-be-anonymous-or-refused.md +0 -35
- package/knowledge/questions/should-an-empty-webhook-signing-secret-send-unsigned.md +0 -23
- package/knowledge/questions/should-http-virtual-user-sessions-reset-between-scenarios-in-one-run.md +0 -27
- package/knowledge/questions/should-the-cookie-jar-scope-cookies-to-the-api-origin.md +0 -26
- package/knowledge/questions/should-voice-input-fetch-audio-urls-without-a-host-allowlist.md +0 -20
- package/knowledge/questions/staging-impersonation-rules.md +0 -27
- package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +0 -44
- package/knowledge/questions/virtual-user-keys-on-cloud-stages-are-pikku-studios-to-build.md +0 -33
- package/knowledge/questions/virtual-user-statement-replay-is-per-process.md +0 -20
- package/knowledge/questions/what-an-impersonated-session-carries.md +0 -22
- package/run-tests.sh +0 -68
- package/scripts/generate-api-report.d.mts +0 -1
- package/scripts/generate-api-report.mjs +0 -96
- package/scripts/generate-api-report.mts +0 -333
- package/src/public-surface.json +0 -637
- package/src/public-surface.json.README +0 -43
- /package/dist/{function/compensation-name.d.ts → compensation-name.d.ts} +0 -0
- /package/dist/{function/compensation-name.js → compensation-name.js} +0 -0
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Scenario agent calls retry sign-in only on 401
|
|
4
|
-
description: HttpVirtualUser.sendAgent sends with whatever session the jar holds and signs in only after a 401, so a no-auth agent route never needs a sign-in; converse signs in eagerly instead
|
|
5
|
-
tags: services
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Scenario agent calls retry sign-in only on 401
|
|
9
|
-
|
|
10
|
-
`HttpVirtualUser.sendAgent` (`packages/core/src/services/http-virtual-users.ts`)
|
|
11
|
-
sends its request with whatever cookie the jar holds. Only a 401 triggers
|
|
12
|
-
`signOut()`, `login()` and a single retry. The agent calls that go through it
|
|
13
|
-
are the stream and approve paths and `postAgent`. Its sibling `invokeRaw` does
|
|
14
|
-
the opposite: it signs in eagerly before the first RPC.
|
|
15
|
-
|
|
16
|
-
`HttpVirtualUser.converse` does not rely on that path. Before its first turn it
|
|
17
|
-
calls `login()` when `signedIn` is false. The reason is in the code comment
|
|
18
|
-
there: a public agent route never returns 401, so the retry would never sign
|
|
19
|
-
the virtual user in, and a virtual user is a real account, so conversing as
|
|
20
|
-
nobody is not the intent. See
|
|
21
|
-
[a virtual user's converse signs in before its first turn](a-virtual-user-converse-signs-in-before-its-first-turn.md).
|
|
22
|
-
|
|
23
|
-
The 401 path exists because agent HTTP routes may be public; RPC routes are
|
|
24
|
-
assumed not to be. Making every agent call eager would mean a virtual user could
|
|
25
|
-
not reach a no-auth agent without a sign-in endpoint and credentials. Deferring
|
|
26
|
-
to the 401 keeps the authenticated case working (the retry succeeds with the
|
|
27
|
-
session attached) at the cost of one extra round trip the first time.
|
|
28
|
-
|
|
29
|
-
**What this rules out:** removing the 401 retry from `sendAgent` on the grounds
|
|
30
|
-
that a sign-in always happens first, and making `sendAgent` sign in up front
|
|
31
|
-
"like `invokeRaw` does" without first checking what the agent route requires.
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: `given` and `when` are sugar for each other; `then` is not
|
|
4
|
-
description: The phase decides whether a step's bindings are alternatives or witnesses, so the same step function called as `when` and as `then` runs differently
|
|
5
|
-
tags: core, workflow
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# `given` and `when` are sugar for each other; `then` is not
|
|
9
|
-
|
|
10
|
-
All three run a named `pikkuScenarioStep` as one durable step. `given` and
|
|
11
|
-
`when` differ only in the prose a reporter renders — the step behaves
|
|
12
|
-
identically either way.
|
|
13
|
-
|
|
14
|
-
`then` is a different operation. The phase is what decides how a step's surface
|
|
15
|
-
bindings are treated: for an action, the bindings are _alternatives_ and one is
|
|
16
|
-
chosen; for an assertion, they are _witnesses_ and every applicable one runs and
|
|
17
|
-
must agree. So the same step function invoked as `when` and as `then` executes a
|
|
18
|
-
different number of times against a different number of surfaces.
|
|
19
|
-
|
|
20
|
-
See `resolveScenarioSurfaces` for the resolution itself.
|
|
21
|
-
|
|
22
|
-
**What this rules out:** collapsing the three into one call with a cosmetic
|
|
23
|
-
label, or letting a caller pass the phase as data. The phase changes execution,
|
|
24
|
-
so it has to be visible at the call site.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Scenario meta lives apart from app meta but merges when read off disk
|
|
4
|
-
description: Scenarios generate into .pikku/scenarios so no app module imports them, yet MetaService folds them back into the workflow and function meta
|
|
5
|
-
tags: services
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Scenario meta lives apart from app meta but merges when read off disk
|
|
9
|
-
|
|
10
|
-
Scenario workflows and scenario steps are generated into `.pikku/scenarios/`
|
|
11
|
-
rather than alongside the app's own `workflow/` and `function/` meta. The split
|
|
12
|
-
exists at the import level: nothing app-facing should pull a scenario into a
|
|
13
|
-
production bundle.
|
|
14
|
-
|
|
15
|
-
The split does not exist at the meta level. `LocalMetaService.getWorkflowMeta`
|
|
16
|
-
reads both `workflow/meta` and `scenarios/meta`, and `getFunctionsMeta` reads
|
|
17
|
-
both `pikku-functions-meta` and `pikku-scenario-functions-meta`
|
|
18
|
-
(`packages/core/src/services/meta-service.ts`). Anything reading meta off disk —
|
|
19
|
-
the console's scenario list first among them — is entitled to see scenarios,
|
|
20
|
-
because to a meta reader they simply are workflows and functions.
|
|
21
|
-
`packages/core/src/services/meta-service.test.ts` guards this.
|
|
22
|
-
|
|
23
|
-
**What this rules out:** dropping the second read on the grounds that the app
|
|
24
|
-
never registers scenario workflows, and "tidying" the two meta directories into
|
|
25
|
-
one. The two reads are the seam: separate on disk and in the import graph,
|
|
26
|
-
merged in `MetaService`.
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Scenario steps return drained response records
|
|
4
|
-
description: A scenario step hands back ScenarioHttpResponse rather than a Response, because the body stream reads once and the return value crosses into the run record
|
|
5
|
-
tags: services
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Scenario steps return drained response records
|
|
9
|
-
|
|
10
|
-
`ScenarioHttpResponse` and `readScenarioHttpResponse`
|
|
11
|
-
(`packages/core/src/services/virtual-users-service.ts`) exist because a `fetch`
|
|
12
|
-
`Response` cannot be a scenario step's return value. A step's result is
|
|
13
|
-
serialised into the workflow run record, and a `Response` body is a stream that
|
|
14
|
-
reads exactly once — by the time anything downstream looks at it, it is either
|
|
15
|
-
consumed or unreadable.
|
|
16
|
-
|
|
17
|
-
So the response is drained at the boundary: status, `ok`, the parsed body, and
|
|
18
|
-
the raw text it was parsed from. `serialized` is kept alongside `body` so an
|
|
19
|
-
assertion can search the payload without knowing its shape, and so an error page
|
|
20
|
-
that is HTML rather than JSON still says what went wrong instead of collapsing to
|
|
21
|
-
a parse failure. `body` is `undefined` for an empty response and the raw text when
|
|
22
|
-
the payload was not JSON; its type parameter is a claim the caller makes, not one
|
|
23
|
-
the transport checked.
|
|
24
|
-
|
|
25
|
-
**What this rules out:** returning `Response` (or anything holding a stream) from
|
|
26
|
-
a scenario step or a virtual user method, and dropping `serialized` as redundant with
|
|
27
|
-
`body` — a non-JSON error body has no other route to the assertion.
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Scenarios, steps and virtual users live in files named for them, and validate errors when they do not
|
|
4
|
-
description: pikkuScenario/pikkuFeature/pikkuScenarioStep must be in *.scenario.ts, *.scenarios.ts or *.steps.ts, and defineVirtualUsers/runVirtualUser in *.virtual-user.ts or *.vu.ts — an error, because the mixing is only cheap to undo while it is one file
|
|
5
|
-
tags: cli, validate, scenarios, virtual users
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Scenarios, steps and virtual users live in files named for them, and validate errors when they do not
|
|
9
|
-
|
|
10
|
-
A `pikkuScenario` declared beside the functions it exercises reads as more of
|
|
11
|
-
the same file. The wiring, the function, and the test of the function arrive in
|
|
12
|
-
one scroll, and the scenario is the part that gets lost — you cannot tell from
|
|
13
|
-
a directory listing which files ship and which files test.
|
|
14
|
-
|
|
15
|
-
So `validate` requires the declaration to be in a file named for what it is:
|
|
16
|
-
|
|
17
|
-
| declaration | file |
|
|
18
|
-
| --------------------------------------------------- | --------------------------------- |
|
|
19
|
-
| `pikkuScenario`, `pikkuFeature` | `*.scenario.ts`, `*.scenarios.ts` |
|
|
20
|
-
| `pikkuScenarioStep` and its platform/addon variants | `*.steps.ts` (or the above) |
|
|
21
|
-
| `defineVirtualUsers`, `runVirtualUser` | `*.virtual-user.ts`, `*.vu.ts` |
|
|
22
|
-
|
|
23
|
-
Three suffixes for scenarios rather than one, because the split that matters is
|
|
24
|
-
scenarios apart from application code, not a particular spelling — `.steps.ts`
|
|
25
|
-
holds the steps, `.scenarios.ts` holds the scenarios that call them, and a
|
|
26
|
-
project that already made that split does not have to rename anything.
|
|
27
|
-
|
|
28
|
-
**Error, not warning.** The mixing is cheap to undo while it is one file and
|
|
29
|
-
expensive once it is thirty, and a warning is exactly the signal a project
|
|
30
|
-
learns to scroll past. This is the one place where the scenario checks are
|
|
31
|
-
strict: everything else `validate` says about scenarios (no virtual users declared,
|
|
32
|
-
no virtual user sign-in, no environments) is a warning, because those describe an
|
|
33
|
-
under-tested project rather than an unreadable one.
|
|
34
|
-
|
|
35
|
-
**Virtual users are the virtual-user file** because there is no `defineVirtualUsers`
|
|
36
|
-
to look for. That name was retired in favour of `defineVirtualUsers`: a virtual user
|
|
37
|
-
is derived rather than authored — the function meta becomes its catalogue, the
|
|
38
|
-
scenario meta becomes its intents, the declared virtual users become its identities.
|
|
39
|
-
The virtual user list is the only part a project writes, so it is the part that has
|
|
40
|
-
to be findable by filename.
|
|
41
|
-
|
|
42
|
-
Matching is on the call (`\bpikkuScenario\s*\(`), not the import, so an aliased
|
|
43
|
-
import cannot slip past and a mention in a comment or a string does not trip it.
|
|
44
|
-
Generated files are exempt — codegen puts things where it likes.
|
|
45
|
-
|
|
46
|
-
**What this rules out:** a scenario in a function file; a step in a wiring file;
|
|
47
|
-
virtual users in a general-purpose `virtual-users.ts`; and reporting any of these as a
|
|
48
|
-
warning that a project can carry indefinitely.
|
package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Scope roots may be co-declared by an addon and its host app
|
|
4
|
-
description: flattenScopeDefinitions dedupes ids because the same root can legitimately be declared twice, and every consumer requires one entry per scope
|
|
5
|
-
tags: services
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Scope roots may be co-declared by an addon and its host app
|
|
9
|
-
|
|
10
|
-
`flattenScopeDefinitions`
|
|
11
|
-
(`packages/core/src/wirings/scope/validate-scope-definitions.ts`) walks the
|
|
12
|
-
declared trees depth-first, emits every node including intermediate ones, and
|
|
13
|
-
then filters the result through a `seen` set. The dedupe is not defensive
|
|
14
|
-
programming.
|
|
15
|
-
|
|
16
|
-
An addon and the app hosting it may both contribute the same root — both
|
|
17
|
-
declaring an `admin` tree, say — and that is a supported arrangement, not a
|
|
18
|
-
misconfiguration. `validateAndBuildScopeDefinitionsMeta` has already established
|
|
19
|
-
that definitions sharing a name are identical, and errors naming both source
|
|
20
|
-
files if they are not, so by the time flattening runs a repeat is redundant rather
|
|
21
|
-
than conflicting. Collapsing it here is what keeps the consumers honest: codegen
|
|
22
|
-
writes these ids into an object literal keyed by id, where a duplicate key is a
|
|
23
|
-
TypeScript error, and a `ScopeService` syncs one row per scope instead of
|
|
24
|
-
re-writing the same one. `packages/core/src/wirings/scope/scope.test.ts` covers
|
|
25
|
-
the co-declaration case.
|
|
26
|
-
|
|
27
|
-
**What this rules out:** dropping the `seen` filter on the grounds that ids are
|
|
28
|
-
already unique per declaration, and turning a repeated root into a validation
|
|
29
|
-
error. The uniqueness guarantee lives here, and both codegen and scope sync
|
|
30
|
-
depend on it.
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Serverless channel disconnect must tolerate a missing channel
|
|
4
|
-
description: A failed channel lookup on disconnect returns quietly, because serverless runtimes deliver disconnect more than once
|
|
5
|
-
tags: channel
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Serverless channel disconnect must tolerate a missing channel
|
|
9
|
-
|
|
10
|
-
`runChannelDisconnect` in
|
|
11
|
-
`packages/core/src/wirings/channel/serverless/serverless-channel-runner.ts`
|
|
12
|
-
wraps `channelStore.getChannel(channelId)` in a `try`/`catch` and returns after
|
|
13
|
-
an info log when the lookup fails, before any lifecycle function runs.
|
|
14
|
-
|
|
15
|
-
Serverless runtimes do not guarantee a single disconnect delivery.
|
|
16
|
-
`serverless-offline`, worker-thread runners and retried invocations all call the
|
|
17
|
-
disconnect path more than once for the same connection, and the second call
|
|
18
|
-
arrives after `channelStore.removeChannels` has already run. There is nothing
|
|
19
|
-
left to disconnect at that point, so an error would be noise on a normal
|
|
20
|
-
shutdown — and, where the platform retries on failure, a loop. The local runner
|
|
21
|
-
does not need this because the channel object lives in-process for the whole
|
|
22
|
-
connection.
|
|
23
|
-
|
|
24
|
-
**What this rules out:** treating a missing channel as an error worth throwing or
|
|
25
|
-
logging at error level, and hoisting the `getChannel` call out of its `try` while
|
|
26
|
-
"tidying up" the early returns. It also means `onDisconnect` is best-effort, not
|
|
27
|
-
exactly-once — anything that must happen once per connection needs its own
|
|
28
|
-
idempotency, not this handler.
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: sideEffects is an allowlist, because core genuinely has some
|
|
4
|
-
description: The error registry is built by addError calls that run on import, so claiming sideEffects:false would let a bundler drop it and leave getErrorResponse unable to find any error
|
|
5
|
-
tags: core, packaging
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# `sideEffects` is an allowlist, not `false`
|
|
9
|
-
|
|
10
|
-
Without a `sideEffects` field a bundler must assume every module in the package
|
|
11
|
-
does something merely by being imported, so it cannot drop any of them. That is
|
|
12
|
-
the state core shipped in, and it costs every bundled consumer the whole package.
|
|
13
|
-
|
|
14
|
-
The reflex fix — `"sideEffects": false` — would be untrue. Five modules run code
|
|
15
|
-
at import, 59 top-level calls between them, and every one is `addError(...)`
|
|
16
|
-
registering an error class in the runtime registry:
|
|
17
|
-
|
|
18
|
-
- `errors/errors.js` (44)
|
|
19
|
-
- `wirings/workflow/pikku-scenario-service.js` (6)
|
|
20
|
-
- `wirings/workflow/workflow-errors.js` (5)
|
|
21
|
-
- `wirings/rpc/rpc-runner.js` (3)
|
|
22
|
-
- `wirings/rpc/remote-addon-auth.js` (1)
|
|
23
|
-
|
|
24
|
-
A bundler that dropped `errors/errors.js` because nothing imported a binding
|
|
25
|
-
from it would leave `getErrorResponse` unable to map any error to a status. The
|
|
26
|
-
app would build, and every error would come back as a generic 500.
|
|
27
|
-
|
|
28
|
-
So the field names those five exactly. Everything else can be tree-shaken.
|
|
29
|
-
|
|
30
|
-
**What this rules out:** flipping this to `false` as a performance change, and
|
|
31
|
-
adding a module-level `addError` (or any other registration) without adding the
|
|
32
|
-
module here. `side-effects-are-declared.test.ts` walks the source for top-level
|
|
33
|
-
calls and fails in both directions — a module with side effects missing from the
|
|
34
|
-
list, and a listed module that no longer has any.
|
package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: Speech synthesis picks a voice per sentence but announces a limitation once
|
|
4
|
-
description: A bilingual reply should speak the half it can, and repeating the notice for every sentence would bury the reply itself
|
|
5
|
-
tags: core, agent
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Speech synthesis picks a voice per sentence, and warns once per reply
|
|
9
|
-
|
|
10
|
-
`voiceOutput` checks the script of each sentence separately, but emits any
|
|
11
|
-
"cannot speak this" notice only once for the whole reply.
|
|
12
|
-
|
|
13
|
-
Per sentence is what makes the voice correct. A reply that answers in English
|
|
14
|
-
and then quotes a Chinese title is two sentences in two scripts, and each is
|
|
15
|
-
synthesized in the voice its own script needs. Checking once for the whole reply
|
|
16
|
-
would pick one voice and mispronounce the other half.
|
|
17
|
-
|
|
18
|
-
Announcing once is what keeps the reply audible. A bilingual answer should still
|
|
19
|
-
speak the part it can, and repeating the notice for every sentence of a long
|
|
20
|
-
reply buries the answer under its own caveats.
|
|
21
|
-
|
|
22
|
-
**What this rules out:** moving the script check up to the reply level to save
|
|
23
|
-
work, and moving the notice down to the sentence level for consistency with it.
|
|
24
|
-
The two belong at different granularities on purpose.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: The agent `done` event goes through the middleware and is awaited
|
|
4
|
-
description: `done` is the only end-of-reply signal a stream hook gets, and buffering hooks flush on it — sending it raw discards work already paid for
|
|
5
|
-
tags: core, agent
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# The agent `done` event goes through the middleware and is awaited
|
|
9
|
-
|
|
10
|
-
Both the first turn and the post-approval resume send their terminating `done`
|
|
11
|
-
event through the stream middleware rather than straight at the channel, and
|
|
12
|
-
await it.
|
|
13
|
-
|
|
14
|
-
`done` is the only signal a stream hook receives that the reply is over. The
|
|
15
|
-
hooks that buffer need it to flush: `voiceOutput` holds a trailing fragment that
|
|
16
|
-
never reached a full stop, and waits on audio it has already asked the provider
|
|
17
|
-
to synthesize and already been billed for. Sending `done` raw skips those hooks
|
|
18
|
-
entirely, and the `close()` immediately after throws the buffered work away.
|
|
19
|
-
|
|
20
|
-
It matters more on the resume path than the first turn. After an approval, most
|
|
21
|
-
of what gets spoken is the agent describing what it just did — so a dropped
|
|
22
|
-
flush silences the larger half of the reply.
|
|
23
|
-
|
|
24
|
-
**What this rules out:** treating the terminating event as a special case that
|
|
25
|
-
can bypass the chain because "nothing comes after it". Something does: the
|
|
26
|
-
flush.
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: The API report pins members, because the export list only pins names
|
|
4
|
-
description: public-surface.json catches an export appearing or vanishing; it cannot see a method added to an interface, which is the change that breaks a consumer's build
|
|
5
|
-
tags: core, api
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# The API report pins members, not just names
|
|
9
|
-
|
|
10
|
-
`public-surface.json` records `Object.keys(module)` for every entry point. That
|
|
11
|
-
is a real guard — it caught a new `./node-host-resolver` subpath and five
|
|
12
|
-
renames during a rebase — but it only sees _names_.
|
|
13
|
-
|
|
14
|
-
It cannot see:
|
|
15
|
-
|
|
16
|
-
- a method added to `MetaService`, which has 32 members
|
|
17
|
-
- a field on `ChannelMeta` becoming required
|
|
18
|
-
- a parameter added to a method on `PikkuWorkflowService`, which has 104
|
|
19
|
-
- any change at all to an `interface`, since types are erased before
|
|
20
|
-
`Object.keys` can enumerate them
|
|
21
|
-
|
|
22
|
-
Those are the changes that break a consumer's build, and there are far more of
|
|
23
|
-
them than there are exports — roughly two members for every name. The report's
|
|
24
|
-
own summary counts both, live, so the figure is not repeated here to rot: an
|
|
25
|
-
earlier hand-count in this note was already wrong by 40 members within a day of
|
|
26
|
-
being written.
|
|
27
|
-
|
|
28
|
-
Demonstrated rather than assumed: adding `probeAddedMember(): void` to
|
|
29
|
-
`MetaService` leaves `public-surface.test.ts` passing 3/0, and fails
|
|
30
|
-
`api-report.test.ts`.
|
|
31
|
-
|
|
32
|
-
So `api-report.md` is generated from the type checker — every exported symbol
|
|
33
|
-
with its full signature, interfaces and classes rendered as their declarations
|
|
34
|
-
so member changes land in the diff. It is committed, and the test fails when
|
|
35
|
-
the code and the report disagree. Regenerate with `yarn api-report`.
|
|
36
|
-
|
|
37
|
-
**What this rules out:** treating `public-surface.json` as the API guard. It
|
|
38
|
-
guards the front door; this guards the rooms. Both are needed, and the export
|
|
39
|
-
list is the cheaper of the two to run — which is why it stayed.
|
|
40
|
-
|
|
41
|
-
Re-exports are resolved through `getAliasedSymbol` before the signature is
|
|
42
|
-
taken. Without that, 624 of the symbols reported as `any`, which would have
|
|
43
|
-
pinned nothing while looking like it did.
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: The core scope validator refuses separator, wildcard and empty scope segments
|
|
4
|
-
description: assertSegment rejects a scope segment that contains the colon separator, equals the wildcard, or is empty
|
|
5
|
-
tags: core, scopes, validation
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# The core scope validator refuses separator, wildcard and empty scope segments
|
|
9
|
-
|
|
10
|
-
`assertSegment` in `packages/core/src/wirings/scope/validate-scope-definitions.ts:11-27`
|
|
11
|
-
checks each segment of a declared scope name in three ways.
|
|
12
|
-
|
|
13
|
-
A segment containing the `:` separator throws (`:12-17`). The message says to
|
|
14
|
-
nest scopes with the `scopes` property instead. A segment equal to `*` throws
|
|
15
|
-
(`:18-23`), because the wildcard is reserved for granting a scope and its
|
|
16
|
-
descendants. An empty segment throws (`:24-26`).
|
|
17
|
-
|
|
18
|
-
The separator and the wildcard constants are at `:8-9`. The walk that calls this
|
|
19
|
-
check is described in `scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md`.
|
|
20
|
-
|
|
21
|
-
**What this rules out:** a declared scope whose name embeds a separator, which
|
|
22
|
-
would make it match a different scope, and a declared wildcard.
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: The dev queue copies prod timing and serialization semantics
|
|
4
|
-
description: InMemoryQueueService dispatches via setTimeout, retries with backoff, and JSON round-trips every payload so dev behaviour matches a real backend
|
|
5
|
-
tags: services
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# The dev queue copies prod timing and serialization semantics
|
|
9
|
-
|
|
10
|
-
`InMemoryQueueService` (`packages/core/src/services/in-memory-queue-service.ts`)
|
|
11
|
-
is the local/dev queue, and it is deliberately less direct than it could be. It
|
|
12
|
-
schedules jobs on the macrotask queue via `setTimeout` rather than calling the
|
|
13
|
-
worker inline, it redelivers a failed job up to `options.attempts` times with
|
|
14
|
-
backoff, and it JSON round-trips every payload on the way in.
|
|
15
|
-
|
|
16
|
-
Each is there so dev does not teach a false lesson. Inline dispatch would make
|
|
17
|
-
enqueue synchronous, and code written against that ordering breaks the first time
|
|
18
|
-
it meets a real queue. Dropping a job on its first error would hide that a
|
|
19
|
-
transiently-failing workflow step recovers fine on pg-boss or BullMQ. And every
|
|
20
|
-
real backend puts the job on a wire — an SQS body, a Redis value, a `jsonb`
|
|
21
|
-
column — so the worker never receives the caller's live object; round-tripping
|
|
22
|
-
here means a payload carrying a `Date`, a class instance or a shared mutable
|
|
23
|
-
reference fails in dev rather than in production. Callers cannot know which
|
|
24
|
-
backend they are talking to, so they must not have to serialise defensively.
|
|
25
|
-
|
|
26
|
-
**What this rules out:** "optimising" the dev queue by invoking the handler
|
|
27
|
-
directly, skipping the JSON copy for speed, or short-circuiting retries. Its job
|
|
28
|
-
is fidelity, not throughput. (Separately, the detached `setTimeout` makes this
|
|
29
|
-
service unusable on Lambda or Workers, where the container freezes at response
|
|
30
|
-
time — it is a dev service by construction, not just by name.)
|
package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: One door per name — the ecosystem tier and the package root are both gone
|
|
4
|
-
description: the adapter surface was split onto @pikku/core/ecosystem to keep a stability promise at the root; publishing every module twice cost more than the promise was worth, so both the facades and the root barrel were deleted
|
|
5
|
-
tags: core, api
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# One door per name
|
|
9
|
-
|
|
10
|
-
**Reversed.** The section below records why `@pikku/core/ecosystem` existed; it
|
|
11
|
-
is kept because the stability argument that produced it is still true and still
|
|
12
|
-
constrains what the subpaths may promise. What changed is the mechanism.
|
|
13
|
-
|
|
14
|
-
## What holds now
|
|
15
|
-
|
|
16
|
-
Every name lives on the subpath that owns the module it comes from, and every
|
|
17
|
-
import carries that subpath: `@pikku/core/http`, `@pikku/core/services`,
|
|
18
|
-
`@pikku/core/errors`, `@pikku/core/types`. There is no second specifier for the
|
|
19
|
-
same module and no package root — `.` resolves to a bootstrap shim, not an entry
|
|
20
|
-
point.
|
|
21
|
-
|
|
22
|
-
The facades did not survive contact with their own premise. `ecosystem/http`
|
|
23
|
-
re-exported `./http`, so a name was reachable through either door; every
|
|
24
|
-
addition had to be made twice, they drifted (25 names had accumulated in the
|
|
25
|
-
facade tier with no raw home, and about 26 more sat under a different area than
|
|
26
|
-
the module they came from), and a consumer's import told you nothing about what
|
|
27
|
-
it used. The package root was the same failure at a larger scale: 206 names in
|
|
28
|
-
one barrel that no bundler could take apart.
|
|
29
|
-
|
|
30
|
-
The stability distinction the split was built to express is now carried by
|
|
31
|
-
`public-surface.json` and `api-report.md`, which pin what each entry point
|
|
32
|
-
exports. Moving a symbol across an area boundary is still a visible diff; it
|
|
33
|
-
just no longer requires a parallel tree of re-export files to be visible.
|
|
34
|
-
|
|
35
|
-
One module survives at an old specifier and is not an entry point:
|
|
36
|
-
`bootstrap-compat/root.ts` exists because `packages/cli` is generated by the
|
|
37
|
-
published CLI pinned in its `build.sh`, which still emits a bare `@pikku/core`.
|
|
38
|
-
The matching `bootstrap-compat/ecosystem.ts` has already gone, along with every
|
|
39
|
-
`@pikku/core/ecosystem` import in the repo — a guard test now fails if one comes
|
|
40
|
-
back. A test pins the root shim's exact contents so it cannot grow, and it goes
|
|
41
|
-
when the pin moves to a CLI released from this branch.
|
|
42
|
-
|
|
43
|
-
**What this rules out:** re-introducing any specifier that re-exports another
|
|
44
|
-
subpath's names. A curated facade over a module that is already published is the
|
|
45
|
-
thing that was tried; adding a name to two places is how it decays.
|
|
46
|
-
|
|
47
|
-
## Why the split existed (superseded)
|
|
48
|
-
|
|
49
|
-
`@pikku/core` has two kinds of consumer. An **application** writes functions and
|
|
50
|
-
wires them: `pikkuFunc`, `wireHTTP`, `PikkuWire`, the error catalogue. A
|
|
51
|
-
**runtime adapter** — the express, fastify, uWS, Next, Cloudflare and Lambda
|
|
52
|
-
packages, plus tests — reaches past that to drive the runner itself.
|
|
53
|
-
|
|
54
|
-
Those two surfaces have measurably different stability. Over the nine months
|
|
55
|
-
since `PikkuWire` was introduced, its app-facing shape took 22 additions and
|
|
56
|
-
**zero removals** — every original field is still there. Over the same period
|
|
57
|
-
`runPikkuFunc` was reshaped: `allServices`/`getAllServices` became
|
|
58
|
-
`singletonServices`/`createWireServices`, the positional arguments became a
|
|
59
|
-
`wireType`/`wireId` pair plus an options object, and `session` became `auth`.
|
|
60
|
-
|
|
61
|
-
Both were exported from the package root. A compatibility promise made there
|
|
62
|
-
would therefore have been a promise about the weaker of the two.
|
|
63
|
-
|
|
64
|
-
So the adapter surface moved to `@pikku/core/ecosystem`: `runPikkuFunc`, the
|
|
65
|
-
singleton-service accessors, and the registration calls the code generator emits
|
|
66
|
-
— `addFunction`, `addGlobalMiddleware`, `addMiddleware` — alongside `pikkuState`
|
|
67
|
-
and `httpRouter`, which were already separated for the same reason. The wire
|
|
68
|
-
runners (`runQueueJob`, `runScheduledTask`, `runCLICommand`, `runMCP*`) left the
|
|
69
|
-
root too, but for a different reason: they already lived on their wire subpaths,
|
|
70
|
-
which is where every runtime package imports them from, so the root copies were
|
|
71
|
-
redundant. 108 runtime exports became 95.
|
|
72
|
-
|
|
73
|
-
**The name took two attempts.** Not `/internal`: the generated bootstrap
|
|
74
|
-
imports from here, so the specifier appears in the user's own `.pikku`
|
|
75
|
-
directory, and telling someone they are touching internals when the code
|
|
76
|
-
generator put it there is both wrong and self-defeating — it could never be
|
|
77
|
-
broken anyway. Not `/runtime` either: that reads as runtime-versus-compile-time,
|
|
78
|
-
i.e. _the real API_, which is the opposite of the intended signal, and
|
|
79
|
-
`packages/runtimes/*` already claims the word while `packages/cli` is the
|
|
80
|
-
largest consumer here at 22 files.
|
|
81
|
-
|
|
82
|
-
`/ecosystem` said the true thing: you are building a package in the Pikku
|
|
83
|
-
ecosystem — a runtime, a service, an addon, the CLI.
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: The embedding model is pinned per service and doc/query embedding is split
|
|
4
|
-
description: AIEmbeddingService fixes its model at construction so index and query share a vector space, and separates embedDocuments from embedQuery for asymmetric models
|
|
5
|
-
tags: services
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# The embedding model is pinned per service and doc/query embedding is split
|
|
9
|
-
|
|
10
|
-
`AIEmbeddingService` (`packages/core/src/services/ai-embedding-service.ts`) is a
|
|
11
|
-
deliberately narrow interface with two properties that look like restrictions.
|
|
12
|
-
The model is `readonly` and fixed at construction rather than passed per call,
|
|
13
|
-
and documents and queries go through separate methods.
|
|
14
|
-
|
|
15
|
-
Both are about comparability. Vector stores (Qdrant, Pinecone, pgvector) embed at
|
|
16
|
-
index time and again at query time; if those two moments can name different
|
|
17
|
-
models they end up in different vector spaces, and similarity search does not
|
|
18
|
-
error — it silently returns nonsense. Pinning the model to the service makes the
|
|
19
|
-
drift unrepresentable. The split methods exist because several embedding models
|
|
20
|
-
are asymmetric and must know which side they are embedding to produce comparable
|
|
21
|
-
vectors: Cohere's `input_type`, E5's `query:` / `passage:` prefixes, BGE's query
|
|
22
|
-
instruction. Symmetric providers such as OpenAI simply point both methods at the
|
|
23
|
-
same call.
|
|
24
|
-
|
|
25
|
-
**What this rules out:** adding a per-call `model` parameter, collapsing
|
|
26
|
-
`embedDocuments` and `embedQuery` into one `embed`, and pointing a vector store
|
|
27
|
-
at `AgentRunnerService.embed` / `embedMany` instead — those take a per-call
|
|
28
|
-
model on purpose and drag in the whole agent-runner tool loop, and they give back
|
|
29
|
-
neither guarantee.
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: The in-memory workflow service is inline-only and single-process
|
|
4
|
-
description: InMemoryWorkflowService wires no queues and implements withRunLease/withStepLock as pass-throughs, because inline execution has no second holder to exclude
|
|
5
|
-
tags: services
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# The in-memory workflow service is inline-only and single-process
|
|
9
|
-
|
|
10
|
-
`InMemoryWorkflowService` (`packages/core/src/services/in-memory-workflow-service.ts`)
|
|
11
|
-
calls `super({ ...options, wireQueues: false })` and implements `withRunLease` and
|
|
12
|
-
`withStepLock` as bare `return fn()`. Both look like unfinished work and neither
|
|
13
|
-
is.
|
|
14
|
-
|
|
15
|
-
Every step runs inline in the process that started the run: there are no queue
|
|
16
|
-
workers, so no other worker can be mid-step on the same run, and all state lives
|
|
17
|
-
in this instance's `Map`s, so no other process can see it to contend for it. A
|
|
18
|
-
lock would be excluding a competitor that cannot exist. It is offered for CLI
|
|
19
|
-
tools that want step orchestration, for tests, and for single-process apps that
|
|
20
|
-
do not need persistence — and the run state is unbounded and lost on restart,
|
|
21
|
-
which is the price of that.
|
|
22
|
-
|
|
23
|
-
**What this rules out:** treating the no-op locks as a bug and adding real
|
|
24
|
-
locking here, and running this service anywhere a second process or a queue
|
|
25
|
-
worker could touch the same run. A deployment that needs either wants a
|
|
26
|
-
persistent `WorkflowService` implementation instead; there is nothing to fix in
|
|
27
|
-
this one.
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: The KEK salt is scoped to the key version, not the secret
|
|
4
|
-
description: One stored salt per key version means N secrets cost one derivation, which is the point of envelope encryption
|
|
5
|
-
tags: crypto, storage
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# The KEK salt is scoped to the key version, not the secret
|
|
9
|
-
|
|
10
|
-
Each secret and credential service stores one random salt per `keyVersion`,
|
|
11
|
-
generated on first use and read once — a `secretKekSalts` / `credentialKekSalts`
|
|
12
|
-
table for kysely, a hash field for redis, a document for mongodb. `deriveKEK`
|
|
13
|
-
runs against that salt to produce a `CryptoKey`, which is what
|
|
14
|
-
`wrapDEK`/`unwrapDEK`/`envelope*` accept. The wrapped-DEK blob therefore carries
|
|
15
|
-
no salt of its own: `[iv:12][ct+tag]`.
|
|
16
|
-
|
|
17
|
-
Envelope encryption exists so the expensive derivation happens once and many
|
|
18
|
-
cheap DEK unwraps follow. A per-secret salt destroys that: every
|
|
19
|
-
`envelopeDecrypt` re-derives, so `getSecrets` over 50 rows cost 50 × PBKDF2-600k
|
|
20
|
-
(~2.3s) and rotation cost twice that. Scoping the salt to the key version
|
|
21
|
-
restored the intended shape — one derivation for a bulk read, two for a
|
|
22
|
-
rotation.
|
|
23
|
-
|
|
24
|
-
Keying by version rather than storing a single salt is what lets `getKEK` keep
|
|
25
|
-
serving `previousKey` for older rows during rotation.
|
|
26
|
-
|
|
27
|
-
A salt's job is to defeat precomputation across deployments and passphrases; one
|
|
28
|
-
random salt per deployment per key version achieves that fully. Per-ciphertext
|
|
29
|
-
salt only buys something when each ciphertext might use a different passphrase,
|
|
30
|
-
which is never the case here. Storing the salt rather than taking it as
|
|
31
|
-
configuration keeps it off the operator's plate — it needs to be
|
|
32
|
-
deployment-random, not secret.
|
|
33
|
-
|
|
34
|
-
**What this rules out:** deriving the KEK inside a per-row loop; a salt shared
|
|
35
|
-
across key versions, which would break rotation; a deterministic salt derived
|
|
36
|
-
from the version number, which is the same salt in every deployment and so
|
|
37
|
-
restores the rainbow table; and caching derived keys anywhere but a read-through
|
|
38
|
-
instance map whose source of truth is the store.
|
|
39
|
-
|
|
40
|
-
See [[passphrases-are-stretched-key-material-is-expanded]].
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: decision
|
|
3
|
-
title: The MCP handshake is challenged only when every target is gated
|
|
4
|
-
description: A client decides whether a server speaks OAuth from the handshake alone, so a fully-gated server that answers initialize with a 200 is detected as needing no sign-in
|
|
5
|
-
tags: [mcp, auth, oauth]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# The MCP handshake is challenged only when every target is gated
|
|
9
|
-
|
|
10
|
-
`requestNeedsCredentials` challenges `initialize` when
|
|
11
|
-
`mcpEveryTargetRequiresSession()` is true, and only then.
|
|
12
|
-
|
|
13
|
-
A client decides at connection time whether a server speaks OAuth, and the only
|
|
14
|
-
thing it can decide from is whether the handshake came back `401` with a
|
|
15
|
-
`WWW-Authenticate` header naming the resource metadata. A server that answers
|
|
16
|
-
`initialize` with a `200` and then `401`s every single tool call has told the
|
|
17
|
-
client "no sign-in needed" and then refused it everything. That is how a fully
|
|
18
|
-
gated server ends up shown as open, with no way for the user to sign in — the
|
|
19
|
-
client never offers the option, because it was told there was nothing to offer.
|
|
20
|
-
|
|
21
|
-
The condition is deliberately all-or-nothing. A server with even one open target
|
|
22
|
-
genuinely is usable anonymously, and challenging its handshake would lock out
|
|
23
|
-
clients that have no credentials to offer at all. An empty registry is not "all
|
|
24
|
-
gated" either: there is nothing there to gate, so the handshake stays open.
|
|
25
|
-
|
|
26
|
-
**What this rules out:** challenging the handshake whenever _any_ target needs a
|
|
27
|
-
session. The handshake is not the place to express per-target policy — the
|
|
28
|
-
per-target `401` already does that, and a client that has been let in can act on
|
|
29
|
-
it. The handshake only answers "is there a sign-in here at all".
|