@pikku/core 0.12.71 → 0.12.74
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/CHANGELOG.md +848 -0
- package/dist/crypto-utils.d.ts +30 -5
- package/dist/crypto-utils.js +146 -41
- package/dist/dev/hot-reload.js +11 -30
- package/dist/dev/module-runner.d.ts +3 -7
- package/dist/dev/module-runner.js +4 -10
- package/dist/dev/reload-meta.d.ts +8 -20
- package/dist/dev/reload-meta.js +9 -29
- package/dist/errors/error-handler.d.ts +5 -30
- package/dist/errors/error-handler.js +16 -32
- package/dist/errors/errors.d.ts +32 -151
- package/dist/errors/errors.js +55 -157
- package/dist/function/abort-scope.d.ts +47 -0
- package/dist/function/abort-scope.js +63 -0
- package/dist/function/function-runner.js +40 -30
- package/dist/function/functions.types.d.ts +44 -136
- package/dist/function/functions.types.js +0 -58
- package/dist/function/list.types.d.ts +12 -62
- package/dist/function/list.types.js +4 -25
- package/dist/handle-error.d.ts +0 -11
- package/dist/handle-error.js +6 -18
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -1
- package/dist/middleware/auth-apikey.d.ts +3 -18
- package/dist/middleware/auth-apikey.js +0 -17
- package/dist/middleware/auth-bearer.d.ts +6 -41
- package/dist/middleware/auth-bearer.js +3 -40
- package/dist/middleware/auth-cookie.d.ts +5 -27
- package/dist/middleware/auth-cookie.js +2 -26
- package/dist/middleware/cors.d.ts +7 -34
- package/dist/middleware/cors.js +7 -34
- package/dist/middleware/remote-auth.d.ts +3 -1
- package/dist/middleware/remote-auth.js +3 -2
- package/dist/middleware/telemetry.d.ts +8 -33
- package/dist/middleware/telemetry.js +2 -31
- package/dist/middleware-runner.d.ts +4 -55
- package/dist/middleware-runner.js +5 -74
- package/dist/permissions.d.ts +3 -44
- package/dist/permissions.js +19 -71
- package/dist/pikku-request.d.ts +0 -6
- package/dist/pikku-request.js +0 -6
- package/dist/pikku-state.d.ts +0 -26
- package/dist/pikku-state.js +2 -30
- package/dist/remote.d.ts +3 -5
- package/dist/remote.js +8 -7
- package/dist/schema.d.ts +7 -17
- package/dist/schema.js +30 -18
- package/dist/scopes.d.ts +4 -23
- package/dist/scopes.js +7 -48
- package/dist/services/ai-agent-runner-service.d.ts +20 -0
- package/dist/services/ai-embedding-service.d.ts +2 -25
- package/dist/services/audit-service.js +1 -2
- package/dist/services/content-service.d.ts +1 -46
- package/dist/services/credential-service.d.ts +3 -40
- package/dist/services/deployment-service.d.ts +3 -9
- package/dist/services/gateway-service.d.ts +0 -15
- package/dist/services/http-personas.d.ts +80 -0
- package/dist/services/http-personas.js +233 -0
- package/dist/services/in-memory-queue-service.d.ts +0 -14
- package/dist/services/in-memory-queue-service.js +1 -15
- package/dist/services/in-memory-trigger-service.d.ts +0 -18
- package/dist/services/in-memory-trigger-service.js +1 -18
- package/dist/services/in-memory-workflow-service.d.ts +0 -16
- package/dist/services/in-memory-workflow-service.js +4 -33
- package/dist/services/index.d.ts +5 -6
- package/dist/services/index.js +2 -5
- package/dist/services/istanbul-coverage-service.d.ts +1 -5
- package/dist/services/istanbul-coverage-service.js +2 -8
- package/dist/services/jwt-service.d.ts +1 -16
- package/dist/services/local-content.d.ts +13 -2
- package/dist/services/local-content.js +40 -13
- package/dist/services/local-gateway-service.d.ts +0 -16
- package/dist/services/local-gateway-service.js +2 -17
- package/dist/services/local-secrets.d.ts +0 -4
- package/dist/services/local-secrets.js +0 -4
- package/dist/services/logger-console.d.ts +3 -7
- package/dist/services/logger-console.js +3 -7
- package/dist/services/logger.d.ts +2 -37
- package/dist/services/meta-service.d.ts +23 -26
- package/dist/services/meta-service.js +22 -36
- package/dist/services/personas-service.d.ts +134 -0
- package/dist/services/personas-service.js +40 -0
- package/dist/services/pikku-user-id.js +0 -4
- package/dist/services/queue-webhook-service.d.ts +2 -36
- package/dist/services/queue-webhook-service.js +9 -41
- package/dist/services/scheduler-service.d.ts +1 -50
- package/dist/services/scheduler-service.js +0 -10
- package/dist/services/schema-service.d.ts +1 -24
- package/dist/services/scope-service.d.ts +49 -34
- package/dist/services/scoped-secret-service.d.ts +0 -4
- package/dist/services/scoped-secret-service.js +0 -4
- package/dist/services/secret-host-binding.d.ts +8 -0
- package/dist/services/secret-host-binding.js +36 -0
- package/dist/services/secret-service.d.ts +5 -33
- package/dist/services/secretless.d.ts +6 -0
- package/dist/services/secretless.js +21 -0
- package/dist/services/stub-tracker.d.ts +7 -18
- package/dist/services/stub-tracker.js +8 -18
- package/dist/services/system-role-guard.d.ts +33 -0
- package/dist/services/system-role-guard.js +38 -0
- package/dist/services/trigger-service.d.ts +0 -12
- package/dist/services/typed-secret-service.d.ts +0 -7
- package/dist/services/typed-secret-service.js +1 -7
- package/dist/services/v8-coverage-service.d.ts +2 -3
- package/dist/services/v8-coverage-service.js +1 -2
- package/dist/services/variables-service.d.ts +1 -8
- package/dist/services/webhook-service.d.ts +19 -63
- package/dist/services/webhook-service.js +6 -20
- package/dist/services/workflow-service.d.ts +3 -15
- package/dist/testing/service-tests.js +0 -17
- package/dist/time-utils.d.ts +0 -16
- package/dist/time-utils.js +1 -19
- package/dist/types/core.types.d.ts +99 -219
- package/dist/types/core.types.js +0 -42
- package/dist/types/state.types.d.ts +4 -9
- package/dist/utils/hmac.d.ts +4 -10
- package/dist/utils/hmac.js +4 -10
- package/dist/utils/safe-fetch.d.ts +7 -35
- package/dist/utils/safe-fetch.js +13 -53
- package/dist/utils.d.ts +1 -6
- package/dist/utils.js +6 -15
- package/dist/wirings/actor-flow/actor-flow.types.d.ts +1 -34
- package/dist/wirings/actor-flow/index.d.ts +0 -9
- package/dist/wirings/actor-flow/run-conversation.d.ts +5 -5
- package/dist/wirings/actor-flow/run-conversation.js +14 -7
- package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -5
- package/dist/wirings/ai-agent/ai-agent-agui.js +34 -12
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +7 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.js +7 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +153 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.js +256 -0
- package/dist/wirings/ai-agent/ai-agent-memory.js +0 -2
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -9
- package/dist/wirings/ai-agent/ai-agent-model-config.js +1 -9
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -99
- package/dist/wirings/ai-agent/ai-agent-prepare.js +58 -131
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +2 -1
- package/dist/wirings/ai-agent/ai-agent-registry.js +5 -1
- package/dist/wirings/ai-agent/ai-agent-runner.js +49 -20
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +25 -2
- package/dist/wirings/ai-agent/ai-agent-stream.js +153 -63
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +84 -4
- package/dist/wirings/ai-agent/index.d.ts +6 -4
- package/dist/wirings/ai-agent/index.js +5 -4
- package/dist/wirings/ai-agent/voice-input.d.ts +39 -1
- package/dist/wirings/ai-agent/voice-input.js +46 -3
- package/dist/wirings/ai-agent/voice-output.d.ts +54 -1
- package/dist/wirings/ai-agent/voice-output.js +153 -50
- package/dist/wirings/channel/channel-common.d.ts +7 -20
- package/dist/wirings/channel/channel-common.js +7 -21
- package/dist/wirings/channel/channel-handler.js +25 -6
- package/dist/wirings/channel/channel-host-rpc.d.ts +25 -0
- package/dist/wirings/channel/channel-host-rpc.js +38 -0
- package/dist/wirings/channel/channel-middleware-runner.d.ts +0 -12
- package/dist/wirings/channel/channel-middleware-runner.js +0 -12
- package/dist/wirings/channel/channel-rpc-registry.d.ts +31 -0
- package/dist/wirings/channel/channel-rpc-registry.js +89 -0
- package/dist/wirings/channel/channel-rpc-responder.d.ts +15 -0
- package/dist/wirings/channel/channel-rpc-responder.js +71 -0
- package/dist/wirings/channel/channel-rpc-service.d.ts +40 -0
- package/dist/wirings/channel/channel-rpc-service.js +106 -0
- package/dist/wirings/channel/channel-rpc-validators.d.ts +14 -0
- package/dist/wirings/channel/channel-rpc-validators.js +30 -0
- package/dist/wirings/channel/channel-rpc.d.ts +5 -0
- package/dist/wirings/channel/channel-rpc.js +5 -0
- package/dist/wirings/channel/channel-rpc.types.d.ts +90 -0
- package/dist/wirings/channel/channel-rpc.types.js +50 -0
- package/dist/wirings/channel/channel-runner.d.ts +0 -4
- package/dist/wirings/channel/channel-runner.js +0 -14
- package/dist/wirings/channel/channel-store.d.ts +0 -10
- package/dist/wirings/channel/channel.types.d.ts +12 -1
- package/dist/wirings/channel/define-channel-routes.d.ts +0 -20
- package/dist/wirings/channel/define-channel-routes.js +0 -20
- package/dist/wirings/channel/eventhub-service.d.ts +0 -18
- package/dist/wirings/channel/index.d.ts +4 -1
- package/dist/wirings/channel/index.js +2 -0
- package/dist/wirings/channel/local/local-channel-runner.js +3 -1
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +0 -33
- package/dist/wirings/channel/local/local-eventhub-service.js +2 -36
- package/dist/wirings/channel/log-channels.d.ts +0 -4
- package/dist/wirings/channel/log-channels.js +0 -4
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +6 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +2 -5
- package/dist/wirings/cli/channel/cli-approval.d.ts +41 -0
- package/dist/wirings/cli/channel/cli-approval.js +81 -0
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +0 -4
- package/dist/wirings/cli/channel/cli-channel-runner.js +3 -25
- package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +47 -9
- package/dist/wirings/cli/channel/cli-raw-channel-runner.js +24 -16
- package/dist/wirings/cli/channel/cli-raw-client-runner.d.ts +20 -0
- package/dist/wirings/cli/channel/cli-raw-client-runner.js +121 -0
- package/dist/wirings/cli/channel/index.d.ts +4 -0
- package/dist/wirings/cli/channel/index.js +2 -0
- package/dist/wirings/cli/cli-runner.d.ts +20 -20
- package/dist/wirings/cli/cli-runner.js +28 -89
- package/dist/wirings/cli/cli.types.d.ts +14 -3
- package/dist/wirings/cli/command-parser.d.ts +1 -10
- package/dist/wirings/cli/command-parser.js +10 -87
- package/dist/wirings/cli/define-cli-commands.d.ts +1 -17
- package/dist/wirings/cli/define-cli-commands.js +1 -17
- package/dist/wirings/credential/credential.types.d.ts +0 -12
- package/dist/wirings/credential/define-credential.d.ts +48 -0
- package/dist/wirings/credential/define-credential.js +47 -0
- package/dist/wirings/credential/index.d.ts +1 -1
- package/dist/wirings/credential/index.js +1 -1
- package/dist/wirings/credential/validate-credential-definitions.d.ts +2 -4
- package/dist/wirings/gateway/gateway-runner.d.ts +1 -20
- package/dist/wirings/gateway/gateway-runner.js +8 -105
- package/dist/wirings/gateway/gateway.types.d.ts +7 -80
- package/dist/wirings/http/http-routes.d.ts +0 -63
- package/dist/wirings/http/http-routes.js +0 -63
- package/dist/wirings/http/http-runner.d.ts +1 -100
- package/dist/wirings/http/http-runner.js +12 -166
- package/dist/wirings/http/http.types.d.ts +16 -55
- package/dist/wirings/http/index.d.ts +2 -1
- package/dist/wirings/http/index.js +1 -1
- package/dist/wirings/http/log-http-routes.d.ts +0 -4
- package/dist/wirings/http/log-http-routes.js +0 -4
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +6 -36
- package/dist/wirings/http/pikku-fetch-http-request.js +56 -50
- package/dist/wirings/http/pikku-fetch-http-response.js +0 -3
- package/dist/wirings/http/routers/path-to-regex.js +2 -13
- package/dist/wirings/http/web-request.d.ts +0 -8
- package/dist/wirings/http/web-request.js +25 -17
- package/dist/wirings/mcp/mcp-runner.d.ts +2 -0
- package/dist/wirings/mcp/mcp-runner.js +6 -16
- package/dist/wirings/mcp/mcp.types.d.ts +2 -35
- package/dist/wirings/oauth2/oauth2.types.d.ts +0 -28
- package/dist/wirings/oauth2/oauth2.types.js +0 -3
- package/dist/wirings/persona/define-personas.d.ts +28 -0
- package/dist/wirings/persona/define-personas.js +27 -0
- package/dist/wirings/persona/index.d.ts +21 -0
- package/dist/wirings/persona/index.js +17 -0
- package/dist/wirings/persona/persona-email.d.ts +37 -0
- package/dist/wirings/persona/persona-email.js +69 -0
- package/dist/wirings/persona/persona-environments.d.ts +45 -0
- package/dist/wirings/persona/persona-environments.js +81 -0
- package/dist/wirings/persona/persona-mailbox.d.ts +101 -0
- package/dist/wirings/persona/persona-mailbox.js +53 -0
- package/dist/wirings/persona/persona.types.d.ts +125 -0
- package/dist/wirings/persona/persona.types.js +1 -0
- package/dist/wirings/persona/validate-personas.d.ts +53 -0
- package/dist/wirings/persona/validate-personas.js +94 -0
- package/dist/wirings/queue/index.d.ts +3 -0
- package/dist/wirings/queue/index.js +2 -3
- package/dist/wirings/queue/queue-identity.d.ts +28 -0
- package/dist/wirings/queue/queue-identity.js +102 -0
- package/dist/wirings/queue/queue-runner.d.ts +0 -19
- package/dist/wirings/queue/queue-runner.js +9 -30
- package/dist/wirings/queue/queue.types.d.ts +18 -89
- package/dist/wirings/queue/register-queue-helper.d.ts +0 -12
- package/dist/wirings/queue/register-queue-helper.js +0 -11
- package/dist/wirings/queue/signed-queue-service.d.ts +16 -0
- package/dist/wirings/queue/signed-queue-service.js +42 -0
- package/dist/wirings/queue/validate-worker-config.d.ts +2 -23
- package/dist/wirings/queue/validate-worker-config.js +0 -14
- package/dist/wirings/role/define-system-role.d.ts +32 -0
- package/dist/wirings/role/define-system-role.js +31 -0
- package/dist/wirings/role/index.d.ts +3 -0
- package/dist/wirings/role/index.js +2 -0
- package/dist/wirings/role/role.types.d.ts +43 -0
- package/dist/wirings/role/role.types.js +1 -0
- package/dist/wirings/role/validate-role-definitions.d.ts +21 -0
- package/dist/wirings/role/validate-role-definitions.js +71 -0
- package/dist/wirings/rpc/addon-runner.d.ts +0 -19
- package/dist/wirings/rpc/addon-runner.js +0 -51
- package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -12
- package/dist/wirings/rpc/remote-addon-auth.js +1 -9
- package/dist/wirings/rpc/rpc-runner.d.ts +11 -18
- package/dist/wirings/rpc/rpc-runner.js +88 -105
- package/dist/wirings/rpc/rpc-types.d.ts +7 -6
- package/dist/wirings/rpc/wire-addon.d.ts +25 -0
- package/dist/wirings/rpc/wire-addon.js +62 -0
- package/dist/wirings/rpc/wire-remote-addon.d.ts +3 -28
- package/dist/wirings/rpc/wire-remote-addon.js +0 -8
- package/dist/wirings/scheduler/log-schedulers.d.ts +0 -4
- package/dist/wirings/scheduler/log-schedulers.js +0 -4
- package/dist/wirings/scheduler/scheduler-runner.d.ts +0 -1
- package/dist/wirings/scheduler/scheduler-runner.js +0 -1
- package/dist/wirings/scheduler/scheduler.types.d.ts +1 -14
- package/dist/wirings/scope/define-scope.d.ts +32 -0
- package/dist/wirings/scope/define-scope.js +31 -0
- package/dist/wirings/scope/index.d.ts +1 -1
- package/dist/wirings/scope/index.js +1 -1
- package/dist/wirings/scope/scope.types.d.ts +7 -9
- package/dist/wirings/scope/validate-scope-definitions.d.ts +2 -21
- package/dist/wirings/scope/validate-scope-definitions.js +3 -21
- package/dist/wirings/secret/index.d.ts +1 -1
- package/dist/wirings/secret/index.js +1 -1
- package/dist/wirings/secret/secret.types.d.ts +19 -15
- package/dist/wirings/secret/secret.types.js +1 -1
- package/dist/wirings/secret/validate-secret-definitions.d.ts +2 -4
- package/dist/wirings/trigger/trigger-runner.d.ts +0 -27
- package/dist/wirings/trigger/trigger-runner.js +1 -24
- package/dist/wirings/trigger/trigger.types.d.ts +1 -82
- package/dist/wirings/trigger/trigger.types.js +0 -34
- package/dist/wirings/variable/index.d.ts +1 -1
- package/dist/wirings/variable/index.js +1 -1
- package/dist/wirings/variable/validate-variable-definitions.d.ts +2 -4
- package/dist/wirings/variable/variable.types.d.ts +1 -13
- package/dist/wirings/variable/variable.types.js +1 -1
- package/dist/wirings/virtual-user/index.d.ts +27 -0
- package/dist/wirings/virtual-user/index.js +8 -0
- package/dist/wirings/virtual-user/run-virtual-user.d.ts +92 -0
- package/dist/wirings/virtual-user/run-virtual-user.js +478 -0
- package/dist/wirings/virtual-user/virtual-user-agents.d.ts +38 -0
- package/dist/wirings/virtual-user/virtual-user-agents.js +24 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.d.ts +92 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.js +134 -0
- package/dist/wirings/virtual-user/virtual-user-derive.d.ts +26 -0
- package/dist/wirings/virtual-user/virtual-user-derive.js +137 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.d.ts +79 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.js +128 -0
- package/dist/wirings/virtual-user/virtual-user-intents.d.ts +78 -0
- package/dist/wirings/virtual-user/virtual-user-intents.js +142 -0
- package/dist/wirings/virtual-user/virtual-user-rng.d.ts +24 -0
- package/dist/wirings/virtual-user/virtual-user-rng.js +44 -0
- package/dist/wirings/virtual-user/virtual-user-target.d.ts +21 -0
- package/dist/wirings/virtual-user/virtual-user-target.js +34 -0
- package/dist/wirings/virtual-user/virtual-user.types.d.ts +199 -0
- package/dist/wirings/virtual-user/virtual-user.types.js +8 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +5 -5
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +0 -4
- package/dist/wirings/workflow/dsl/workflow-runner.js +0 -4
- package/dist/wirings/workflow/feature.d.ts +0 -19
- package/dist/wirings/workflow/feature.js +0 -19
- package/dist/wirings/workflow/graph/graph-node.d.ts +0 -98
- package/dist/wirings/workflow/graph/graph-node.js +0 -34
- package/dist/wirings/workflow/graph/graph-runner.js +6 -41
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +0 -4
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -58
- package/dist/wirings/workflow/graph/workflow-graph.types.js +0 -6
- package/dist/wirings/workflow/index.d.ts +5 -7
- package/dist/wirings/workflow/index.js +3 -17
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +87 -5
- package/dist/wirings/workflow/pikku-scenario-service.js +204 -42
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +7 -459
- package/dist/wirings/workflow/pikku-workflow-service.js +58 -551
- package/dist/wirings/workflow/run-timeline.d.ts +0 -47
- package/dist/wirings/workflow/run-timeline.js +0 -22
- package/dist/wirings/workflow/scenario-cookie-jar.d.ts +0 -23
- package/dist/wirings/workflow/scenario-cookie-jar.js +0 -16
- package/dist/wirings/workflow/scenario-poll.d.ts +0 -15
- package/dist/wirings/workflow/scenario-poll.js +0 -12
- package/dist/wirings/workflow/scenario-prose.d.ts +0 -28
- package/dist/wirings/workflow/scenario-prose.js +0 -18
- package/dist/wirings/workflow/scenario-step-guards.d.ts +0 -13
- package/dist/wirings/workflow/scenario-step-guards.js +1 -14
- package/dist/wirings/workflow/scenario-step.types.d.ts +72 -6
- package/dist/wirings/workflow/scenario-step.types.js +5 -1
- package/dist/wirings/workflow/scenario-surface.d.ts +16 -0
- package/dist/wirings/workflow/scenario-surface.js +56 -0
- package/dist/wirings/workflow/workflow-invocation-id.d.ts +0 -18
- package/dist/wirings/workflow/workflow-invocation-id.js +2 -22
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +0 -20
- package/dist/wirings/workflow/workflow-queue-workers.js +0 -19
- package/dist/wirings/workflow/workflow.types.d.ts +0 -197
- package/knowledge/decisions/index.md +19 -0
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +49 -0
- package/knowledge/decisions/internals/actor-flow-conversations-seed-a-hidden-kickoff-message.md +23 -0
- package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +24 -0
- package/knowledge/decisions/internals/actor-flow-verdicts-are-llm-self-evaluations.md +25 -0
- package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +26 -0
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +33 -0
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +28 -0
- package/knowledge/decisions/internals/ai-agent-agui-bridge-obeys-the-client-ordering-contract.md +29 -0
- package/knowledge/decisions/internals/ai-agent-audio-chunks-carry-the-format-the-provider-returned.md +20 -0
- package/knowledge/decisions/internals/ai-agent-credential-suspensions-hide-the-tool-result.md +26 -0
- package/knowledge/decisions/internals/ai-agent-delegate-and-supervise-hide-different-text.md +26 -0
- package/knowledge/decisions/internals/ai-agent-llm-tool-arguments-have-nulls-stripped.md +23 -0
- package/knowledge/decisions/internals/ai-agent-model-config-stays-a-single-resolution-seam.md +25 -0
- package/knowledge/decisions/internals/ai-agent-onerror-hooks-cannot-change-the-failure.md +22 -0
- package/knowledge/decisions/internals/ai-agent-runner-methods-must-keep-their-receiver.md +22 -0
- package/knowledge/decisions/internals/ai-agent-stream-persistence-is-best-effort.md +27 -0
- package/knowledge/decisions/internals/ai-agent-sub-agents-inherit-the-parent-context-block.md +26 -0
- package/knowledge/decisions/internals/ai-agent-tool-execute-failures-are-logged-unconditionally.md +25 -0
- package/knowledge/decisions/internals/ai-agent-voice-input-transcribes-audio-parts-in-place.md +22 -0
- package/knowledge/decisions/internals/ai-agent-working-memory-is-persisted-only-when-valid.md +25 -0
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +30 -0
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +31 -0
- package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +29 -0
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +28 -0
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +27 -0
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +28 -0
- package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +34 -0
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +29 -0
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +34 -0
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +44 -0
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +39 -0
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +42 -0
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +39 -0
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +43 -0
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +38 -0
- package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +44 -0
- package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +27 -0
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +32 -0
- package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +28 -0
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +31 -0
- package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +26 -0
- package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +32 -0
- package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +28 -0
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +30 -0
- package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +26 -0
- package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +28 -0
- package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +32 -0
- package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +26 -0
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +25 -0
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +26 -0
- package/knowledge/decisions/internals/index.md +113 -0
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +25 -0
- package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +26 -0
- package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +24 -0
- package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +28 -0
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +27 -0
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +31 -0
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +32 -0
- package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +27 -0
- package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +26 -0
- package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +27 -0
- package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +30 -0
- package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +28 -0
- package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +30 -0
- package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +29 -0
- package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +27 -0
- package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +40 -0
- package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +26 -0
- package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +33 -0
- package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +26 -0
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +26 -0
- package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +25 -0
- package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +58 -0
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +34 -0
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +42 -0
- package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +38 -0
- package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +29 -0
- package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +42 -0
- package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +25 -0
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +29 -0
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +43 -0
- package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +29 -0
- package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +42 -0
- package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +33 -0
- package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +32 -0
- package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +31 -0
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +39 -0
- package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +29 -0
- package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +33 -0
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +37 -0
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +50 -0
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +43 -0
- package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +32 -0
- package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +18 -0
- package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +34 -0
- package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +26 -0
- package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +33 -0
- package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +27 -0
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +34 -0
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +38 -0
- package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +30 -0
- package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +26 -0
- package/knowledge/decisions/security/actor-flow-missing-approval-decisions-default-to-denied.md +22 -0
- package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +27 -0
- package/knowledge/decisions/security/actor-sign-in-only-works-for-actor-flagged-users.md +27 -0
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +43 -0
- package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +52 -0
- package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +46 -0
- package/knowledge/decisions/security/ai-agent-approval-forwarding-requires-a-symbol-brand.md +27 -0
- package/knowledge/decisions/security/ai-agent-credential-requests-are-symbol-branded.md +37 -0
- package/knowledge/decisions/security/ai-agent-gate-requires-a-session-only-when-auth-is-true.md +31 -0
- package/knowledge/decisions/security/ai-agent-ownership-failures-never-echo-the-resource.md +23 -0
- package/knowledge/decisions/security/ai-agent-resume-re-runs-the-authorization-gate.md +22 -0
- package/knowledge/decisions/security/ai-agent-sessionless-deployments-have-no-thread-ownership.md +39 -0
- package/knowledge/decisions/security/ai-agent-thread-ownership-composes-the-session-principal.md +30 -0
- package/knowledge/decisions/security/ai-agent-tool-filtering-reads-the-live-function-config.md +24 -0
- package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +30 -0
- package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +49 -0
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +76 -0
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +39 -0
- package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +37 -0
- package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +31 -0
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +30 -0
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +40 -0
- package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +33 -0
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +46 -0
- package/knowledge/decisions/security/index.md +55 -0
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +27 -0
- package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +40 -0
- package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +31 -0
- package/knowledge/decisions/security/pikku-carries-actor-scopes-as-data-and-the-app-grants-them.md +26 -0
- package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +69 -0
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +39 -0
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +34 -0
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +49 -0
- package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +30 -0
- package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +28 -0
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +34 -0
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +37 -0
- package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +25 -0
- package/knowledge/decisions/security/workflow-actor-steps-always-use-the-real-transport.md +34 -0
- package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +40 -0
- package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-actor-and-per-scenario.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +31 -0
- package/knowledge/index.md +24 -0
- package/knowledge/questions/index.md +15 -0
- package/package.json +4 -2
- package/run-tests.sh +0 -0
- package/src/crypto-utils.test.ts +460 -19
- package/src/crypto-utils.ts +283 -55
- package/src/data-classification.ts +1 -7
- package/src/dev/hot-reload.test.ts +0 -4
- package/src/dev/hot-reload.ts +11 -30
- package/src/dev/module-runner.ts +7 -32
- package/src/dev/reload-meta.ts +9 -29
- package/src/errors/error-handler.ts +20 -35
- package/src/errors/error.test.ts +30 -1
- package/src/errors/errors.ts +73 -157
- package/src/function/abort-scope.test.ts +97 -0
- package/src/function/abort-scope.ts +80 -0
- package/src/function/function-runner.test.ts +75 -7
- package/src/function/function-runner.ts +73 -30
- package/src/function/functions.types.ts +56 -136
- package/src/function/list.types.test.ts +3 -25
- package/src/function/list.types.ts +12 -62
- package/src/gopass-secrets-removed.test.ts +51 -0
- package/src/handle-error.test.ts +108 -1
- package/src/handle-error.ts +8 -18
- package/src/index.ts +60 -1
- package/src/middleware/auth-apikey.test.ts +0 -1
- package/src/middleware/auth-apikey.ts +0 -17
- package/src/middleware/auth-bearer.test.ts +0 -3
- package/src/middleware/auth-bearer.ts +3 -40
- package/src/middleware/auth-cookie.test.ts +0 -6
- package/src/middleware/auth-cookie.ts +2 -26
- package/src/middleware/cors.test.ts +34 -0
- package/src/middleware/cors.ts +12 -33
- package/src/middleware/remote-auth.test.ts +24 -9
- package/src/middleware/remote-auth.ts +10 -2
- package/src/middleware/telemetry.ts +2 -31
- package/src/middleware-runner.test.ts +0 -2
- package/src/middleware-runner.ts +5 -74
- package/src/permissions.test.ts +30 -0
- package/src/permissions.ts +24 -74
- package/src/pikku-request.ts +0 -6
- package/src/pikku-state.ts +2 -30
- package/src/production-barrels-stay-lean.test.ts +110 -0
- package/src/remote.test.ts +172 -0
- package/src/remote.ts +17 -7
- package/src/schema.test.ts +103 -0
- package/src/schema.ts +35 -18
- package/src/scopes.ts +7 -48
- package/src/services/ai-agent-runner-service.ts +20 -0
- package/src/services/ai-embedding-service.ts +3 -25
- package/src/services/audit-service.ts +1 -2
- package/src/services/content-service.ts +1 -46
- package/src/services/credential-service.ts +3 -40
- package/src/services/credential-wire-service.test.ts +0 -2
- package/src/services/deployment-service.ts +3 -9
- package/src/services/gateway-service.ts +0 -15
- package/src/services/{http-scenario-actors-converse.test.ts → http-personas-converse.test.ts} +38 -9
- package/src/services/{http-scenario-actors.test.ts → http-personas.test.ts} +39 -22
- package/src/services/{http-scenario-actors.ts → http-personas.ts} +85 -45
- package/src/services/in-memory-queue-service.ts +1 -15
- package/src/services/in-memory-trigger-service.ts +1 -18
- package/src/services/in-memory-workflow-service.test.ts +0 -13
- package/src/services/in-memory-workflow-service.ts +4 -38
- package/src/services/index.ts +20 -15
- package/src/services/istanbul-coverage-service.ts +2 -8
- package/src/services/jwt-service.ts +1 -16
- package/src/services/local-content.test.ts +159 -27
- package/src/services/local-content.ts +55 -23
- package/src/services/local-gateway-service.ts +2 -17
- package/src/services/local-secrets.ts +0 -4
- package/src/services/logger-console.test.ts +0 -1
- package/src/services/logger-console.ts +3 -7
- package/src/services/logger.ts +2 -37
- package/src/services/meta-service.test.ts +1 -5
- package/src/services/meta-service.ts +41 -61
- package/src/services/{scenario-actors-service.ts → personas-service.ts} +48 -43
- package/src/services/pikku-user-id.ts +0 -4
- package/src/services/queue-webhook-service.ts +9 -41
- package/src/services/scheduler-service.ts +1 -50
- package/src/services/schema-service.ts +1 -24
- package/src/services/scope-service.ts +50 -34
- package/src/services/scoped-secret-service.ts +0 -4
- package/src/services/secret-host-binding.test.ts +138 -0
- package/src/services/secret-host-binding.ts +51 -0
- package/src/services/secret-service.ts +5 -33
- package/src/services/secretless.test.ts +54 -0
- package/src/services/secretless.ts +29 -0
- package/src/services/stub-tracker.ts +8 -18
- package/src/services/system-role-guard.test.ts +93 -0
- package/src/services/system-role-guard.ts +71 -0
- package/src/services/trigger-service.ts +0 -12
- package/src/services/typed-secret-service.ts +1 -7
- package/src/services/v8-coverage-service.ts +3 -6
- package/src/services/variables-service.ts +1 -8
- package/src/services/webhook-service.ts +19 -63
- package/src/services/workflow-service.ts +3 -20
- package/src/testing/service-tests.ts +0 -26
- package/src/time-utils.ts +1 -19
- package/src/types/core.types.ts +116 -229
- package/src/types/state.types.ts +7 -9
- package/src/utils/hmac.ts +4 -10
- package/src/utils/safe-fetch.ts +13 -54
- package/src/utils.test.ts +11 -2
- package/src/utils.ts +6 -15
- package/src/wirings/actor-flow/actor-flow.types.ts +1 -34
- package/src/wirings/actor-flow/index.ts +0 -9
- package/src/wirings/actor-flow/run-conversation.test.ts +11 -6
- package/src/wirings/actor-flow/run-conversation.ts +19 -12
- package/src/wirings/ai-agent/ai-agent-agui.test.ts +75 -10
- package/src/wirings/ai-agent/ai-agent-agui.ts +36 -17
- package/src/wirings/ai-agent/ai-agent-helpers.ts +20 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +842 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.ts +399 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-model-config.ts +1 -9
- package/src/wirings/ai-agent/ai-agent-prepare.test.ts +202 -31
- package/src/wirings/ai-agent/ai-agent-prepare.ts +82 -138
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +191 -6
- package/src/wirings/ai-agent/ai-agent-registry.ts +18 -1
- package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +11 -9
- package/src/wirings/ai-agent/ai-agent-runner.ts +67 -33
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +205 -103
- package/src/wirings/ai-agent/ai-agent-stream.ts +192 -75
- package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +301 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +85 -4
- package/src/wirings/ai-agent/index.ts +35 -3
- package/src/wirings/ai-agent/voice-input.test.ts +72 -7
- package/src/wirings/ai-agent/voice-input.ts +48 -3
- package/src/wirings/ai-agent/voice-output.test.ts +422 -0
- package/src/wirings/ai-agent/voice-output.ts +216 -56
- package/src/wirings/channel/channel-common.ts +15 -20
- package/src/wirings/channel/channel-handler.test.ts +50 -0
- package/src/wirings/channel/channel-handler.ts +32 -11
- package/src/wirings/channel/channel-host-rpc.test.ts +150 -0
- package/src/wirings/channel/channel-host-rpc.ts +69 -0
- package/src/wirings/channel/channel-middleware-runner.test.ts +0 -1
- package/src/wirings/channel/channel-middleware-runner.ts +0 -12
- package/src/wirings/channel/channel-rpc-registry.ts +116 -0
- package/src/wirings/channel/channel-rpc-responder.ts +117 -0
- package/src/wirings/channel/channel-rpc-service.ts +146 -0
- package/src/wirings/channel/channel-rpc-validators.ts +65 -0
- package/src/wirings/channel/channel-rpc.test.ts +820 -0
- package/src/wirings/channel/channel-rpc.ts +5 -0
- package/src/wirings/channel/channel-rpc.types.ts +150 -0
- package/src/wirings/channel/channel-runner.ts +0 -14
- package/src/wirings/channel/channel-store.ts +0 -10
- package/src/wirings/channel/channel.types.ts +19 -8
- package/src/wirings/channel/define-channel-routes.ts +0 -20
- package/src/wirings/channel/eventhub-service.ts +0 -18
- package/src/wirings/channel/index.ts +35 -0
- package/src/wirings/channel/local/local-channel-handler.ts +3 -1
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -10
- package/src/wirings/channel/local/local-channel-runner.ts +3 -1
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -13
- package/src/wirings/channel/local/local-eventhub-service.ts +2 -37
- package/src/wirings/channel/log-channels.ts +0 -4
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +83 -2
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +7 -0
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +2 -5
- package/src/wirings/cli/channel/cli-approval.test.ts +177 -0
- package/src/wirings/cli/channel/cli-approval.ts +135 -0
- package/src/wirings/cli/channel/cli-channel-runner.ts +4 -26
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +169 -0
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +59 -16
- package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +480 -0
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +155 -0
- package/src/wirings/cli/channel/index.ts +9 -0
- package/src/wirings/cli/cli-runner.test.ts +0 -1
- package/src/wirings/cli/cli-runner.ts +46 -88
- package/src/wirings/cli/cli.types.ts +14 -3
- package/src/wirings/cli/command-parser.test.ts +0 -4
- package/src/wirings/cli/command-parser.ts +11 -91
- package/src/wirings/cli/define-cli-commands.ts +1 -17
- package/src/wirings/credential/credential.types.ts +0 -12
- package/src/wirings/credential/{wire-credential.ts → define-credential.ts} +7 -7
- package/src/wirings/credential/index.ts +1 -1
- package/src/wirings/credential/validate-credential-definitions.ts +2 -4
- package/src/wirings/gateway/gateway-runner.test.ts +1 -21
- package/src/wirings/gateway/gateway-runner.ts +8 -110
- package/src/wirings/gateway/gateway.types.ts +7 -80
- package/src/wirings/http/http-routes.test.ts +0 -3
- package/src/wirings/http/http-routes.ts +0 -86
- package/src/wirings/http/http-runner.test.ts +0 -1
- package/src/wirings/http/http-runner.ts +12 -168
- package/src/wirings/http/http.types.ts +17 -62
- package/src/wirings/http/index.ts +5 -1
- package/src/wirings/http/log-http-routes.ts +0 -4
- package/src/wirings/http/pikku-fetch-http-request.test.ts +88 -7
- package/src/wirings/http/pikku-fetch-http-request.ts +74 -50
- package/src/wirings/http/pikku-fetch-http-response.test.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -3
- package/src/wirings/http/routers/path-to-regex.test.ts +4 -17
- package/src/wirings/http/routers/path-to-regex.ts +2 -13
- package/src/wirings/http/web-request.test.ts +33 -2
- package/src/wirings/http/web-request.ts +30 -17
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -1
- package/src/wirings/mcp/mcp-runner.test.ts +40 -0
- package/src/wirings/mcp/mcp-runner.ts +9 -15
- package/src/wirings/mcp/mcp.types.ts +7 -42
- package/src/wirings/oauth2/oauth2.types.ts +0 -30
- package/src/wirings/persona/define-personas.ts +29 -0
- package/src/wirings/persona/index.ts +62 -0
- package/src/wirings/persona/persona-email.ts +87 -0
- package/src/wirings/persona/persona-environments.test.ts +183 -0
- package/src/wirings/persona/persona-environments.ts +138 -0
- package/src/wirings/persona/persona-mailbox.ts +156 -0
- package/src/wirings/persona/persona.test.ts +220 -0
- package/src/wirings/persona/persona.types.ts +131 -0
- package/src/wirings/persona/validate-personas.ts +133 -0
- package/src/wirings/queue/index.ts +13 -3
- package/src/wirings/queue/queue-identity.test.ts +453 -0
- package/src/wirings/queue/queue-identity.ts +173 -0
- package/src/wirings/queue/queue-runner.ts +12 -31
- package/src/wirings/queue/queue.types.ts +19 -89
- package/src/wirings/queue/register-queue-helper.ts +0 -14
- package/src/wirings/queue/signed-queue-service.ts +59 -0
- package/src/wirings/queue/validate-worker-config.ts +2 -28
- package/src/wirings/role/define-system-role.ts +33 -0
- package/src/wirings/role/index.ts +13 -0
- package/src/wirings/role/role.test.ts +104 -0
- package/src/wirings/role/role.types.ts +47 -0
- package/src/wirings/role/validate-role-definitions.ts +93 -0
- package/src/wirings/rpc/addon-auth-tags.test.ts +223 -0
- package/src/wirings/rpc/addon-runner.ts +0 -56
- package/src/wirings/rpc/addon-scopes.test.ts +225 -0
- package/src/wirings/rpc/remote-addon-auth.ts +1 -13
- package/src/wirings/rpc/rpc-runner.test.ts +186 -2
- package/src/wirings/rpc/rpc-runner.ts +145 -127
- package/src/wirings/rpc/rpc-types.ts +11 -6
- package/src/wirings/rpc/wire-addon.test.ts +43 -1
- package/src/wirings/rpc/wire-addon.ts +99 -0
- package/src/wirings/rpc/wire-remote-addon.ts +9 -29
- package/src/wirings/scheduler/log-schedulers.ts +0 -4
- package/src/wirings/scheduler/scheduler-runner.test.ts +1 -8
- package/src/wirings/scheduler/scheduler-runner.ts +0 -2
- package/src/wirings/scheduler/scheduler.types.ts +1 -14
- package/src/wirings/scope/{wire-scope.ts → define-scope.ts} +5 -6
- package/src/wirings/scope/index.ts +1 -1
- package/src/wirings/scope/scope.test.ts +1 -2
- package/src/wirings/scope/scope.types.ts +7 -9
- package/src/wirings/scope/validate-scope-definitions.ts +3 -21
- package/src/wirings/secret/index.ts +1 -1
- package/src/wirings/secret/secret.types.ts +19 -15
- package/src/wirings/secret/validate-secret-definitions.ts +2 -4
- package/src/wirings/trigger/trigger-runner.ts +1 -27
- package/src/wirings/trigger/trigger.types.ts +1 -82
- package/src/wirings/variable/index.ts +1 -1
- package/src/wirings/variable/validate-variable-definitions.ts +2 -4
- package/src/wirings/variable/variable.types.ts +1 -13
- package/src/wirings/virtual-user/index.ts +76 -0
- package/src/wirings/virtual-user/run-virtual-user.test.ts +765 -0
- package/src/wirings/virtual-user/run-virtual-user.ts +671 -0
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +65 -0
- package/src/wirings/virtual-user/virtual-user-agents.ts +57 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +215 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.ts +184 -0
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +398 -0
- package/src/wirings/virtual-user/virtual-user-derive.ts +173 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +63 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +213 -0
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +208 -0
- package/src/wirings/virtual-user/virtual-user-intents.ts +185 -0
- package/src/wirings/virtual-user/virtual-user-rng.test.ts +72 -0
- package/src/wirings/virtual-user/virtual-user-rng.ts +50 -0
- package/src/wirings/virtual-user/virtual-user-target.ts +47 -0
- package/src/wirings/virtual-user/virtual-user.types.ts +219 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +5 -4
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -4
- package/src/wirings/workflow/feature.ts +0 -19
- package/src/wirings/workflow/graph/graph-node.ts +0 -136
- package/src/wirings/workflow/graph/graph-runner.test.ts +20 -19
- package/src/wirings/workflow/graph/graph-runner.ts +6 -41
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -4
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -58
- package/src/wirings/workflow/index.ts +10 -44
- package/src/wirings/workflow/pikku-scenario-service.ts +235 -52
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -39
- package/src/wirings/workflow/pikku-workflow-service.ts +77 -674
- package/src/wirings/workflow/run-timeline.test.ts +7 -19
- package/src/wirings/workflow/run-timeline.ts +0 -56
- package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -1
- package/src/wirings/workflow/scenario-cookie-jar.ts +0 -25
- package/src/wirings/workflow/scenario-expectations.test.ts +2 -7
- package/src/wirings/workflow/scenario-hooks.test.ts +2 -7
- package/src/wirings/workflow/scenario-poll.test.ts +0 -2
- package/src/wirings/workflow/scenario-poll.ts +0 -15
- package/src/wirings/workflow/scenario-prose.ts +0 -28
- package/src/wirings/workflow/scenario-service.test.ts +2 -9
- package/src/wirings/workflow/scenario-step-guards.ts +1 -14
- package/src/wirings/workflow/scenario-step.test.ts +159 -14
- package/src/wirings/workflow/scenario-step.types.ts +82 -6
- package/src/wirings/workflow/scenario-surface.test.ts +145 -0
- package/src/wirings/workflow/scenario-surface.ts +71 -0
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +14 -15
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -4
- package/src/wirings/workflow/workflow-inline-authority.test.ts +169 -0
- package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -2
- package/src/wirings/workflow/workflow-invocation-id.ts +2 -22
- package/src/wirings/workflow/workflow-mirror.test.ts +0 -7
- package/src/wirings/workflow/workflow-on-error.test.ts +0 -9
- package/src/wirings/workflow/workflow-queue-workers.ts +0 -21
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +8 -7
- package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -5
- package/src/wirings/workflow/workflow-run-context.test.ts +5 -10
- package/src/wirings/workflow/workflow-run-polling.test.ts +0 -5
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +19 -4
- package/src/wirings/workflow/workflow-step-session.test.ts +0 -7
- package/src/wirings/workflow/workflow.types.ts +0 -203
- package/tsconfig.tsbuildinfo +1 -1
- package/src/middleware/timeout.ts +0 -22
- package/src/pikku-response.ts +0 -5
- package/src/services/gopass-secrets.ts +0 -78
- package/src/wirings/mcp/mcp-endpoint-registry.test.d.ts +0 -1
- package/src/wirings/workflow/dsl/index.ts +0 -36
- package/src/wirings/workflow/graph/index.ts +0 -15
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Queue jobs carry the producer's pikku user id
|
|
4
|
+
description: A job's pikkuUserId is trusted as identity by the worker, so enqueue rights are effectively act-as-user rights
|
|
5
|
+
tags: queue
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Queue jobs carry the producer's pikku user id
|
|
9
|
+
|
|
10
|
+
`JobOptions.pikkuUserId` (`packages/core/src/wirings/queue/queue.types.ts`) is
|
|
11
|
+
set by whoever enqueues the job. The adapter surfaces it as
|
|
12
|
+
`QueueJob.pikkuUserId`, `runQueueJob` in
|
|
13
|
+
`packages/core/src/wirings/queue/queue-runner.ts` copies it onto the wire as
|
|
14
|
+
`PikkuQueue.pikkuUserId`, and `resolveSession` in
|
|
15
|
+
`packages/core/src/function/function-runner.ts` then resolves it through
|
|
16
|
+
`defaultPikkuUserIdResolver` and loads that user's session out of the
|
|
17
|
+
`sessionStore`. The worker function runs with that session.
|
|
18
|
+
|
|
19
|
+
The claim is now HMAC-signed at enqueue and verified in `runQueueJob` — see
|
|
20
|
+
[[queue-job-identities-are-signed-at-enqueue]], which supersedes the "any
|
|
21
|
+
producer may name any user" reading below. Everything here still holds for the
|
|
22
|
+
*authorization* question: signing proves the producer held the deployment
|
|
23
|
+
secret, not that it was entitled to name that user.
|
|
24
|
+
|
|
25
|
+
There is no re-authentication at the worker boundary — the queue payload *is* the
|
|
26
|
+
credential. Workers run with `auth: false`, so nothing downstream re-checks that
|
|
27
|
+
the producer was entitled to name that user. This is deliberate: the whole point
|
|
28
|
+
is to let a background job resolve the same per-user credentials the original
|
|
29
|
+
request had, without persisting a token in the queue. The cost is that write
|
|
30
|
+
access to the queue is equivalent to being able to act as any user whose session
|
|
31
|
+
is in the store.
|
|
32
|
+
|
|
33
|
+
**What this rules out:** exposing job enqueue to untrusted callers, or letting a
|
|
34
|
+
client-supplied field flow into `JobOptions.pikkuUserId` without an authorization
|
|
35
|
+
check first. It also rules out treating the queue as an authorization boundary —
|
|
36
|
+
do not add a "the worker validated the producer's rights" assumption anywhere
|
|
37
|
+
downstream, and do not drop the id from the wire on the theory that workers are
|
|
38
|
+
unauthenticated anyway. Dropping an id that fails *signature* verification is a
|
|
39
|
+
different matter and is what the worker now does.
|
package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Remote addon tokens are client credentials, not mesh trust
|
|
4
|
+
description: wireRemoteAddon authenticates as a client to a hosted library and fails closed on an empty token; it never uses PIKKU_REMOTE_SECRET
|
|
5
|
+
tags: rpc
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Remote addon tokens are client credentials, not mesh trust
|
|
9
|
+
|
|
10
|
+
`resolveRemoteAddonToken` in
|
|
11
|
+
`packages/core/src/wirings/rpc/remote-addon-auth.ts` resolves the bearer token a
|
|
12
|
+
`wireRemoteAddon` consumer sends to the host. This is a **client** authenticating
|
|
13
|
+
to a hosted library — it is not pikku's trusted machine-to-machine mesh, which
|
|
14
|
+
uses `PIKKU_REMOTE_SECRET`. Conflating the two would hand a third-party addon
|
|
15
|
+
host a credential that grants mesh-level trust inside the consumer's own
|
|
16
|
+
deployment.
|
|
17
|
+
|
|
18
|
+
The consumer binds the addon's declared auth requirement to one of three local
|
|
19
|
+
sources: `credentialId`, a per-user credential read through `wire.getCredential`
|
|
20
|
+
and therefore scoped to `pikkuUserId`; `secretId`, a platform key from the
|
|
21
|
+
secrets service; or `resolve`, a custom escape hatch. The resolved token is never
|
|
22
|
+
logged or traced. Binding a `credentialId` without a wire that supports
|
|
23
|
+
credentials throws rather than falling back to a shared secret.
|
|
24
|
+
|
|
25
|
+
Resolution fails closed. `null` is returned only when no auth is bound at all,
|
|
26
|
+
which is the addon declaring its remote surface public. Once auth *is* bound, a
|
|
27
|
+
resolved value of `null`, `undefined` or `''` raises `RemoteAddonAuthError` (401)
|
|
28
|
+
instead of dispatching an unauthenticated request that the host might accept as
|
|
29
|
+
anonymous.
|
|
30
|
+
|
|
31
|
+
**What this rules out:** defaulting to `PIKKU_REMOTE_SECRET` or any ambient
|
|
32
|
+
credential when the bound source comes up empty, treating an empty token as
|
|
33
|
+
"public", and adding the token to log lines, trace headers or error messages for
|
|
34
|
+
debugging.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: A scaffolded surface is authenticated unless the config opts out in writing
|
|
4
|
+
description: scaffold.<feature> became boolean | { auth, path }, where true means authenticated — going public requires typing { auth: false }, and the legacy 'auth' | 'no-auth' strings are refused rather than coerced
|
|
5
|
+
tags: config, authorization, codegen, scaffold
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# A scaffolded surface is authenticated unless the config opts out in writing
|
|
9
|
+
|
|
10
|
+
`scaffold.<feature>` was `'auth' | 'no-auth' | false`. Two things were wrong
|
|
11
|
+
with it, and they compounded.
|
|
12
|
+
|
|
13
|
+
The auth dimension asked the wrong question of some features and the right one
|
|
14
|
+
of others. For `rpc` it is a blanket "no anonymous RPC in this app", set on a
|
|
15
|
+
dispatcher that cannot know what it dispatches to — wrong the moment one
|
|
16
|
+
legitimately public sessionless function exists. For `userAdmin` it was
|
|
17
|
+
redundant: the generated functions are `pikkuFunc` with `scopes:
|
|
18
|
+
['admin:users:list']`, gated twice over already. But for `agent`, `workflow`,
|
|
19
|
+
`events` and `scenarios` it was the *only* gate, because those generate real
|
|
20
|
+
endpoints the app never authors and has nowhere else to declare a gate for.
|
|
21
|
+
A uniform collapse to boolean would have silently opened four surfaces.
|
|
22
|
+
|
|
23
|
+
And the value read like a preference. `"rpc": "no-auth"` looks like a
|
|
24
|
+
starter-file setting; it was a live authorization decision, three directories
|
|
25
|
+
from the functions it governed. That is the shape the console incident took.
|
|
26
|
+
|
|
27
|
+
The type is now `boolean | { auth?: boolean; path?: string }`. `true` means
|
|
28
|
+
enabled **and authenticated**; a surface becomes public only by writing
|
|
29
|
+
`{ auth: false }`. Omitting a field can then never open anything — the failure
|
|
30
|
+
mode of a forgotten flag is a locked door. Features with no auth dimension
|
|
31
|
+
(`webhook`, `remoteRpc`, whose generator hardcodes `auth: false`) simply ignore
|
|
32
|
+
it.
|
|
33
|
+
|
|
34
|
+
The object form is also what makes the legacy strings safe to remove. An
|
|
35
|
+
earlier design used `string` for the output path, under which `"no-auth"` would
|
|
36
|
+
have parsed as *a file named `no-auth`* — every unmigrated config silently
|
|
37
|
+
producing nonsense instead of failing. With `boolean | object`, a string is
|
|
38
|
+
never valid, so `resolveScaffoldFeature` refuses `'auth'` and `'no-auth'` by
|
|
39
|
+
name and prints the replacement. Coercing them was rejected outright: the value
|
|
40
|
+
it would coerce to is the one that caused the incident.
|
|
41
|
+
|
|
42
|
+
Reading happens once, in `pikku-cli-config.ts`, so a legacy value fails at load
|
|
43
|
+
with the migration named rather than downstream where it has already become
|
|
44
|
+
something plausible.
|
|
45
|
+
|
|
46
|
+
**What this rules out:** a bare `true` that means "public"; inferring a
|
|
47
|
+
feature's auth posture from its default; using `string` for the output path
|
|
48
|
+
while the legacy string values still exist in the wild; and collapsing the auth
|
|
49
|
+
dimension uniformly across features that do not all have one.
|
package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Scenario-step functions are never externally invocable over RPC
|
|
4
|
+
description: rpcExposed requires expose and rejects scenarioStep, so test steps stay reachable only from inside a scenario run
|
|
5
|
+
tags: rpc
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Scenario-step functions are never externally invocable over RPC
|
|
9
|
+
|
|
10
|
+
`ContextAwareRPCService.rpcExposed` in
|
|
11
|
+
`packages/core/src/wirings/rpc/rpc-runner.ts` is the entry point for RPCs that
|
|
12
|
+
arrive from outside the process. It resolves the function's meta and throws
|
|
13
|
+
`RPCNotFoundError` unless `functionMeta.expose` is set **and**
|
|
14
|
+
`functionMeta.scenarioStep` is falsy — the same 404 an unknown name gets, so the
|
|
15
|
+
existence of a hidden function is not disclosed.
|
|
16
|
+
|
|
17
|
+
A scenario step is a piece of a test scenario: it may drive a browser, assert
|
|
18
|
+
against fixtures, or reach for privileged setup helpers. Steps are dispatched by
|
|
19
|
+
name from inside a scenario run through the internal `rpc` path, which does not
|
|
20
|
+
consult `expose`. If a step were also reachable from the outside, any caller who
|
|
21
|
+
guessed its name would get an unauthenticated handle on test tooling in whatever
|
|
22
|
+
environment the scenario code shipped to.
|
|
23
|
+
|
|
24
|
+
The two conditions are independent and both required: `expose` opts a function
|
|
25
|
+
into the external surface, `scenarioStep` opts it back out regardless.
|
|
26
|
+
|
|
27
|
+
**What this rules out:** collapsing the check to `!functionMeta.expose`,
|
|
28
|
+
returning a distinct "forbidden" error that confirms the name exists, and routing
|
|
29
|
+
external traffic through `rpc` instead of `rpcExposed` for convenience — `rpc`
|
|
30
|
+
performs no exposure check at all.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Scope resolution happens at the session boundary and scope sync never deletes
|
|
4
|
+
description: ScopeService is called when a session is built, never by the function runner, and syncScopes only ever adds — revoking is an explicit operation
|
|
5
|
+
tags: services
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Scope resolution happens at the session boundary and scope sync never deletes
|
|
9
|
+
|
|
10
|
+
Implementations of `ScopeService` (`packages/core/src/services/scope-service.ts`)
|
|
11
|
+
are called at the session boundary — better-auth's `mapSession`, for instance —
|
|
12
|
+
and never by the function runner. The runner reads `session.scopes` and performs
|
|
13
|
+
no I/O of its own, which is what keeps it viable on Workers and Lambda. Because
|
|
14
|
+
the session is rebuilt per request, a scope change takes effect on the next call:
|
|
15
|
+
nothing is cached and there is nothing to invalidate.
|
|
16
|
+
|
|
17
|
+
`syncScopes` is additive and never deletes. Scopes are declared in code, so a
|
|
18
|
+
declaration removed in a deploy would otherwise revoke a live grant the moment
|
|
19
|
+
the new build boots — silently, mid-rollout, for everyone holding it. Instead the
|
|
20
|
+
row stays and goes inert: `listScopes` reports it as `declared: false`, no
|
|
21
|
+
function can require it, `findStaleScopes` surfaces it for `pikku scopes audit`,
|
|
22
|
+
and `pikku scopes prune` is the explicit act that removes it.
|
|
23
|
+
|
|
24
|
+
**What this rules out:** having the function runner resolve scopes per call (it
|
|
25
|
+
would put a store round-trip in every request path and break the Workers/Lambda
|
|
26
|
+
story), caching resolved scopes anywhere, and making `syncScopes` reconcile —
|
|
27
|
+
diffing declared against stored and deleting the difference. A deploy must never
|
|
28
|
+
be able to revoke a grant as a side effect.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Self-authentication is declared, not detected
|
|
4
|
+
description: A function that authorizes callers in its own body says so with selfAuthenticated; codegen never tries to infer it
|
|
5
|
+
tags: permissions, codegen
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Self-authentication is declared, not detected
|
|
9
|
+
|
|
10
|
+
Some functions are genuinely closed while carrying no session, scope or
|
|
11
|
+
permission: a webhook receiver that verifies a signature, a handler that
|
|
12
|
+
redeems a signed invite, an exchange endpoint that validates a token before it
|
|
13
|
+
does anything. Nothing in meta distinguishes those from a function nobody
|
|
14
|
+
remembered to gate, so `validateExposedFunctionsGated` (PKU574) would warn about
|
|
15
|
+
them on every build.
|
|
16
|
+
|
|
17
|
+
The fix is a declaration — `selfAuthenticated: true` on the function config —
|
|
18
|
+
not analysis of the body. Detection would have to recognise an open-ended set of
|
|
19
|
+
authorization idioms, and it fails in the expensive direction: a body that
|
|
20
|
+
*looks* like it checks something silences the warning for a function that
|
|
21
|
+
checks nothing. A declaration cannot be wrong by accident. Someone typed it,
|
|
22
|
+
it is greppable, and it survives into meta where an audit reads it as what it
|
|
23
|
+
is — a claim by a named author, not an inference.
|
|
24
|
+
|
|
25
|
+
It carries no runtime effect and grants nothing. Its entire job is to move a
|
|
26
|
+
gate that codegen cannot see into a place where a human can, and to keep PKU574
|
|
27
|
+
worth reading: a warning that is usually wrong stops being read, which costs
|
|
28
|
+
more than the warning ever saved.
|
|
29
|
+
|
|
30
|
+
**What this rules out:** inferring self-authentication from the function body or
|
|
31
|
+
from what it imports; giving `selfAuthenticated` any runtime meaning (it must
|
|
32
|
+
never be a way to skip a check the runtime would otherwise run); and dropping
|
|
33
|
+
the PKU574 warning instead, which was the alternative that would have left every
|
|
34
|
+
genuinely ungated function silent too.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Signed content URLs bind the request path and verify fail-closed
|
|
4
|
+
description: A signature that only carries timestamps authorizes every asset, and a verifier with no key must refuse rather than allow
|
|
5
|
+
tags: content
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Signed content URLs bind the request path and verify fail-closed
|
|
9
|
+
|
|
10
|
+
`LocalContent` signs a payload containing the decoded request path, and the
|
|
11
|
+
verifier in `pikku-node-http-server.ts` compares it against the path actually
|
|
12
|
+
requested. `LocalContent` requires a `JWTService` and throws without one; a
|
|
13
|
+
verifier with no key available rejects with 403 rather than allowing the
|
|
14
|
+
request, logging once per process so an attacker-triggerable path cannot flood.
|
|
15
|
+
|
|
16
|
+
A signature over `{signedAt, expiresAt, notBefore}` alone proves only *when* a
|
|
17
|
+
URL was issued, never *what* it was issued for. Any valid token was a skeleton
|
|
18
|
+
key: swap the pathname from a public thumbnail to a private document and the
|
|
19
|
+
signature still verifies. Timestamps bound the window; only the path binds the
|
|
20
|
+
asset.
|
|
21
|
+
|
|
22
|
+
The path is the representation both signing entry points can produce and the
|
|
23
|
+
verifier can reconstruct — it sees a request line, and cannot recover the
|
|
24
|
+
bucket/key split from it. `signedContentPath` normalizes both sides identically
|
|
25
|
+
(pathname only, origin and query dropped, `decodeURIComponent` falling back to
|
|
26
|
+
the raw pathname on a malformed escape) so a difference in encoding cannot
|
|
27
|
+
become a difference in verdict.
|
|
28
|
+
|
|
29
|
+
`pikku serve` and `pikku dev` mint an ephemeral per-process signing key, so
|
|
30
|
+
local content serving works with no configuration without shipping a fail-open
|
|
31
|
+
path. URLs signed by one dev-server process are meaningless to the next, which
|
|
32
|
+
is the correct lifetime for a dev secret.
|
|
33
|
+
|
|
34
|
+
**What this rules out:** signing a URL without binding it to what it grants;
|
|
35
|
+
returning "valid" from a verifier that could not check anything; normalizing the
|
|
36
|
+
path differently on the two sides; and constructing `LocalContent` without a
|
|
37
|
+
JWT service.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Webhook bodies are signed before they are enqueued
|
|
4
|
+
description: QueueWebhookService computes the HMAC at enqueue time so the signing key never travels in the queue payload
|
|
5
|
+
tags: services
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Webhook bodies are signed before they are enqueued
|
|
9
|
+
|
|
10
|
+
`QueueWebhookService.prepareDelivery`
|
|
11
|
+
(`packages/core/src/services/queue-webhook-service.ts`) serialises the payload,
|
|
12
|
+
resolves the signing secret, computes the signature and writes it into the job's
|
|
13
|
+
`headers` — all before `queueService.add` is called. The worker,
|
|
14
|
+
`pikkuWebhookWorkerFunc`, POSTs headers it was handed and never sees a secret.
|
|
15
|
+
|
|
16
|
+
Signing in the worker instead would mean the key has to reach the worker, and the
|
|
17
|
+
only channel between the two is the queue payload: an SQS body, a Redis value, a
|
|
18
|
+
`jsonb` column, all of which are at rest, replicated, and visible to anyone who
|
|
19
|
+
can read the queue. The signature is not sensitive; the key is.
|
|
20
|
+
|
|
21
|
+
**What this rules out:** moving signing into the worker so it can re-sign on
|
|
22
|
+
retry, and putting `secret` (or a resolved key of any kind) onto `WebhookJobData`.
|
|
23
|
+
Note the related consequence: because the signature is fixed at enqueue time, a
|
|
24
|
+
key rotated between enqueue and delivery does not change an in-flight job's
|
|
25
|
+
signature — that is intended, not a bug to fix by carrying the key.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: A scenario actor step always goes over the real transport and never through internal dispatch
|
|
4
|
+
description: Internal dispatch would bypass auth middleware and permissions, turning a scenario into a green health check that proves nothing
|
|
5
|
+
tags: workflow
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# A scenario actor step always goes over the real transport and never through internal dispatch
|
|
9
|
+
|
|
10
|
+
When a workflow step carries `options.actor`, `rpcStep` in
|
|
11
|
+
`pikku-workflow-service.ts` calls `actor.invoke(rpcName, data)` — the actor's
|
|
12
|
+
authenticated client, over the real network transport — and never falls back to
|
|
13
|
+
internal dispatch. Internal dispatch skips auth middleware and permission
|
|
14
|
+
checks, so a scenario that "passed" that way would prove only that the function
|
|
15
|
+
body runs, not that the persona is allowed to run it. That is a green health
|
|
16
|
+
check for a system that may be wide open.
|
|
17
|
+
|
|
18
|
+
For the same reason, actor steps never queue: `rpcStep` short-circuits
|
|
19
|
+
`dispatchStep` to `false` whenever `options.actor` is set. An actor step is an
|
|
20
|
+
outbound HTTP call made by the runner itself, and the actor's session lives in
|
|
21
|
+
this process — a queued worker in another process would have no session to make
|
|
22
|
+
it with. The step is still recorded durably like any RPC step, so replay and
|
|
23
|
+
reporting are unaffected.
|
|
24
|
+
|
|
25
|
+
Actor identity is process-local by nature. `PikkuScenarioService.runActors` maps
|
|
26
|
+
run id to live authenticated clients (cookie jars), and those ride that map
|
|
27
|
+
only, never the persisted run wire — a serialized session on a durable run row
|
|
28
|
+
would be a credential at rest.
|
|
29
|
+
|
|
30
|
+
**What this rules out:** adding an "internal dispatch is faster" fast path for
|
|
31
|
+
actor steps, routing an actor step through the queue, serializing actor sessions
|
|
32
|
+
onto the run wire, or letting `actor.invoke` degrade to `rpcWithWire` when the
|
|
33
|
+
transport is unavailable. Each turns an end-to-end authorization test into one
|
|
34
|
+
that cannot fail.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: An approval decision is stored raw and validated on replay, and an invalid one closes the gate rather than failing the run
|
|
4
|
+
description: The schema only exists inside the workflow body, and letting an external payload fail the run would let any caller kill a workflow
|
|
5
|
+
tags: workflow
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# An approval decision is stored raw and validated on replay, and an invalid one closes the gate rather than failing the run
|
|
9
|
+
|
|
10
|
+
`approveStep` in `pikku-workflow-service.ts` is called from outside the workflow
|
|
11
|
+
— an HTTP route, an RPC — where the approval's schema value is not in scope. It
|
|
12
|
+
therefore stores the decision payload raw in run state and does nothing else.
|
|
13
|
+
Validation happens on replay inside `approvalStep`, in the workflow body, which
|
|
14
|
+
is the only place the schema exists.
|
|
15
|
+
|
|
16
|
+
When validation fails, the bad decision is dropped, the issues are recorded on
|
|
17
|
+
the gate's state record, and a `WorkflowSuspendedException` re-closes the gate.
|
|
18
|
+
The failure stays legible to whoever tries next, and — the security point —
|
|
19
|
+
failing the run instead would let any caller kill a workflow with a malformed
|
|
20
|
+
payload. A later valid decision still lands normally.
|
|
21
|
+
|
|
22
|
+
`WorkflowApprovalOptions.schema` is a VALUE, not a type generic, for the same
|
|
23
|
+
reason: the payload arrives from an untrusted caller over the approve wire, and
|
|
24
|
+
a generic is erased at compile time, so it would validate nothing. Any
|
|
25
|
+
standard-schema library (zod, valibot, arktype) satisfies it. The contract is
|
|
26
|
+
the `~standard` spec and nothing more: `@pikku/core` deliberately carries no
|
|
27
|
+
zod dependency, which is why `pikku-workflow-service.test.ts` hand-rolls a
|
|
28
|
+
minimal `StandardSchemaV1` rather than importing a validation library.
|
|
29
|
+
|
|
30
|
+
A decision arriving for a gate that has already resolved is rejected with
|
|
31
|
+
`WorkflowApprovalResolvedError` (409) rather than accepted and dropped. The gate
|
|
32
|
+
caches its outcome as the step result and never re-reads run state, so a
|
|
33
|
+
decision recorded after resolution could not take effect — most obviously when
|
|
34
|
+
it loses the race with expiry — and the approver has to be told their decision
|
|
35
|
+
did not land.
|
|
36
|
+
|
|
37
|
+
**What this rules out:** validating in `approveStep` (the schema is not there),
|
|
38
|
+
failing the run on an invalid payload, turning `schema` into a type parameter,
|
|
39
|
+
accepting a decision on a resolved gate, or making a resolved gate re-read run
|
|
40
|
+
state so a late decision "wins".
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: A queued workflow step rehydrates its session from the persisted run wire
|
|
4
|
+
description: The queue job payload is just `{ runId }`, so without threading `pikkuUserId` an authed step sees no session and throws
|
|
5
|
+
tags: workflow
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# A queued workflow step rehydrates its session from the persisted run wire
|
|
9
|
+
|
|
10
|
+
A queued workflow step is executed with the bare job wire — the payload is just
|
|
11
|
+
`{ runId }` (or `{ runId, stepName, rpcName, data, fromStepName }`) — so it
|
|
12
|
+
carries no `pikkuUserId`. `invokeStepRpc` in `pikku-workflow-service.ts`
|
|
13
|
+
therefore merges the run's own `wire.pikkuUserId` into the step wire override
|
|
14
|
+
before calling `rpcWithWire`. Without it, a step written as an authed
|
|
15
|
+
`pikkuFunc` sees no session and fails with "Authentication required" on the
|
|
16
|
+
queued path while passing inline, which is the worst possible split: it looks
|
|
17
|
+
like a transport bug rather than an auth one.
|
|
18
|
+
|
|
19
|
+
`invokeStepRpc` is shared by the queue executor and the inline executor
|
|
20
|
+
precisely so the two cannot drift. The only thing that differs between
|
|
21
|
+
transports is who calls it, not the call itself. `createWorkflowWire` and
|
|
22
|
+
`runWorkflowJobInner` propagate the same `pikkuUserId` onto the workflow wire
|
|
23
|
+
for the workflow body.
|
|
24
|
+
|
|
25
|
+
The user id is the only identity carried. It is a reference for credential
|
|
26
|
+
resolution, not a serialized session — the session itself is rehydrated on the
|
|
27
|
+
far side.
|
|
28
|
+
|
|
29
|
+
**What this rules out:** giving the queued path its own invocation helper,
|
|
30
|
+
dropping the `pikkuUserId` merge because "the wire already has a session"
|
|
31
|
+
inline, or widening the run wire to persist session tokens instead of a user id
|
|
32
|
+
reference.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Scenario sessions are isolated per actor and reset between scenarios
|
|
4
|
+
description: One jar per actor keeps two personas from sharing a session; a browser reset keeps one scenario from leaving the next signed in as somebody else
|
|
5
|
+
tags: workflow
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Scenario sessions are isolated per actor and reset between scenarios
|
|
9
|
+
|
|
10
|
+
`createCookieJar` in `scenario-cookie-jar.ts` holds its `Map` as a closure
|
|
11
|
+
local, so two jars can never share a session. That is precisely what lets one
|
|
12
|
+
scenario sign in as several people without one of them inheriting another's
|
|
13
|
+
session. Every response is read, not just the sign-in, so a cookie the target
|
|
14
|
+
rotates mid-session is followed rather than dropped, and an empty `Set-Cookie`
|
|
15
|
+
value is treated as a deletion — the name is dropped rather than held as a
|
|
16
|
+
cookie whose value says it is gone. The jar also stamps `Origin`, because Better
|
|
17
|
+
Auth rejects a state-changing POST whose Origin does not match its baseURL.
|
|
18
|
+
|
|
19
|
+
`ScenarioCookieJar.empty` reports a fact about the jar, not about the session: a
|
|
20
|
+
target that sets a CSRF or locale cookie before anyone signs in fills the jar
|
|
21
|
+
without establishing a session. Anything needing to know whether a sign-in
|
|
22
|
+
happened has to track the sign-in itself.
|
|
23
|
+
|
|
24
|
+
The browser side has the same requirement. `ScenarioBrowserProvider.reset`
|
|
25
|
+
discards every actor's per-scenario state — cookies, storage, open pages — while
|
|
26
|
+
keeping the browser, and is called between scenarios so one scenario cannot
|
|
27
|
+
leave the next signed in as somebody else.
|
|
28
|
+
|
|
29
|
+
**What this rules out:** hoisting the jar to a module-level or per-service map,
|
|
30
|
+
sharing one jar across actors, reading `Set-Cookie` only from the sign-in
|
|
31
|
+
response, treating `empty === false` as "signed in", or skipping `reset` between
|
|
32
|
+
scenarios as an optimisation.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: A scenario step is never registered as a callable RPC and never dispatched on the queue
|
|
4
|
+
description: A step drives a browser and holds an actor's session, so exposing it as an RPC would put that reach on the network
|
|
5
|
+
tags: workflow
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# A scenario step is never registered as a callable RPC and never dispatched on the queue
|
|
9
|
+
|
|
10
|
+
`ScenarioStepMeta` in `dsl/workflow-dsl.types.ts` is a distinct meta type from
|
|
11
|
+
`RpcStepMeta` on purpose. A scenario step runs locally through `runPikkuFunc`
|
|
12
|
+
and must never be treated as dispatchable on the queue or replay path, nor
|
|
13
|
+
registered as a callable RPC — a browser-driving step must not be
|
|
14
|
+
network-invocable. It executes with a browser handle and an actor's
|
|
15
|
+
authenticated session in hand; exposed as an RPC it would hand a remote caller
|
|
16
|
+
that reach.
|
|
17
|
+
|
|
18
|
+
`PikkuScenarioService.scenarioStep` reflects this at runtime: it always runs
|
|
19
|
+
through `engine.inlineStep` with `runPikkuFunc`, never through `rpcStep`, so no
|
|
20
|
+
transport is involved. A step declaring `browser: true` is refused outright
|
|
21
|
+
unless both a browser provider is registered and an actor was supplied, with an
|
|
22
|
+
error saying which is missing.
|
|
23
|
+
|
|
24
|
+
Scenario steps are also modelled as sessionless pikku functions (see
|
|
25
|
+
`scenario-step.test.ts`) because a step is driven by an actor, not by a wire
|
|
26
|
+
session.
|
|
27
|
+
|
|
28
|
+
**What this rules out:** collapsing `ScenarioStepMeta` into `RpcStepMeta`,
|
|
29
|
+
registering step functions in the RPC map so they "can be tested directly",
|
|
30
|
+
routing a scenario step through `rpcStep`/`dispatchStep`, or defaulting a
|
|
31
|
+
`browser: true` step to run without an actor.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: overview
|
|
3
|
+
title: Knowledge
|
|
4
|
+
description: Why @pikku/core is built the way it is — the reasoning that used to live in comments
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Knowledge
|
|
8
|
+
|
|
9
|
+
Pikku's source says *what* it does. These notes say *why*, for the handful of
|
|
10
|
+
choices where the code alone reads as arbitrary or, worse, reads as a mistake.
|
|
11
|
+
|
|
12
|
+
The rule that produced this directory: **reasoning never lives in code.** A
|
|
13
|
+
comment that restates the line below it is deleted. A comment that records a
|
|
14
|
+
decision — a constraint, a trade-off, a thing that was tried and failed — moves
|
|
15
|
+
here and gets a name, so it can be linked to and argued with.
|
|
16
|
+
|
|
17
|
+
Everything mechanical is generated or inspectable: the wirings, the schemas, the
|
|
18
|
+
meta files, the export surface. A note that repeats them is a copy that will
|
|
19
|
+
drift.
|
|
20
|
+
|
|
21
|
+
<!-- pikku:knowledge-index -->
|
|
22
|
+
- [decisions](decisions/index.md) — a rule that was chosen, and what it rules out
|
|
23
|
+
- [questions](questions/index.md) — something asked and not yet answered
|
|
24
|
+
<!-- /pikku:knowledge-index -->
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: overview
|
|
3
|
+
title: Questions
|
|
4
|
+
description: Things asked of core and not yet answered
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Questions
|
|
8
|
+
|
|
9
|
+
Something asked and not yet answered. A question earns a note when the code
|
|
10
|
+
currently makes a choice that nobody has defended — the choice stays, the doubt
|
|
11
|
+
gets recorded.
|
|
12
|
+
|
|
13
|
+
<!-- pikku:knowledge-index -->
|
|
14
|
+
_Nothing here yet._
|
|
15
|
+
<!-- /pikku:knowledge-index -->
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/core",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.74",
|
|
4
4
|
"description": "The Pikku runtime — functions, wirings, services, middleware and types",
|
|
5
5
|
"author": "yasser.fadl@gmail.com",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"./workflow/timeline": "./dist/wirings/workflow/run-timeline.js",
|
|
28
28
|
"./workflow/types": "./dist/wirings/workflow/workflow.types.js",
|
|
29
29
|
"./actor-flow": "./dist/wirings/actor-flow/index.js",
|
|
30
|
+
"./virtual-user": "./dist/wirings/virtual-user/index.js",
|
|
30
31
|
"./channel/local": "./dist/wirings/channel/local/index.js",
|
|
31
32
|
"./channel/serverless": "./dist/wirings/channel/serverless/index.js",
|
|
32
33
|
"./http": "./dist/wirings/http/index.js",
|
|
@@ -45,6 +46,8 @@
|
|
|
45
46
|
"./node": "./dist/wirings/node/index.js",
|
|
46
47
|
"./credential": "./dist/wirings/credential/index.js",
|
|
47
48
|
"./scope": "./dist/wirings/scope/index.js",
|
|
49
|
+
"./role": "./dist/wirings/role/index.js",
|
|
50
|
+
"./persona": "./dist/wirings/persona/index.js",
|
|
48
51
|
"./secret": "./dist/wirings/secret/index.js",
|
|
49
52
|
"./variable": "./dist/wirings/variable/index.js",
|
|
50
53
|
"./oauth2": "./dist/wirings/oauth2/index.js",
|
|
@@ -55,7 +58,6 @@
|
|
|
55
58
|
"./services/istanbul-coverage": "./dist/services/istanbul-coverage-service.js",
|
|
56
59
|
"./services/local-content": "./dist/services/local-content.js",
|
|
57
60
|
"./services/temporary-file-service": "./dist/services/temporary-file-service.js",
|
|
58
|
-
"./services/gopass-secrets": "./dist/services/gopass-secrets.js",
|
|
59
61
|
"./crypto-utils": "./dist/crypto-utils.js",
|
|
60
62
|
"./hmac": "./dist/utils/hmac.js",
|
|
61
63
|
"./internal": "./dist/internal.js",
|
package/run-tests.sh
CHANGED
|
File without changes
|